Keep is_public usage backwards compatible

5a1513244c added the ability to
filter by AZ, but it changed the existing behavior if is_public
was not specified. This adds handling to make sure we are still
consistent with the previous behavior.

Co-Authored-by: Alan Bishop <abishop@redhat.com>
Change-Id: I5000aab092c1b434c8dc17bbe4b2d3d632f528c3
Closes-bug: #1778055
This commit is contained in:
Sean McGinnis
2018-06-21 07:55:03 -05:00
parent 83864a25e2
commit a4fc1416ef
3 changed files with 36 additions and 12 deletions

View File

@@ -51,17 +51,23 @@ class FakeClient(object):
result = False result = False
return result return result
def assert_in_call(self, url_part):
"""Assert a call contained a part in its URL."""
assert self.client.callstack, "Expected call but no calls were made"
called = self.client.callstack[-1][1]
assert url_part in called, 'Expected %s in call but found %s' % (
url_part, called)
def assert_called(self, method, url, body=None, def assert_called(self, method, url, body=None,
partial_body=None, pos=-1, **kwargs): partial_body=None, pos=-1, **kwargs):
""" """Assert than an API method was just called."""
Assert than an API method was just called.
"""
expected = (method, url) expected = (method, url)
called = self.client.callstack[pos][0:2]
assert self.client.callstack, ("Expected %s %s but no calls " assert self.client.callstack, ("Expected %s %s but no calls "
"were made." % expected) "were made." % expected)
called = self.client.callstack[pos][0:2]
assert expected == called, 'Expected %s %s; got %s %s' % ( assert expected == called, 'Expected %s %s; got %s %s' % (
expected + called) expected + called)

View File

@@ -96,6 +96,9 @@ class ShellTest(utils.TestCase):
return self.shell.cs.assert_called(method, url, body, return self.shell.cs.assert_called(method, url, body,
partial_body, **kwargs) partial_body, **kwargs)
def assert_call_contained(self, url_part):
self.shell.cs.assert_in_call(url_part)
@ddt.data({'resource': None, 'query_url': None}, @ddt.data({'resource': None, 'query_url': None},
{'resource': 'volume', 'query_url': '?resource=volume'}, {'resource': 'volume', 'query_url': '?resource=volume'},
{'resource': 'group', 'query_url': '?resource=group'}) {'resource': 'group', 'query_url': '?resource=group'})
@@ -253,10 +256,16 @@ class ShellTest(utils.TestCase):
def test_type_list_with_filters(self): def test_type_list_with_filters(self):
self.run_command('--os-volume-api-version 3.52 type-list ' self.run_command('--os-volume-api-version 3.52 type-list '
'--filters extra_specs={key:value}') '--filters extra_specs={key:value}')
self.assert_called( self.assert_called('GET', mock.ANY)
'GET', '/types?%s' % parse.urlencode( self.assert_call_contained(
parse.urlencode(
{'extra_specs': {'extra_specs':
{six.text_type('key'): six.text_type('value')}})) {six.text_type('key'): six.text_type('value')}}))
self.assert_call_contained(parse.urlencode({'is_public': None}))
def test_type_list_no_filters(self):
self.run_command('--os-volume-api-version 3.52 type-list')
self.assert_called('GET', '/types?is_public=None')
@ddt.data("3.10", "3.11") @ddt.data("3.10", "3.11")
def test_list_with_group_id_after_3_10(self, version): def test_list_with_group_id_after_3_10(self, version):

View File

@@ -85,14 +85,23 @@ class VolumeTypeManager(base.ManagerWithFind):
def list(self, search_opts=None, is_public=None): def list(self, search_opts=None, is_public=None):
"""Lists all volume types. """Lists all volume types.
:rtype: list of :class:`VolumeType`. :param search_opts: Optional search filters.
:param is_public: Whether to only get public types.
:return: List of :class:`VolumeType`.
""" """
if not search_opts: if not search_opts:
search_opts = dict() search_opts = dict()
if is_public:
search_opts.update({"is_public": is_public}) # Remove 'all_tenants' option added by ManagerWithFind.findall(),
query_string = "?%s" % parse.urlencode( # as it is not a valid search option for volume_types.
search_opts) if search_opts else '' search_opts.pop('all_tenants', None)
# Need to keep backwards compatibility with is_public usage. If it
# isn't included then cinder will assume you want is_public=True, which
# negatively affects the results.
search_opts['is_public'] = is_public
query_string = "?%s" % parse.urlencode(search_opts)
return self._list("/types%s" % query_string, "volume_types") return self._list("/types%s" % query_string, "volume_types")
def get(self, volume_type): def get(self, volume_type):