Skip to content

Commit 6cdf7cb

Browse files
committed
PYTHON-5506 Add unittest for _RetryPolicy/_TokenBucket
1 parent 83798d1 commit 6cdf7cb

File tree

2 files changed

+85
-5
lines changed

2 files changed

+85
-5
lines changed

test/asynchronous/test_backpressure.py

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,15 @@
1919

2020
sys.path[0:0] = [""]
2121

22-
from test.asynchronous import AsyncIntegrationTest, async_client_context, unittest
23-
24-
from pymongo.asynchronous.helpers import _MAX_RETRIES
22+
from test.asynchronous import (
23+
AsyncIntegrationTest,
24+
AsyncPyMongoTestCase,
25+
async_client_context,
26+
unittest,
27+
)
28+
29+
from pymongo.asynchronous import helpers
30+
from pymongo.asynchronous.helpers import _MAX_RETRIES, _RetryPolicy, _TokenBucket
2531
from pymongo.errors import PyMongoError
2632

2733
_IS_SYNC = False
@@ -173,5 +179,39 @@ async def test_limit_retry_command(self):
173179
self.assertIn("Retryable", str(error.exception))
174180

175181

182+
class TestRetryPolicy(AsyncPyMongoTestCase):
183+
async def test_retry_policy(self):
184+
capacity = 10
185+
retry_policy = _RetryPolicy(_TokenBucket(capacity=capacity))
186+
self.assertEqual(retry_policy.attempts, helpers._MAX_RETRIES)
187+
self.assertEqual(retry_policy.backoff_initial, helpers._BACKOFF_INITIAL)
188+
self.assertEqual(retry_policy.backoff_max, helpers._BACKOFF_MAX)
189+
for i in range(1, helpers._MAX_RETRIES + 1):
190+
self.assertTrue(await retry_policy.should_retry(i))
191+
self.assertFalse(await retry_policy.should_retry(helpers._MAX_RETRIES + 1))
192+
for i in range(capacity - helpers._MAX_RETRIES):
193+
self.assertTrue(await retry_policy.should_retry(1))
194+
# No tokens left, should not retry.
195+
self.assertFalse(await retry_policy.should_retry(1))
196+
self.assertEqual(retry_policy.token_bucket.tokens, 0)
197+
198+
# record_success should generate tokens.
199+
for _ in range(int(2 / helpers.DEFAULT_RETRY_TOKEN_RETURN)):
200+
await retry_policy.record_success(retry=False)
201+
self.assertAlmostEqual(retry_policy.token_bucket.tokens, 2)
202+
for i in range(2):
203+
self.assertTrue(await retry_policy.should_retry(1))
204+
self.assertFalse(await retry_policy.should_retry(1))
205+
206+
# Recording a successful retry should return 1 additional token.
207+
await retry_policy.record_success(retry=True)
208+
self.assertAlmostEqual(
209+
retry_policy.token_bucket.tokens, 1 + helpers.DEFAULT_RETRY_TOKEN_RETURN
210+
)
211+
self.assertTrue(await retry_policy.should_retry(1))
212+
self.assertFalse(await retry_policy.should_retry(1))
213+
self.assertAlmostEqual(retry_policy.token_bucket.tokens, helpers.DEFAULT_RETRY_TOKEN_RETURN)
214+
215+
176216
if __name__ == "__main__":
177217
unittest.main()

test/test_backpressure.py

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,16 @@
1919

2020
sys.path[0:0] = [""]
2121

22-
from test import IntegrationTest, client_context, unittest
22+
from test import (
23+
IntegrationTest,
24+
PyMongoTestCase,
25+
client_context,
26+
unittest,
27+
)
2328

2429
from pymongo.errors import PyMongoError
25-
from pymongo.synchronous.helpers import _MAX_RETRIES
30+
from pymongo.synchronous import helpers
31+
from pymongo.synchronous.helpers import _MAX_RETRIES, _RetryPolicy, _TokenBucket
2632

2733
_IS_SYNC = True
2834

@@ -173,5 +179,39 @@ def test_limit_retry_command(self):
173179
self.assertIn("Retryable", str(error.exception))
174180

175181

182+
class TestRetryPolicy(PyMongoTestCase):
183+
def test_retry_policy(self):
184+
capacity = 10
185+
retry_policy = _RetryPolicy(_TokenBucket(capacity=capacity))
186+
self.assertEqual(retry_policy.attempts, helpers._MAX_RETRIES)
187+
self.assertEqual(retry_policy.backoff_initial, helpers._BACKOFF_INITIAL)
188+
self.assertEqual(retry_policy.backoff_max, helpers._BACKOFF_MAX)
189+
for i in range(1, helpers._MAX_RETRIES + 1):
190+
self.assertTrue(retry_policy.should_retry(i))
191+
self.assertFalse(retry_policy.should_retry(helpers._MAX_RETRIES + 1))
192+
for i in range(capacity - helpers._MAX_RETRIES):
193+
self.assertTrue(retry_policy.should_retry(1))
194+
# No tokens left, should not retry.
195+
self.assertFalse(retry_policy.should_retry(1))
196+
self.assertEqual(retry_policy.token_bucket.tokens, 0)
197+
198+
# record_success should generate tokens.
199+
for _ in range(int(2 / helpers.DEFAULT_RETRY_TOKEN_RETURN)):
200+
retry_policy.record_success(retry=False)
201+
self.assertAlmostEqual(retry_policy.token_bucket.tokens, 2)
202+
for i in range(2):
203+
self.assertTrue(retry_policy.should_retry(1))
204+
self.assertFalse(retry_policy.should_retry(1))
205+
206+
# Recording a successful retry should return 1 additional token.
207+
retry_policy.record_success(retry=True)
208+
self.assertAlmostEqual(
209+
retry_policy.token_bucket.tokens, 1 + helpers.DEFAULT_RETRY_TOKEN_RETURN
210+
)
211+
self.assertTrue(retry_policy.should_retry(1))
212+
self.assertFalse(retry_policy.should_retry(1))
213+
self.assertAlmostEqual(retry_policy.token_bucket.tokens, helpers.DEFAULT_RETRY_TOKEN_RETURN)
214+
215+
176216
if __name__ == "__main__":
177217
unittest.main()

0 commit comments

Comments
 (0)