Add prose tests

This commit is contained in:
Noah Stapp 2026-02-20 13:48:22 -05:00
parent e666b895d6
commit e0d1267c00
2 changed files with 78 additions and 70 deletions

View File

@ -278,18 +278,54 @@ class AsyncTestClientBackpressure(AsyncIntegrationTest):
self.assertTrue(abs((end1 - start1) - (end0 - start0 + 3.1)) < 1)
@async_client_context.require_failCommand_appName
async def test_02_overload_retries_limited(self):
async def test_03_overload_retries_limited(self):
# Drivers should test that without adaptive retries enabled, overload errors are retried a maximum of five times.
# 1. Let `client` be a `MongoClient`.
client = self.client
# 2. Let `coll` be a collection.
coll = client.pymongo_test.coll
# 3. Configure the following failpoint:
failpoint = {
"configureFailPoint": "failCommand",
"mode": "alwaysOn",
"data": {
"failCommands": ["find"],
"errorCode": 462, # IngressRequestRateLimitExceeded
"errorLabels": ["RetryableError", "SystemOverloadedError"],
},
}
# 4. Perform a find operation with `coll` that fails.
async with self.fail_point(failpoint):
with self.assertRaises(PyMongoError) as error:
await coll.find_one({})
# 5. Assert that the raised error contains both the `RetryableError` and `SystemOverLoadedError` error labels.
self.assertIn("RetryableError", str(error.exception))
self.assertIn("SystemOverloadedError", str(error.exception))
# 6. Assert that the total number of started commands is MAX_RETRIES + 1.
self.assertEqual(len(self.listener.started_events), _MAX_RETRIES + 1)
@async_client_context.require_failCommand_appName
async def test_03_adaptive_retries_limited_by_tokens(self):
# Drivers should test that when enabled, adaptive retries are limited by the number of tokens in the bucket.
# 1. Let `client` be a `MongoClient` with adaptiveRetries=True.
client = await self.async_rs_or_single_client(
adaptive_retries=True, event_listeners=[self.listener]
)
# 2. Set `client`'s retry token bucket to have 2 tokens.
client._retry_policy.token_bucket.tokens = 2
# 3. Let `coll` be a collection.
coll = client.pymongo_test.coll
# 4. Configure the following failpoint:
failpoint = {
"configureFailPoint": "failCommand",
"mode": "alwaysOn",
"mode": {"times": 3},
"data": {
"failCommands": ["find"],
"errorCode": 462, # IngressRequestRateLimitExceeded
@ -306,39 +342,8 @@ class AsyncTestClientBackpressure(AsyncIntegrationTest):
self.assertIn("RetryableError", str(error.exception))
self.assertIn("SystemOverloadedError", str(error.exception))
# 7. Assert that the total number of started commands is MAX_RETRIES + 1.
self.assertEqual(len(self.listener.started_events), _MAX_RETRIES + 1)
@async_client_context.require_failCommand_appName
async def test_03_adaptive_retries_limited_by_tokens(self):
# Drivers should test that when enabled, adaptive retries are limited by the number of tokens in the bucket.
# 1. Let `client` be a `MongoClient` with adaptiveRetries=True.
client = await self.async_rs_or_single_client(adaptive_retries=True)
# 2. Set `client`'s retry token bucket to have 1 token.
client._retry_policy.token_bucket.tokens = 1
# 3. Let `coll` be a collection.
coll = client.pymongo_test.coll
# 4. Configure the following failpoint:
failpoint = {
"configureFailPoint": "failCommand",
"mode": {"times": 2},
"data": {
"failCommands": ["find", "insert", "update"],
"errorCode": 462, # IngressRequestRateLimitExceeded
"errorLabels": ["RetryableError", "SystemOverloadedError"],
},
}
# 5. Perform a find operation with `coll` that fails.
async with self.fail_point(failpoint):
with self.assertRaises(PyMongoError) as error:
await coll.find_one({})
# 6. Assert that the raised error contains both the `RetryableError` and `SystemOverLoadedError` error labels.
self.assertIn("RetryableError", str(error.exception))
self.assertIn("SystemOverloadedError", str(error.exception))
# 7. Assert that the total number of started commands is 3: one for the initial attempt and two for the retries.
self.assertEqual(len(self.listener.started_events), 3)
# Location of JSON test specifications.

View File

@ -278,18 +278,52 @@ class TestClientBackpressure(IntegrationTest):
self.assertTrue(abs((end1 - start1) - (end0 - start0 + 3.1)) < 1)
@client_context.require_failCommand_appName
def test_02_overload_retries_limited(self):
def test_03_overload_retries_limited(self):
# Drivers should test that without adaptive retries enabled, overload errors are retried a maximum of five times.
# 1. Let `client` be a `MongoClient`.
client = self.client
# 2. Let `coll` be a collection.
coll = client.pymongo_test.coll
# 3. Configure the following failpoint:
failpoint = {
"configureFailPoint": "failCommand",
"mode": "alwaysOn",
"data": {
"failCommands": ["find"],
"errorCode": 462, # IngressRequestRateLimitExceeded
"errorLabels": ["RetryableError", "SystemOverloadedError"],
},
}
# 4. Perform a find operation with `coll` that fails.
with self.fail_point(failpoint):
with self.assertRaises(PyMongoError) as error:
coll.find_one({})
# 5. Assert that the raised error contains both the `RetryableError` and `SystemOverLoadedError` error labels.
self.assertIn("RetryableError", str(error.exception))
self.assertIn("SystemOverloadedError", str(error.exception))
# 6. Assert that the total number of started commands is MAX_RETRIES + 1.
self.assertEqual(len(self.listener.started_events), _MAX_RETRIES + 1)
@client_context.require_failCommand_appName
def test_03_adaptive_retries_limited_by_tokens(self):
# Drivers should test that when enabled, adaptive retries are limited by the number of tokens in the bucket.
# 1. Let `client` be a `MongoClient` with adaptiveRetries=True.
client = self.rs_or_single_client(adaptive_retries=True, event_listeners=[self.listener])
# 2. Set `client`'s retry token bucket to have 2 tokens.
client._retry_policy.token_bucket.tokens = 2
# 3. Let `coll` be a collection.
coll = client.pymongo_test.coll
# 4. Configure the following failpoint:
failpoint = {
"configureFailPoint": "failCommand",
"mode": "alwaysOn",
"mode": {"times": 3},
"data": {
"failCommands": ["find"],
"errorCode": 462, # IngressRequestRateLimitExceeded
@ -306,39 +340,8 @@ class TestClientBackpressure(IntegrationTest):
self.assertIn("RetryableError", str(error.exception))
self.assertIn("SystemOverloadedError", str(error.exception))
# 7. Assert that the total number of started commands is MAX_RETRIES + 1.
self.assertEqual(len(self.listener.started_events), _MAX_RETRIES + 1)
@client_context.require_failCommand_appName
def test_03_adaptive_retries_limited_by_tokens(self):
# Drivers should test that when enabled, adaptive retries are limited by the number of tokens in the bucket.
# 1. Let `client` be a `MongoClient` with adaptiveRetries=True.
client = self.rs_or_single_client(adaptive_retries=True)
# 2. Set `client`'s retry token bucket to have 1 token.
client._retry_policy.token_bucket.tokens = 1
# 3. Let `coll` be a collection.
coll = client.pymongo_test.coll
# 4. Configure the following failpoint:
failpoint = {
"configureFailPoint": "failCommand",
"mode": {"times": 2},
"data": {
"failCommands": ["find", "insert", "update"],
"errorCode": 462, # IngressRequestRateLimitExceeded
"errorLabels": ["RetryableError", "SystemOverloadedError"],
},
}
# 5. Perform a find operation with `coll` that fails.
with self.fail_point(failpoint):
with self.assertRaises(PyMongoError) as error:
coll.find_one({})
# 6. Assert that the raised error contains both the `RetryableError` and `SystemOverLoadedError` error labels.
self.assertIn("RetryableError", str(error.exception))
self.assertIn("SystemOverloadedError", str(error.exception))
# 7. Assert that the total number of started commands is 3: one for the initial attempt and two for the retries.
self.assertEqual(len(self.listener.started_events), 3)
# Location of JSON test specifications.