From 93b48681a341ce674bbae6f7784d92db05d5da5b Mon Sep 17 00:00:00 2001 From: scottda Date: Fri, 26 Feb 2016 09:49:28 -0700 Subject: [PATCH] Allow api_version_request.matches to accept a string or None According to the Manila devref you should be able to use the following pattern: if req_version.matches("2.1", "2.5"): ....stuff.... elif req_version.matches("2.6", "2.10"): ....other stuff.... elif req_version > api_version_request.APIVersionRequest("2.10"): ....more stuff..... However, the api_version_request.matches() function will not accept a string, it requires an api_version_request object. Fix this to accept a string, as well as None for object. Change-Id: Ic2faaaa7696cc7a647679cbb7a8600b30c3d66d7 Closes-Bug: 1550337 (cherry picked from commit 29b8358ef56160b2845d6ce6f5fd46695617bf7e) --- manila/api/openstack/api_version_request.py | 17 +++- manila/tests/api/test_versions.py | 105 ++++++++++++++++++++ 2 files changed, 119 insertions(+), 3 deletions(-) diff --git a/manila/api/openstack/api_version_request.py b/manila/api/openstack/api_version_request.py index d0ef62c38c..7dbe68fd70 100644 --- a/manila/api/openstack/api_version_request.py +++ b/manila/api/openstack/api_version_request.py @@ -15,6 +15,7 @@ # under the License. import re +import six from manila.api.openstack import versioned_method from manila import exception @@ -221,11 +222,21 @@ class APIVersionRequest(utils.ComparableMixin): # looking for equality. if not self.experimental and experimental: return False - if max_version.is_null() and min_version.is_null(): + + if isinstance(min_version, six.string_types): + min_version = APIVersionRequest(version_string=min_version) + if isinstance(max_version, six.string_types): + max_version = APIVersionRequest(version_string=max_version) + + if not (min_version or max_version): return True - elif max_version.is_null(): + elif (min_version and max_version and + max_version.is_null() and min_version.is_null()): + return True + + elif not max_version or max_version.is_null(): return min_version <= self - elif min_version.is_null(): + elif not min_version or min_version.is_null(): return self <= max_version else: return min_version <= self <= max_version diff --git a/manila/tests/api/test_versions.py b/manila/tests/api/test_versions.py index 83f0abba10..44a2177d77 100644 --- a/manila/tests/api/test_versions.py +++ b/manila/tests/api/test_versions.py @@ -16,6 +16,7 @@ import ddt import mock from oslo_serialization import jsonutils +from oslo_utils import encodeutils from manila.api.openstack import api_version_request from manila.api.openstack import wsgi @@ -154,6 +155,110 @@ class VersionsControllerTestCase(test.TestCase): self.assertEqual('3.0', response.headers[version_header_name]) self.assertEqual(version_header_name, response.headers['Vary']) + @ddt.data(['2.5', 200], ['2.55', 404]) + @ddt.unpack + def test_req_version_matches(self, version, HTTP_ret): + version_request = api_version_request.APIVersionRequest(version) + self.mock_object(api_version_request, + 'max_api_version', + mock.Mock(return_value=version_request)) + + class Controller(wsgi.Controller): + + @wsgi.Controller.api_version('2.0', '2.6') + def index(self, req): + return 'off' + + req = fakes.HTTPRequest.blank('/tests', base_url='http://localhost/v2') + req.headers = {version_header_name: version} + app = fakes.TestRouter(Controller()) + + response = req.get_response(app) + + if HTTP_ret == 200: + self.assertEqual(b'off', response.body) + elif HTTP_ret == 404: + self.assertNotEqual(b'off', response.body) + self.assertEqual(HTTP_ret, response.status_int) + + @ddt.data(['2.5', 'older'], ['2.37', 'newer']) + @ddt.unpack + def test_req_version_matches_with_if(self, version, ret_val): + version_request = api_version_request.APIVersionRequest(version) + self.mock_object(api_version_request, + 'max_api_version', + mock.Mock(return_value=version_request)) + + class Controller(wsgi.Controller): + + def index(self, req): + req_version = req.api_version_request + if req_version.matches('2.1', '2.8'): + return 'older' + if req_version.matches('2.9', '2.88'): + return 'newer' + + req = fakes.HTTPRequest.blank('/tests', base_url='http://localhost/v2') + req.headers = {version_header_name: version} + app = fakes.TestRouter(Controller()) + + response = req.get_response(app) + + resp = encodeutils.safe_decode(response.body, incoming='utf-8') + self.assertEqual(ret_val, resp) + self.assertEqual(200, response.status_int) + + @ddt.data(['2.5', 'older'], ['2.37', 'newer']) + @ddt.unpack + def test_req_version_matches_with_None(self, version, ret_val): + version_request = api_version_request.APIVersionRequest(version) + self.mock_object(api_version_request, + 'max_api_version', + mock.Mock(return_value=version_request)) + + class Controller(wsgi.Controller): + + def index(self, req): + req_version = req.api_version_request + if req_version.matches(None, '2.8'): + return 'older' + if req_version.matches('2.9', None): + return 'newer' + + req = fakes.HTTPRequest.blank('/tests', base_url='http://localhost/v2') + req.headers = {version_header_name: version} + app = fakes.TestRouter(Controller()) + + response = req.get_response(app) + + resp = encodeutils.safe_decode(response.body, incoming='utf-8') + self.assertEqual(ret_val, resp) + self.assertEqual(200, response.status_int) + + def test_req_version_matches_with_None_None(self): + version_request = api_version_request.APIVersionRequest('2.39') + self.mock_object(api_version_request, + 'max_api_version', + mock.Mock(return_value=version_request)) + + class Controller(wsgi.Controller): + + def index(self, req): + req_version = req.api_version_request + # This case is artificial, and will return True + if req_version.matches(None, None): + return "Pass" + + req = fakes.HTTPRequest.blank('/tests', base_url='http://localhost/v2') + req.headers = {version_header_name: '2.39'} + app = fakes.TestRouter(Controller()) + + response = req.get_response(app) + + resp = encodeutils.safe_decode(response.body, incoming='utf-8') + self.assertEqual("Pass", resp) + self.assertEqual(200, response.status_int) + @ddt.ddt class ExperimentalAPITestCase(test.TestCase):