def test_get_string(self): v1_string = "3.23" v1 = api_version_request.APIVersionRequest(v1_string) self.assertEqual(v1_string, v1.get_string()) self.assertRaises(ValueError, api_version_request.APIVersionRequest().get_string)
def set_api_version_request(self): """Set API version request based on the request header information.""" if API_VERSION_REQUEST_HEADER in self.headers: hdr_string = self.headers[API_VERSION_REQUEST_HEADER] # 'latest' is a special keyword which is equivalent to requesting # the maximum version of the API supported if hdr_string == 'latest': self.api_version_request = api_version.max_api_version() else: self.api_version_request = api_version.APIVersionRequest( hdr_string) # Check that the version requested is within the global # minimum/maximum of supported API versions if not self.api_version_request.matches( api_version.min_api_version(), api_version.max_api_version()): raise exception.InvalidGlobalAPIVersion( req_ver=self.api_version_request.get_string(), min_ver=api_version.min_api_version().get_string(), max_ver=api_version.max_api_version().get_string()) else: self.api_version_request = api_version.APIVersionRequest( api_version.DEFAULT_API_VERSION)
def decorator(f): obj_min_ver = api_version.APIVersionRequest(min_ver) if max_ver: obj_max_ver = api_version.APIVersionRequest(max_ver) else: obj_max_ver = api_version.APIVersionRequest() # Add to list of versioned methods registered func_name = f.__name__ new_func = versioned_method.VersionedMethod( func_name, obj_min_ver, obj_max_ver, f) func_dict = getattr(cls, VER_METHOD_ATTR, {}) if not func_dict: setattr(cls, VER_METHOD_ATTR, func_dict) func_list = func_dict.get(func_name, []) if not func_list: func_dict[func_name] = func_list func_list.append(new_func) # Ensure the list is sorted by minimum version (reversed) # so later when we work through the list in order we find # the method which has the latest version which supports # the version requested. # TODO(cyeoh): Add check to ensure that there are no overlapping # ranges of valid versions as that is amibiguous func_list.sort(key=lambda f: f.start_version, reverse=True) return f
def test_api_version_request_header_latest(self, mock_maxver): mock_maxver.return_value = api_version.APIVersionRequest("3.5") request = wsgi.Request.blank('/') request.headers = {self.header_name: 'latest'} request.set_api_version_request() self.assertEqual(api_version.APIVersionRequest("3.5"), request.api_version_request)
def test_version_comparisons(self): v1 = api_version_request.APIVersionRequest("2.0") v2 = api_version_request.APIVersionRequest("2.5") v3 = api_version_request.APIVersionRequest("5.23") v4 = api_version_request.APIVersionRequest("2.0") v_null = api_version_request.APIVersionRequest() self.assertTrue(v1 < v2) self.assertTrue(v3 > v2) self.assertTrue(v1 != v2) self.assertTrue(v1 == v4) self.assertTrue(v1 != v_null) self.assertTrue(v_null == v_null) self.assertRaises(TypeError, v1.__cmp__, "2.1")
def test_microversions2_version_too_high(self, mock_namespace, mock_maxver): mock_maxver.return_value = api_version.APIVersionRequest("3.5") app = fakes.wsgi_app_v21(init_only='test-microversions') req = fakes.HTTPRequest.blank('/v2/fake/microversions2') req.headers = {self.header_name: '3.2'} res = req.get_response(app) self.assertEqual(404, res.status_int)
def blank(*args, **kwargs): kwargs['base_url'] = 'http://localhost/v3' use_admin_context = kwargs.pop('use_admin_context', False) version = kwargs.pop('version', os_wsgi.DEFAULT_API_VERSION) out = os_wsgi.Request.blank(*args, **kwargs) out.api_version_request = api_version.APIVersionRequest(version) out.environ['patron.context'] = FakeRequestContext('fake_user', 'fake', is_admin=use_admin_context) return out
def test_microversions2_later_version(self, mock_namespace, mock_maxver): mock_maxver.return_value = api_version.APIVersionRequest("3.1") app = fakes.wsgi_app_v21(init_only='test-microversions') req = fakes.HTTPRequest.blank('/v2/fake/microversions2') req.headers = {self.header_name: '3.0'} res = req.get_response(app) self.assertEqual(202, res.status_int) resp_json = jsonutils.loads(res.body) self.assertEqual('controller2_val2', resp_json['param'])
def test_microversions_return_header_fault(self, mock_namespace, mock_maxver): mock_maxver.return_value = api_version.APIVersionRequest("3.0") app = fakes.wsgi_app_v21(init_only='test-microversions') req = fakes.HTTPRequest.blank('/v2/fake/microversions') req.headers = {self.header_name: '3.0'} res = req.get_response(app) self.assertEqual(400, res.status_int) self.assertEqual("3.0", res.headers[self.header_name]) self.assertEqual(self.header_name, res.headers['Vary'])
def _check_microversion_response(self, url, req_version, resp_param, mock_namespace, mock_maxver): mock_maxver.return_value = api_version.APIVersionRequest('2.3') app = fakes.wsgi_app_v21(init_only='test-microversions') req = fakes.HTTPRequest.blank(url) req.headers = {self.header_name: req_version} res = req.get_response(app) self.assertEqual(200, res.status_int) resp_json = jsonutils.loads(res.body) self.assertEqual(resp_param, resp_json['param'])
def wrapper(*args, **kwargs): min_ver = api_version.APIVersionRequest(min_version) max_ver = api_version.APIVersionRequest(max_version) # The request object is always the second argument. # However numerous unittests pass in the request object # via kwargs instead so we handle that as well. # TODO(cyeoh): cleanup unittests so we don't have to # to do this if 'req' in kwargs: ver = kwargs['req'].api_version_request else: ver = args[1].api_version_request if ver.matches(min_ver, max_ver): # Only validate against the schema if it lies within # the version range specified. Note that if both min # and max are not specified the validator will always # be run. schema_validator.validate(kwargs['body']) return func(*args, **kwargs)
def test_microversions_return_header_non_default(self, mock_namespace, mock_maxver): mock_maxver.return_value = api_version.APIVersionRequest("2.3") app = fakes.wsgi_app_v21(init_only='test-microversions') req = fakes.HTTPRequest.blank('/v2/fake/microversions') req.headers = {self.header_name: '2.3'} res = req.get_response(app) self.assertEqual(200, res.status_int) resp_json = jsonutils.loads(res.body) self.assertEqual('val2', resp_json['param']) self.assertEqual("2.3", res.headers[self.header_name]) self.assertEqual(self.header_name, res.headers['Vary'])
def test_microversions_global_version_too_high(self, mock_namespace, mock_maxver): mock_maxver.return_value = api_version.APIVersionRequest("3.5") app = fakes.wsgi_app_v21(init_only='test-microversions') req = fakes.HTTPRequest.blank('/v2/fake/microversions2') req.headers = {self.header_name: '3.7'} res = req.get_response(app) self.assertEqual(406, res.status_int) res_json = jsonutils.loads(res.body) self.assertEqual( "Version 3.7 is not supported by the API. " "Minimum is 2.1 and maximum is 3.5.", res_json['computeFault']['message'])
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(init_only='test-microversions') req = fakes.HTTPRequest.blank('/v2/fake/microversions4') req.headers = {self.header_name: version} req.environ['CONTENT_TYPE'] = "application/json" req.method = 'POST' res = req.get_response(app) self.assertEqual(200, res.status_int) resp_json = jsonutils.loads(res.body) self.assertEqual(expected_resp, resp_json['param']) self.assertEqual(version, res.headers[self.header_name])
def test_microversions_schema_fail(self, mock_namespace, mock_maxver): mock_maxver.return_value = api_version.APIVersionRequest("3.3") app = fakes.wsgi_app_v21(init_only='test-microversions') 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.dumps({'dummy': {'invalid_param': 'foo'}}) res = req.get_response(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."))
def test_microversions_schema_second_version(self, mock_namespace, mock_maxver): mock_maxver.return_value = api_version.APIVersionRequest("3.3") app = fakes.wsgi_app_v21(init_only='test-microversions') req = fakes.HTTPRequest.blank('/v2/fake/microversions3/1') req.headers = {self.header_name: '2.10'} req.environ['CONTENT_TYPE'] = "application/json" req.method = 'PUT' req.body = jsonutils.dumps({'dummy': {'val2': 'foo'}}) res = req.get_response(app) self.assertEqual(200, res.status_int) resp_json = jsonutils.loads(res.body) self.assertEqual('update_val1', resp_json['param']) self.assertEqual("2.10", res.headers[self.header_name])
def test_version_matches(self): v1 = api_version_request.APIVersionRequest("2.0") v2 = api_version_request.APIVersionRequest("2.5") v3 = api_version_request.APIVersionRequest("2.45") v4 = api_version_request.APIVersionRequest("3.3") v5 = api_version_request.APIVersionRequest("3.23") v6 = api_version_request.APIVersionRequest("2.0") v7 = api_version_request.APIVersionRequest("3.3") v8 = api_version_request.APIVersionRequest("4.0") v_null = api_version_request.APIVersionRequest() self.assertTrue(v2.matches(v1, v3)) self.assertTrue(v2.matches(v1, v_null)) self.assertTrue(v1.matches(v6, v2)) self.assertTrue(v4.matches(v2, v7)) self.assertTrue(v4.matches(v_null, v7)) self.assertTrue(v4.matches(v_null, v8)) self.assertFalse(v1.matches(v2, v3)) self.assertFalse(v5.matches(v2, v4)) self.assertFalse(v2.matches(v3, v1)) self.assertRaises(ValueError, v_null.matches, v1, v3)
def test_resource_receives_api_version_request(self, mock_maxver): version = "2.5" mock_maxver.return_value = api_version.APIVersionRequest(version) class Controller(object): def index(self, req): if req.api_version_request != \ api_version.APIVersionRequest(version): raise webob.exc.HTTPInternalServerError() return 'success' app = fakes.TestRouterV21(Controller()) req = webob.Request.blank('/tests') req.headers = {self.header_name: version} response = req.get_response(app) self.assertEqual(response.body, 'success') self.assertEqual(response.status_int, 200)
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(init_only='test-microversions') req = fakes.HTTPRequest.blank('/v2/fake/microversions3/1/action') if req_header: req.headers = {self.header_name: req_header} req.method = 'POST' req.body = jsonutils.dumps({'foo': None}) res = self._test_microversions(app, req, ret_code, ret_header=ret_header) if ret_code == 202: resp_json = jsonutils.loads(res.body) self.assertEqual({'foo': 'bar'}, resp_json)
def test_with_extends_decorator(self, mock_namespace, mock_maxver): mock_maxver.return_value = api_version.APIVersionRequest('2.4') app = fakes.wsgi_app_v21(init_only='test-microversions') req = fakes.HTTPRequest.blank('/v2/fake/microversions5/item') req.headers = {'X-OpenStack-Nova-API-Version': '2.4'} res = req.get_response(app) self.assertEqual(200, res.status_int) expected_res = { "extend_ctrlr2": "val_2", "extend_ctrlr1": "val_1", "base_param": "base_val" } resp_json = jsonutils.loads(res.body) for param in resp_json: self.assertIn(param, expected_res) self.assertEqual(expected_res[param], resp_json[param]) self.assertEqual(3, len(resp_json))
def __init__(self, *args, **kwargs): super(ExtendedVolumesController, self).__init__(*args, **kwargs) self.api_version_2_3 = api_version_request.APIVersionRequest('2.3')
def __init__(self, *args, **kwargs): super(Request, self).__init__(*args, **kwargs) self._extension_data = {'db_items': {}} if not hasattr(self, 'api_version_request'): self.api_version_request = api_version.APIVersionRequest()
def test_null_version(self): v = api_version_request.APIVersionRequest() self.assertTrue(v.is_null())
def _test_string(version, exp_major, exp_minor): v = api_version_request.APIVersionRequest(version) self.assertEqual(v.ver_major, exp_major) self.assertEqual(v.ver_minor, exp_minor)
class FakeRequest(object): api_version_request = api_version.APIVersionRequest("2.1")
def index(self, req): if req.api_version_request != \ api_version.APIVersionRequest(version): raise webob.exc.HTTPInternalServerError() return 'success'
def test_api_version_request_header_none(self): request = wsgi.Request.blank('/') request.set_api_version_request() self.assertEqual( api_version.APIVersionRequest(api_version.DEFAULT_API_VERSION), request.api_version_request)