Add a PlacementFixture

Some of the functional tests are calling the scheduler for getting the destination.
Once we will accept having the scheduler be calling the Placement service in order
to know a list of valid resource providers, we will need to run a local fixture
for having those tests faking the Placement service.

Change-Id: I6883888bf5d1920ab57dbf3dcaa1a7b375591754
This commit is contained in:
Sylvain Bauza 2017-01-20 17:13:11 +01:00
parent 58719f52a5
commit 98936fb28f
2 changed files with 115 additions and 0 deletions

View File

@ -23,6 +23,7 @@ import os
import warnings import warnings
import fixtures import fixtures
from keystoneauth1 import session as ks
import mock import mock
from oslo_concurrency import lockutils from oslo_concurrency import lockutils
from oslo_config import cfg from oslo_config import cfg
@ -31,6 +32,7 @@ import oslo_messaging as messaging
from oslo_messaging import conffixture as messaging_conffixture from oslo_messaging import conffixture as messaging_conffixture
import six import six
from nova.api.openstack.placement import deploy as placement_deploy
from nova.compute import rpcapi as compute_rpcapi from nova.compute import rpcapi as compute_rpcapi
from nova import context from nova import context
from nova.db import migration from nova.db import migration
@ -43,6 +45,7 @@ from nova import rpc
from nova import service from nova import service
from nova.tests.functional.api import client from nova.tests.functional.api import client
from nova.tests import uuidsentinel from nova.tests import uuidsentinel
from nova import wsgi
_TRUE_VALUES = ('True', 'true', '1', 'yes') _TRUE_VALUES = ('True', 'true', '1', 'yes')
@ -1143,3 +1146,96 @@ class CinderFixture(fixtures.Fixture):
lambda *args, **kwargs: None) lambda *args, **kwargs: None)
self.test.stub_out('nova.volume.cinder.API.unreserve_volume', self.test.stub_out('nova.volume.cinder.API.unreserve_volume',
fake_unreserve_volume) fake_unreserve_volume)
class PlacementFixture(fixtures.Fixture):
"""A fixture to placement operations.
Runs a local WSGI server bound on a free port and having the Placement
application with NoAuth middleware.
This fixture also prevents calling the ServiceCatalog for getting the
endpoint.
It's possible to ask for a specific token when running the fixtures so
all calls would be passing this token.
"""
def __init__(self, token='admin'):
self.token = token
def setUp(self):
super(PlacementFixture, self).setUp()
self.useFixture(ConfPatcher(group='api', auth_strategy='noauth2'))
app = placement_deploy.loadapp(CONF)
# in order to run these in tests we need to bind only to local
# host, and dynamically allocate ports
self.service = wsgi.Server('placement', app, host='127.0.0.1')
self.service.start()
self.addCleanup(self.service.stop)
self._client = ks.Session(auth=None)
self.useFixture(fixtures.MonkeyPatch(
'nova.scheduler.client.report.SchedulerReportClient.get',
self._fake_get))
self.useFixture(fixtures.MonkeyPatch(
'nova.scheduler.client.report.SchedulerReportClient.post',
self._fake_post))
self.useFixture(fixtures.MonkeyPatch(
'nova.scheduler.client.report.SchedulerReportClient.put',
self._fake_put))
self.useFixture(fixtures.MonkeyPatch(
'nova.scheduler.client.report.SchedulerReportClient.delete',
self._fake_delete))
def _fake_get(self, *args):
(url,) = args[1:]
# TODO(sbauza): The current placement NoAuthMiddleware returns a 401
# in case a token is not provided. We should change that by creating
# a fake token so we could remove adding the header below.
return self._client.get(
url,
endpoint_override="http://127.0.0.1:%s" % self.service.port,
headers={'x-auth-token': self.token},
raise_exc=False)
def _fake_post(self, *args):
(url, data) = args[1:]
# NOTE(sdague): using json= instead of data= sets the
# media type to application/json for us. Placement API is
# more sensitive to this than other APIs in the OpenStack
# ecosystem.
# TODO(sbauza): The current placement NoAuthMiddleware returns a 401
# in case a token is not provided. We should change that by creating
# a fake token so we could remove adding the header below.
return self._client.post(
url, json=data,
endpoint_override="http://127.0.0.1:%s" % self.service.port,
headers={'x-auth-token': self.token},
raise_exc=False)
def _fake_put(self, *args):
(url, data) = args[1:]
# NOTE(sdague): using json= instead of data= sets the
# media type to application/json for us. Placement API is
# more sensitive to this than other APIs in the OpenStack
# ecosystem.
# TODO(sbauza): The current placement NoAuthMiddleware returns a 401
# in case a token is not provided. We should change that by creating
# a fake token so we could remove adding the header below.
return self._client.put(
url, json=data,
endpoint_override="http://127.0.0.1:%s" % self.service.port,
headers={'x-auth-token': self.token},
raise_exc=False)
def _fake_delete(self, *args):
(url,) = args[1:]
# TODO(sbauza): The current placement NoAuthMiddleware returns a 401
# in case a token is not provided. We should change that by creating
# a fake token so we could remove adding the header below.
return self._client.delete(
url,
endpoint_override="http://127.0.0.1:%s" % self.service.port,
headers={'x-auth-token': self.token},
raise_exc=False)

View File

@ -468,3 +468,22 @@ class TestSingleCellSimpleFixture(testtools.TestCase):
self.useFixture(fixtures.SingleCellSimple()) self.useFixture(fixtures.SingleCellSimple())
with context.target_cell(mock.sentinel.context, None) as c: with context.target_cell(mock.sentinel.context, None) as c:
self.assertIs(mock.sentinel.context, c) self.assertIs(mock.sentinel.context, c)
class TestPlacementFixture(testtools.TestCase):
def test_responds_to_version(self):
"""Ensure the Placement server responds to calls sensibly."""
placement_fixture = self.useFixture(fixtures.PlacementFixture())
# request the API root, which provides us the versions of the API
resp = placement_fixture._fake_get(None, '/')
self.assertEqual(200, resp.status_code)
# request a known bad url, and we should get a 404
resp = placement_fixture._fake_get(None, '/foo')
self.assertEqual(404, resp.status_code)
# unsets the token so we fake missing it
placement_fixture.token = None
resp = placement_fixture._fake_get(None, '/foo')
self.assertEqual(401, resp.status_code)