Merge "Prevent the endless loop in resource listing"

This commit is contained in:
Zuul
2021-03-03 21:39:28 +00:00
committed by Gerrit Code Review
2 changed files with 37 additions and 1 deletions

View File

@@ -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

View File

@@ -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!"