Merge "Prevent the endless loop in resource listing"
This commit is contained in:
@@ -1755,7 +1755,7 @@ class Resource(dict):
|
||||
data = response.json()
|
||||
|
||||
# Discard any existing pagination keys
|
||||
query_params.pop('marker', None)
|
||||
last_marker = query_params.pop('marker', None)
|
||||
query_params.pop('limit', None)
|
||||
|
||||
if cls.resources_key:
|
||||
@@ -1788,6 +1788,17 @@ class Resource(dict):
|
||||
if resources and paginated:
|
||||
uri, next_params = cls._get_next_link(
|
||||
uri, response, data, marker, limit, total_yielded)
|
||||
try:
|
||||
if next_params['marker'] == last_marker:
|
||||
# If next page marker is same as what we were just
|
||||
# asked something went terribly wrong. Some ancient
|
||||
# services had bugs.
|
||||
raise exceptions.SDKException(
|
||||
'Endless pagination loop detected, aborting'
|
||||
)
|
||||
except KeyError:
|
||||
# do nothing, exception handling is cheaper then "if"
|
||||
pass
|
||||
query_params.update(next_params)
|
||||
else:
|
||||
return
|
||||
|
@@ -2086,6 +2086,31 @@ class TestResourceActions(base.TestCase):
|
||||
self.assertEqual(ids[0], results[0].id)
|
||||
self.assertIsInstance(results[0], self.test_class)
|
||||
|
||||
def test_list_paginated_infinite_loop(self):
|
||||
q_limit = 1
|
||||
mock_response = mock.Mock()
|
||||
mock_response.status_code = 200
|
||||
mock_response.links = {}
|
||||
mock_response.json.side_effect = [
|
||||
{
|
||||
"resources": [{"id": 1}],
|
||||
}, {
|
||||
"resources": [{"id": 1}],
|
||||
}]
|
||||
|
||||
self.session.get.return_value = mock_response
|
||||
|
||||
class Test(self.test_class):
|
||||
_query_mapping = resource.QueryParameters("limit")
|
||||
|
||||
res = Test.list(self.session, paginated=True, limit=q_limit)
|
||||
|
||||
self.assertRaises(
|
||||
exceptions.SDKException,
|
||||
list,
|
||||
res
|
||||
)
|
||||
|
||||
def test_list_query_params(self):
|
||||
id = 1
|
||||
qp = "query param!"
|
||||
|
Reference in New Issue
Block a user