Support listing non-paginated response bodies
We previously tried to discover whether or not a resource supported pagination by making extra calls, and then another attempt was made to separate the idea of paginated and unpaginated by making separate calls and modifying Resource.page. We can instead pass in a pagination parameter to list, defaulting to True, which remains the one call to make in order to be yielded Resource objects. Change-Id: Ie97ef5b43fcabef145ab2758082ae9f2f400a0ab Related-Bug: 1410980
This commit is contained in:
@@ -706,8 +706,9 @@ class Resource(collections.MutableMapping):
|
||||
self.delete_by_id(session, self.id, path_args=self)
|
||||
|
||||
@classmethod
|
||||
def list(cls, session, limit=None, marker=None, path_args=None, **params):
|
||||
"""Get a response that is a list of potentially paginated objects.
|
||||
def list(cls, session, limit=None, marker=None, path_args=None,
|
||||
paginated=False, **params):
|
||||
"""Get a response that is a list of objects.
|
||||
|
||||
This method starts at ``limit`` and ``marker`` (both defaulting to
|
||||
None), advances the marker to the last item received in each response,
|
||||
@@ -726,6 +727,12 @@ class Resource(collections.MutableMapping):
|
||||
:param dict path_args: A dictionary of arguments to construct
|
||||
a compound URL.
|
||||
See `How path_args are used`_ for details.
|
||||
:param bool paginated: ``True`` if a GET to this resource returns
|
||||
a paginated series of responses, or ``False``
|
||||
if a GET returns only one page of data.
|
||||
**When paginated is False only one
|
||||
page of data will be returned regardless
|
||||
of the API's support of pagination.**
|
||||
:param dict params: Parameters to be passed into the underlying
|
||||
:meth:`~openstack.session.Session.get` method.
|
||||
|
||||
@@ -759,7 +766,7 @@ class Resource(collections.MutableMapping):
|
||||
yielded += 1
|
||||
yield value
|
||||
|
||||
if limit and yielded < limit:
|
||||
if not paginated or limit and yielded < limit:
|
||||
more_data = False
|
||||
|
||||
@classmethod
|
||||
|
||||
@@ -639,7 +639,8 @@ class ResourceTests(base.TestTransportBase):
|
||||
json=json_body)
|
||||
|
||||
objs = resource_class.list(self.session, limit=1,
|
||||
path_args=fake_arguments)
|
||||
path_args=fake_arguments,
|
||||
paginated=True)
|
||||
objs = list(objs)
|
||||
self.assertIn(marker, httpretty.last_request().path)
|
||||
self.assertEqual(3, len(objs))
|
||||
@@ -650,18 +651,28 @@ class ResourceTests(base.TestTransportBase):
|
||||
self.assertEqual(fake_name, obj.name)
|
||||
self.assertIsInstance(obj, FakeResource)
|
||||
|
||||
def test_list_bail_out(self):
|
||||
def _test_list_call_count(self, paginated):
|
||||
# Test that we've only made one call to receive all data
|
||||
results = [fake_data.copy(), fake_data.copy(), fake_data.copy()]
|
||||
body = mock.Mock(body={fake_resources: results})
|
||||
attrs = {"get.return_value": body}
|
||||
session = mock.Mock(**attrs)
|
||||
|
||||
list(FakeResource.list(session, limit=len(results) + 1,
|
||||
path_args=fake_arguments))
|
||||
path_args=fake_arguments,
|
||||
paginated=paginated))
|
||||
|
||||
# Ensure we only made one call to complete this.
|
||||
self.assertEqual(session.get.call_count, 1)
|
||||
|
||||
def test_list_bail_out(self):
|
||||
# When we get less data than limit, make sure we made one call
|
||||
self._test_list_call_count(True)
|
||||
|
||||
def test_list_nonpaginated(self):
|
||||
# When we call with paginated=False, make sure we made one call
|
||||
self._test_list_call_count(False)
|
||||
|
||||
def test_page(self):
|
||||
session = mock.Mock()
|
||||
session.get = mock.Mock()
|
||||
|
||||
Reference in New Issue
Block a user