Skip to content

Commit 4644074

Browse files
committed
update unified test and add prose test
1 parent 6333244 commit 4644074

File tree

3 files changed

+106
-386
lines changed

3 files changed

+106
-386
lines changed

test/asynchronous/test_client_backpressure.py

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@
1616
import os
1717
import pathlib
1818
import sys
19+
from time import perf_counter
20+
from unittest.mock import patch
21+
22+
from pymongo.errors import OperationFailure
1923

2024
sys.path[0:0] = [""]
2125

@@ -41,10 +45,57 @@ def setUpClass(cls) -> None:
4145
async def asyncSetUp(self) -> None:
4246
await super().asyncSetUp()
4347
self.listener.reset()
48+
self.app_name = self.__class__.__name__.lower()
4449
self.client = await self.async_rs_or_single_client(
45-
event_listeners=[self.listener], retryWrites=False
50+
event_listeners=[self.listener], retryWrites=False, appName=self.app_name
4651
)
4752

53+
@patch("random.random")
54+
async def test_01_operation_retry_uses_exponential_backoff(self, random_func):
55+
# Drivers should test that retries do not occur immediately when a SystemOverloadedError is encountered.
56+
57+
# 1. let `client` be a `MongoClient`
58+
client = self.client
59+
60+
# 2. let `collection` be a collection
61+
collection = client.test.test
62+
63+
# 3. Now, run transactions without backoff:
64+
65+
# a. Configure the random number generator used for jitter to always return `0` -- this effectively disables backoff.
66+
random_func.return_value = 0
67+
68+
# b. Configure the following failPoint:
69+
fail_point = dict(
70+
mode="alwaysOn",
71+
data=dict(
72+
failCommands=["insert"],
73+
errorCode=2,
74+
errorLabels=["SystemOverloadedError", "RetryableError"],
75+
appName=self.app_name,
76+
),
77+
)
78+
async with self.fail_point(fail_point):
79+
# c. Execute the following command. Expect that the command errors. Measure the duration of the command execution.
80+
start0 = perf_counter()
81+
with self.assertRaises(OperationFailure):
82+
await collection.insert_one({"a": 1})
83+
end0 = perf_counter()
84+
85+
# d. Configure the random number generator used for jitter to always return `1`.
86+
random_func.return_value = 1
87+
88+
# e. Execute step c again.
89+
start1 = perf_counter()
90+
with self.assertRaises(OperationFailure):
91+
await collection.insert_one({"a": 1})
92+
end1 = perf_counter()
93+
94+
# f. Compare the two time between the two runs.
95+
# The sum of 5 backoffs is 3.1 seconds. There is a 1-second window to account for potential variance between the two
96+
# runs.
97+
self.assertTrue(abs((end1 - start1) - (end0 - start0 + 3.1)) < 1)
98+
4899

49100
# Location of JSON test specifications.
50101
if _IS_SYNC:

0 commit comments

Comments
 (0)