From d8928e4a7ca59fb153967ef436962a4658975129 Mon Sep 17 00:00:00 2001 From: He Jie Xu Date: Wed, 19 Jul 2017 15:02:29 +0800 Subject: [PATCH] Using plain routes for the microversions test Few microversions unittest still depend on the stevedore to load few fake controller. This patch uses the plain routes to instead of stevedore. For the unittest can injects routes which are used for test, the `custom_routes` parameter is added to the APIRouterV21. Partial-implement-blueprint api-no-more-extensions-pike Change-Id: I1a7c653ab21be41b1a41f748a35ec9a57dd8b15d --- nova/api/openstack/compute/routes.py | 11 +- .../api/openstack/compute/microversions.py | 76 ++++++----- .../openstack/compute/test_microversions.py | 123 ++++++------------ nova/tests/unit/api/openstack/fakes.py | 5 +- setup.cfg | 3 - 5 files changed, 97 insertions(+), 121 deletions(-) diff --git a/nova/api/openstack/compute/routes.py b/nova/api/openstack/compute/routes.py index d21e6314849e..6570bd80fc2f 100644 --- a/nova/api/openstack/compute/routes.py +++ b/nova/api/openstack/compute/routes.py @@ -877,11 +877,18 @@ class APIRouterV21(nova.api.openstack.APIRouterV21): and method. The URL mapping based on the plain list `ROUTE_LIST` is built at here. The stevedore based API loading will be replaced by this. """ - def __init__(self): + def __init__(self, custom_routes=None): + """:param custom_routes: the additional routes can be added by this + parameter. This parameter is used to test on some fake routes + primarily. + """ self._loaded_extension_info = extension_info.LoadedExtensionInfo() super(APIRouterV21, self).__init__() - for path, methods in ROUTE_LIST: + if custom_routes is None: + custom_routes = tuple() + + for path, methods in ROUTE_LIST + custom_routes: # NOTE(alex_xu): The variable 'methods' is a dict in normal, since # the dict includes all the methods supported in the path. But # if the variable 'method' is a string, it means a redirection. diff --git a/nova/tests/unit/api/openstack/compute/microversions.py b/nova/tests/unit/api/openstack/compute/microversions.py index 89f720d97ffb..862be55d0d83 100644 --- a/nova/tests/unit/api/openstack/compute/microversions.py +++ b/nova/tests/unit/api/openstack/compute/microversions.py @@ -13,16 +13,15 @@ # under the License. """Microversions Test Extension""" +import functools import webob -from nova.api.openstack import extensions +from nova.api.openstack.compute import routes from nova.api.openstack import wsgi from nova.api import validation from nova.tests.unit.api.openstack.compute import dummy_schema -ALIAS = 'test-microversions' - class MicroversionsController(wsgi.Controller): @@ -124,32 +123,51 @@ class MicroversionsExtendsController3(wsgi.Controller): resp_obj.obj['extend_ctrlr3'] = 'val_3' -class Microversions(extensions.V21APIExtensionBase): - """Basic Microversions Extension.""" +mv_controller = functools.partial(routes._create_controller, + MicroversionsController, [], []) - name = "Microversions" - alias = ALIAS - version = 1 - def get_resources(self): - res1 = extensions.ResourceExtension('microversions', - MicroversionsController()) - res2 = extensions.ResourceExtension('microversions2', - MicroversionsController2()) - res3 = extensions.ResourceExtension('microversions3', - MicroversionsController3(), - member_actions={"action": "POST"}) - res4 = extensions.ResourceExtension('microversions4', - MicroversionsController4()) - res5 = extensions.ResourceExtension( - 'microversions5', MicroversionsExtendsBaseController()) - return [res1, res2, res3, res4, res5] +mv2_controller = functools.partial(routes._create_controller, + MicroversionsController2, [], []) - def get_controller_extensions(self): - extension1 = extensions.ControllerExtension( - self, 'microversions5', MicroversionsExtendsController1()) - extension2 = extensions.ControllerExtension( - self, 'microversions5', MicroversionsExtendsController2()) - extension3 = extensions.ControllerExtension( - self, 'microversions5', MicroversionsExtendsController3()) - return [extension1, extension2, extension3] + +mv3_controller = functools.partial(routes._create_controller, + MicroversionsController3, [], []) + + +mv4_controller = functools.partial(routes._create_controller, + MicroversionsController4, [], []) + + +mv5_controller = functools.partial(routes._create_controller, + MicroversionsExtendsBaseController, + [ + MicroversionsExtendsController1, + MicroversionsExtendsController2, + MicroversionsExtendsController3 + ], []) + + +ROUTES = ( + ('/microversions', { + 'GET': [mv_controller, 'index'] + }), + ('/microversions2', { + 'GET': [mv2_controller, 'index'] + }), + ('/microversions3', { + 'POST': [mv3_controller, 'create'] + }), + ('/microversions3/{id}', { + 'PUT': [mv3_controller, 'update'] + }), + ('/microversions3/{id}/action', { + 'POST': [mv3_controller, 'action'] + }), + ('/microversions4', { + 'POST': [mv4_controller, 'create'] + }), + ('/microversions5/{id}', { + 'GET': [mv5_controller, 'show'] + }), +) diff --git a/nova/tests/unit/api/openstack/compute/test_microversions.py b/nova/tests/unit/api/openstack/compute/test_microversions.py index 7405252e5efd..104c5eb4e299 100644 --- a/nova/tests/unit/api/openstack/compute/test_microversions.py +++ b/nova/tests/unit/api/openstack/compute/test_microversions.py @@ -17,6 +17,7 @@ from oslo_serialization import jsonutils from nova.api.openstack import api_version_request as api_version from nova import test +from nova.tests.unit.api.openstack.compute import microversions from nova.tests.unit.api.openstack import fakes @@ -24,6 +25,10 @@ class LegacyMicroversionsTest(test.NoDBTestCase): header_name = 'X-OpenStack-Nova-API-Version' + def setUp(self): + super(LegacyMicroversionsTest, self).setUp() + self.app = fakes.wsgi_app_v21(custom_routes=microversions.ROUTES) + def _test_microversions(self, app, req, ret_code, ret_header=None): req.environ['CONTENT_TYPE'] = "application/json" @@ -43,22 +48,16 @@ class LegacyMicroversionsTest(test.NoDBTestCase): headers = {self.header_name: 'compute %s' % req_header} return headers - @mock.patch("nova.api.openstack.APIRouterV21.api_extension_namespace", - return_value='nova.api.v21.test_extensions') - def test_microversions_no_header(self, mock_namespace): - app = fakes.wsgi_app_v21() - req = fakes.HTTPRequest.blank('/v2/fake/microversions') - res = req.get_response(app) + def test_microversions_no_header(self): + req = fakes.HTTPRequest.blank('/v2/fake/microversions', method='GET') + res = req.get_response(self.app) self.assertEqual(200, res.status_int) resp_json = jsonutils.loads(res.body) self.assertEqual('val', resp_json['param']) - @mock.patch("nova.api.openstack.APIRouterV21.api_extension_namespace", - return_value='nova.api.v21.test_extensions') - def test_microversions_return_header(self, mock_namespace): - app = fakes.wsgi_app_v21() + def test_microversions_return_header(self): req = fakes.HTTPRequest.blank('/v2/fake/microversions') - res = req.get_response(app) + res = req.get_response(self.app) self.assertEqual(200, res.status_int) resp_json = jsonutils.loads(res.body) self.assertEqual('val', resp_json['param']) @@ -69,16 +68,13 @@ class LegacyMicroversionsTest(test.NoDBTestCase): self.assertIn(self.header_name, res.headers.getall('Vary')) @mock.patch("nova.api.openstack.api_version_request.max_api_version") - @mock.patch("nova.api.openstack.APIRouterV21.api_extension_namespace", - return_value='nova.api.v21.test_extensions') - def test_microversions_return_header_non_default(self, mock_namespace, - mock_maxver): + def test_microversions_return_header_non_default(self, + mock_maxver): mock_maxver.return_value = api_version.APIVersionRequest("2.3") - app = fakes.wsgi_app_v21() req = fakes.HTTPRequest.blank('/v2/fake/microversions') req.headers = self._make_header('2.3') - res = req.get_response(app) + res = req.get_response(self.app) self.assertEqual(200, res.status_int) resp_json = jsonutils.loads(res.body) self.assertEqual('val2', resp_json['param']) @@ -89,16 +85,12 @@ class LegacyMicroversionsTest(test.NoDBTestCase): self.assertIn(self.header_name, res.headers.getall('Vary')) @mock.patch("nova.api.openstack.api_version_request.max_api_version") - @mock.patch("nova.api.openstack.APIRouterV21.api_extension_namespace", - return_value='nova.api.v21.test_extensions') - def test_microversions_return_header_fault(self, mock_namespace, - mock_maxver): + def test_microversions_return_header_fault(self, mock_maxver): mock_maxver.return_value = api_version.APIVersionRequest("3.0") - app = fakes.wsgi_app_v21() req = fakes.HTTPRequest.blank('/v2/fake/microversions') req.headers = self._make_header('3.0') - res = req.get_response(app) + res = req.get_response(self.app) self.assertEqual(400, res.status_int) if 'nova' in self.header_name.lower(): self.assertEqual("3.0", res.headers[self.header_name]) @@ -107,16 +99,13 @@ class LegacyMicroversionsTest(test.NoDBTestCase): self.assertIn(self.header_name, res.headers.getall('Vary')) @mock.patch("nova.api.openstack.api_version_request.max_api_version") - @mock.patch("nova.api.openstack.APIRouterV21.api_extension_namespace", - return_value='nova.api.v21.test_extensions') def _check_microversion_response(self, url, req_version, resp_param, - mock_namespace, mock_maxver): + mock_maxver): mock_maxver.return_value = api_version.APIVersionRequest('2.3') - app = fakes.wsgi_app_v21() req = fakes.HTTPRequest.blank(url) req.headers = self._make_header(req_version) - res = req.get_response(app) + res = req.get_response(self.app) self.assertEqual(200, res.status_int) resp_json = jsonutils.loads(res.body) self.assertEqual(resp_param, resp_json['param']) @@ -134,52 +123,39 @@ class LegacyMicroversionsTest(test.NoDBTestCase): '2.3', 'controller2_val1') @mock.patch("nova.api.openstack.api_version_request.max_api_version") - @mock.patch("nova.api.openstack.APIRouterV21.api_extension_namespace", - return_value='nova.api.v21.test_extensions') - def test_microversions2_later_version(self, mock_namespace, mock_maxver): + def test_microversions2_later_version(self, mock_maxver): mock_maxver.return_value = api_version.APIVersionRequest("3.1") - app = fakes.wsgi_app_v21() req = fakes.HTTPRequest.blank('/v2/fake/microversions2') req.headers = self._make_header('3.0') - res = req.get_response(app) + res = req.get_response(self.app) self.assertEqual(202, res.status_int) resp_json = jsonutils.loads(res.body) self.assertEqual('controller2_val2', resp_json['param']) @mock.patch("nova.api.openstack.api_version_request.max_api_version") - @mock.patch("nova.api.openstack.APIRouterV21.api_extension_namespace", - return_value='nova.api.v21.test_extensions') - def test_microversions2_version_too_high(self, mock_namespace, - mock_maxver): + def test_microversions2_version_too_high(self, mock_maxver): mock_maxver.return_value = api_version.APIVersionRequest("3.5") - app = fakes.wsgi_app_v21() req = fakes.HTTPRequest.blank('/v2/fake/microversions2') req.headers = {self.header_name: '3.2'} - res = req.get_response(app) + res = req.get_response(self.app) self.assertEqual(404, res.status_int) - @mock.patch("nova.api.openstack.APIRouterV21.api_extension_namespace", - return_value='nova.api.v21.test_extensions') - def test_microversions2_version_too_low(self, mock_namespace): - app = fakes.wsgi_app_v21() + def test_microversions2_version_too_low(self): req = fakes.HTTPRequest.blank('/v2/fake/microversions2') req.headers = {self.header_name: '2.1'} - res = req.get_response(app) + res = req.get_response(self.app) self.assertEqual(404, res.status_int) @mock.patch("nova.api.openstack.api_version_request.max_api_version") - @mock.patch("nova.api.openstack.APIRouterV21.api_extension_namespace", - return_value='nova.api.v21.test_extensions') - def test_microversions_global_version_too_high(self, mock_namespace, + def test_microversions_global_version_too_high(self, mock_maxver): mock_maxver.return_value = api_version.APIVersionRequest("3.5") - app = fakes.wsgi_app_v21() req = fakes.HTTPRequest.blank('/v2/fake/microversions2') req.headers = self._make_header('3.7') - res = req.get_response(app) + res = req.get_response(self.app) self.assertEqual(406, res.status_int) res_json = jsonutils.loads(res.body) self.assertEqual("Version 3.7 is not supported by the API. " @@ -187,19 +163,16 @@ class LegacyMicroversionsTest(test.NoDBTestCase): res_json['computeFault']['message']) @mock.patch("nova.api.openstack.api_version_request.max_api_version") - @mock.patch("nova.api.openstack.APIRouterV21.api_extension_namespace", - return_value='nova.api.v21.test_extensions') - def test_microversions_schema(self, mock_namespace, mock_maxver): + def test_microversions_schema(self, mock_maxver): mock_maxver.return_value = api_version.APIVersionRequest("3.3") - app = fakes.wsgi_app_v21() req = fakes.HTTPRequest.blank('/v2/fake/microversions3') req.method = 'POST' req.headers = self._make_header('2.2') req.environ['CONTENT_TYPE'] = "application/json" req.body = jsonutils.dump_as_bytes({'dummy': {'val': 'foo'}}) - res = req.get_response(app) + res = req.get_response(self.app) self.assertEqual(200, res.status_int) resp_json = jsonutils.loads(res.body) self.assertEqual('create_val1', resp_json['param']) @@ -210,39 +183,33 @@ class LegacyMicroversionsTest(test.NoDBTestCase): self.assertIn(self.header_name, res.headers.getall('Vary')) @mock.patch("nova.api.openstack.api_version_request.max_api_version") - @mock.patch("nova.api.openstack.APIRouterV21.api_extension_namespace", - return_value='nova.api.v21.test_extensions') - def test_microversions_schema_fail(self, mock_namespace, mock_maxver): + def test_microversions_schema_fail(self, mock_maxver): mock_maxver.return_value = api_version.APIVersionRequest("3.3") - app = fakes.wsgi_app_v21() req = fakes.HTTPRequest.blank('/v2/fake/microversions3') req.method = 'POST' req.headers = {self.header_name: '2.2'} req.environ['CONTENT_TYPE'] = "application/json" req.body = jsonutils.dump_as_bytes({'dummy': {'invalid_param': 'foo'}}) - res = req.get_response(app) + res = req.get_response(self.app) self.assertEqual(400, res.status_int) resp_json = jsonutils.loads(res.body) self.assertTrue(resp_json['badRequest']['message'].startswith( "Invalid input for field/attribute dummy.")) @mock.patch("nova.api.openstack.api_version_request.max_api_version") - @mock.patch("nova.api.openstack.APIRouterV21.api_extension_namespace", - return_value='nova.api.v21.test_extensions') - def test_microversions_schema_out_of_version_check(self, mock_namespace, + def test_microversions_schema_out_of_version_check(self, mock_maxver): mock_maxver.return_value = api_version.APIVersionRequest("3.3") - app = fakes.wsgi_app_v21() req = fakes.HTTPRequest.blank('/v2/fake/microversions3/1') req.method = 'PUT' req.headers = self._make_header('2.2') req.body = jsonutils.dump_as_bytes({'dummy': {'inv_val': 'foo'}}) req.environ['CONTENT_TYPE'] = "application/json" - res = req.get_response(app) + res = req.get_response(self.app) self.assertEqual(200, res.status_int) resp_json = jsonutils.loads(res.body) self.assertEqual('update_val1', resp_json['param']) @@ -252,20 +219,17 @@ class LegacyMicroversionsTest(test.NoDBTestCase): self.assertEqual("compute 2.2", res.headers[self.header_name]) @mock.patch("nova.api.openstack.api_version_request.max_api_version") - @mock.patch("nova.api.openstack.APIRouterV21.api_extension_namespace", - return_value='nova.api.v21.test_extensions') - def test_microversions_schema_second_version(self, mock_namespace, - mock_maxver): + def test_microversions_schema_second_version(self, + mock_maxver): mock_maxver.return_value = api_version.APIVersionRequest("3.3") - app = fakes.wsgi_app_v21() req = fakes.HTTPRequest.blank('/v2/fake/microversions3/1') req.headers = self._make_header('2.10') req.environ['CONTENT_TYPE'] = "application/json" req.method = 'PUT' req.body = jsonutils.dump_as_bytes({'dummy': {'val2': 'foo'}}) - res = req.get_response(app) + res = req.get_response(self.app) self.assertEqual(200, res.status_int) resp_json = jsonutils.loads(res.body) self.assertEqual('update_val1', resp_json['param']) @@ -275,20 +239,16 @@ class LegacyMicroversionsTest(test.NoDBTestCase): self.assertEqual("compute 2.10", res.headers[self.header_name]) @mock.patch("nova.api.openstack.api_version_request.max_api_version") - @mock.patch("nova.api.openstack.APIRouterV21.api_extension_namespace", - return_value='nova.api.v21.test_extensions') def _test_microversions_inner_function(self, version, expected_resp, - mock_namespace, mock_maxver): mock_maxver.return_value = api_version.APIVersionRequest("2.2") - app = fakes.wsgi_app_v21() req = fakes.HTTPRequest.blank('/v2/fake/microversions4') req.headers = self._make_header(version) req.environ['CONTENT_TYPE'] = "application/json" req.method = 'POST' req.body = b'' - res = req.get_response(app) + res = req.get_response(self.app) self.assertEqual(200, res.status_int) resp_json = jsonutils.loads(res.body) self.assertEqual(expected_resp, resp_json['param']) @@ -303,15 +263,12 @@ class LegacyMicroversionsTest(test.NoDBTestCase): self._test_microversions_inner_function('2.1', 'controller4_val1') @mock.patch("nova.api.openstack.api_version_request.max_api_version") - @mock.patch("nova.api.openstack.APIRouterV21.api_extension_namespace", - return_value='nova.api.v21.test_extensions') - def test_with_extends_decorator(self, mock_namespace, mock_maxver): + def test_with_extends_decorator(self, mock_maxver): mock_maxver.return_value = api_version.APIVersionRequest('2.4') - app = fakes.wsgi_app_v21() req = fakes.HTTPRequest.blank('/v2/fake/microversions5/item') req.headers = {'X-OpenStack-Nova-API-Version': '2.4'} - res = req.get_response(app) + res = req.get_response(self.app) self.assertEqual(200, res.status_int) expected_res = { @@ -326,21 +283,17 @@ class LegacyMicroversionsTest(test.NoDBTestCase): self.assertEqual(3, len(resp_json)) @mock.patch("nova.api.openstack.api_version_request.max_api_version") - @mock.patch("nova.api.openstack.APIRouterV21.api_extension_namespace", - return_value='nova.api.v21.test_extensions') def _test_microversions_actions(self, ret_code, ret_header, req_header, - mock_namespace, mock_maxver): mock_maxver.return_value = api_version.APIVersionRequest("2.3") - app = fakes.wsgi_app_v21() req = fakes.HTTPRequest.blank('/v2/fake/microversions3/1/action') if req_header: req.headers = self._make_header(req_header) req.method = 'POST' req.body = jsonutils.dump_as_bytes({'foo': None}) - res = self._test_microversions(app, req, ret_code, + res = self._test_microversions(self.app, req, ret_code, ret_header=ret_header) if ret_code == 202: resp_json = jsonutils.loads(res.body) diff --git a/nova/tests/unit/api/openstack/fakes.py b/nova/tests/unit/api/openstack/fakes.py index 74c3f26955d1..8167b34e2a32 100644 --- a/nova/tests/unit/api/openstack/fakes.py +++ b/nova/tests/unit/api/openstack/fakes.py @@ -63,9 +63,10 @@ def fake_wsgi(self, req): return self.application -def wsgi_app_v21(fake_auth_context=None, v2_compatible=False): +def wsgi_app_v21(fake_auth_context=None, v2_compatible=False, + custom_routes=None): - inner_app_v21 = compute.APIRouterV21() + inner_app_v21 = compute.APIRouterV21(custom_routes=custom_routes) if v2_compatible: inner_app_v21 = openstack_api.LegacyV2CompatibleWrapper(inner_app_v21) diff --git a/setup.cfg b/setup.cfg index 73768fa9d191..b02cec4f3766 100644 --- a/setup.cfg +++ b/setup.cfg @@ -73,9 +73,6 @@ wsgi_scripts = nova-api-wsgi = nova.api.openstack.compute.wsgi:init_application nova-metadata-wsgi = nova.api.metadata.wsgi:init_application -nova.api.v21.test_extensions = - microversions = nova.tests.unit.api.openstack.compute.microversions:Microversions - nova.ipv6_backend = rfc2462 = nova.ipv6.rfc2462 account_identifier = nova.ipv6.account_identifier