|
|
|
@@ -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)
|
|
|
|
|