Skip to content

Commit f1fc9e9

Browse files
committed
Update rate limit testing
1 parent b95a85d commit f1fc9e9

File tree

2 files changed

+34
-20
lines changed

2 files changed

+34
-20
lines changed

ciscosparkapi/restsession.py

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@
3939
# Module Constants
4040
DEFAULT_SINGLE_REQUEST_TIMEOUT = 20.0
4141
DEFAULT_RATE_LIMIT_TIMEOUT = 60.0
42-
RATE_LIMIT_EXCEEDED_RESPONSE_CODE = 429
42+
RATE_LIMIT_RESPONSE_CODE = 429
43+
RATE_LIMIT_LOG_MESSAGE = "Received a [%s] rate-limit response code."
4344

4445

4546
# Helper Functions
@@ -251,7 +252,6 @@ def request(self, method, relative_url, erc, **kwargs):
251252
kwargs.setdefault('timeout', self.single_request_timeout)
252253

253254
start_time = time.time()
254-
finish_time = start_time + self.rate_limit_timeout
255255

256256
while True:
257257
# Make the HTTP request to the API endpoint
@@ -264,23 +264,25 @@ def request(self, method, relative_url, erc, **kwargs):
264264
except SparkApiError as e:
265265

266266
# Catch rate-limit errors
267-
if e.response_code == RATE_LIMIT_EXCEEDED_RESPONSE_CODE \
267+
if e.response_code == RATE_LIMIT_RESPONSE_CODE \
268268
and response.headers.get('Retry-After'):
269269

270-
logger.debug("Received a [%s] rate limit response. "
271-
"Attempting to retry.", e.response_code)
270+
logger.debug(RATE_LIMIT_LOG_MESSAGE,
271+
e.response_code)
272272

273-
rate_limit_wait = response.headers['Retry-After']
273+
rate_limit_wait = float(response.headers['Retry-After'])
274274

275275
if self.rate_limit_timeout is None:
276276
# Retry indefinitely
277-
logger.debug("Waiting {:0.3f} seconds. "
278-
"rate_limit_timeout is None; "
277+
logger.debug("Rate-limiting; waiting {:0.3f} seconds. "
278+
"rate_limit_timeout is None. "
279279
"will retry indefinitely."
280280
"".format(rate_limit_wait))
281281
time.sleep(rate_limit_wait)
282282
continue
283-
elif time.time() + rate_limit_wait < finish_time:
283+
284+
elif (time.time() + rate_limit_wait
285+
< start_time + self.rate_limit_timeout):
284286
# Retry if doing so will not exceed the finish time
285287
logger.debug("Waiting {:0.3f} seconds. "
286288
"rate_limit_timeout is {:0.3f} seconds, "
@@ -291,6 +293,7 @@ def request(self, method, relative_url, erc, **kwargs):
291293
finish_time - time.time()))
292294
time.sleep(rate_limit_wait)
293295
continue
296+
294297
else:
295298
# Time exceeded re-raise the rate limit SparkApiError
296299
raise
@@ -301,6 +304,8 @@ def request(self, method, relative_url, erc, **kwargs):
301304

302305
else:
303306
# No errors - return the response object
307+
logger.debug("Response Code [%s]: %s",
308+
response.status_code, response.url)
304309
return response
305310

306311
def get(self, url, params=None, **kwargs):

tests/test_restsession.py

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,10 @@
66

77
import pytest
88

9-
from ciscosparkapi.exceptions import SPARK_RESPONSE_CODES
10-
11-
# Constants
12-
RATE_LIMIT_RESPONSE_CODE = 429
13-
RATE_LIMIT_RESPONSE_TEXT = SPARK_RESPONSE_CODES[RATE_LIMIT_RESPONSE_CODE]
14-
RATE_LIMIT_LOG_MESSAGE = ("Received a [%s] rate limit response. "
15-
"Attempting to retry.")
9+
from ciscosparkapi.restsession import (
10+
RATE_LIMIT_RESPONSE_CODE,
11+
RATE_LIMIT_LOG_MESSAGE
12+
)
1613

1714

1815
# Helper Classes
@@ -39,7 +36,13 @@ class TestRestSession:
3936
"""Test edge cases of core RestSession functionality."""
4037

4138
@pytest.mark.ratelimit
42-
def test_rate_limit_support(self, api, rooms_list, add_rooms):
39+
def test_rate_limit_retry_indefinitely(self, api, rooms_list, add_rooms):
40+
logger = logging.getLogger(__name__)
41+
42+
# Save state and initialize test setup
43+
original_rate_limit_timer = api._session.rate_limit_timeout
44+
api._session.rate_limit_timeout = None
45+
4346
# Add log handler
4447
root_logger = logging.getLogger()
4548
rate_limit_detector = RateLimitDetector()
@@ -48,13 +51,19 @@ def test_rate_limit_support(self, api, rooms_list, add_rooms):
4851
try:
4952
# Try and trigger a rate-limit
5053
rooms = api.rooms.list(max=1)
54+
request_count = 0
5155
while not rate_limit_detector.rate_limit_detected:
5256
for room in rooms:
53-
# Do nothing
54-
pass
57+
request_count += 1
58+
if rate_limit_detector.rate_limit_detected:
59+
break
5560

5661
finally:
57-
# Remove the log handler
62+
logger.info("Rate-limit reached with approximately %s requests.",
63+
request_count)
64+
# Remove the log handler and restore the pre-test state
5865
root_logger.removeHandler(rate_limit_detector)
66+
api._session.rate_limit_timeout = original_rate_limit_timer
5967

68+
# Assert test condition
6069
assert rate_limit_detector.rate_limit_detected == True

0 commit comments

Comments
 (0)