Skip to content

Commit 6fc638a

Browse files
committed
try the prose test
1 parent af427fa commit 6fc638a

File tree

2 files changed

+128
-2
lines changed

2 files changed

+128
-2
lines changed

test/asynchronous/test_discovery_and_monitoring.py

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,12 @@
7070
)
7171
from pymongo.hello import Hello, HelloCompat
7272
from pymongo.helpers_shared import _check_command_response, _check_write_command_response
73-
from pymongo.monitoring import ServerHeartbeatFailedEvent, ServerHeartbeatStartedEvent
73+
from pymongo.monitoring import (
74+
ConnectionCheckOutFailedEvent,
75+
PoolClearedEvent,
76+
ServerHeartbeatFailedEvent,
77+
ServerHeartbeatStartedEvent,
78+
)
7479
from pymongo.server_description import SERVER_TYPE, ServerDescription
7580
from pymongo.topology_description import TOPOLOGY_TYPE
7681

@@ -446,6 +451,66 @@ async def mock_close(self, reason):
446451
AsyncConnection.close_conn = original_close
447452

448453

454+
class TestPoolBackpressure(AsyncIntegrationTest):
455+
# @async_client_context.require_version_min(8, 0, 0)
456+
async def test_connection_pool_is_not_cleared(self):
457+
listener = CMAPListener()
458+
459+
# Create a client that listens to CMAP events, with maxConnecting=100.
460+
client = await self.async_rs_or_single_client(maxConnecting=100, event_listeners=[listener])
461+
462+
# Use an admin client for test setup and teardown to enable and disable the ingress rate limiter.
463+
admin_client = self.client
464+
await admin_client.admin.command(
465+
"setParameter", 1, ingressConnectionEstablishmentRateLimiterEnabled=True
466+
)
467+
await admin_client.admin.command(
468+
"setParameter", 1, ingressConnectionEstablishmentRatePerSec=30
469+
)
470+
await admin_client.admin.command(
471+
"setParameter", 1, ingressConnectionEstablishmentBurstCapacitySecs=1
472+
)
473+
await admin_client.admin.command(
474+
"setParameter", 1, ingressConnectionEstablishmentMaxQueueDepth=1
475+
)
476+
477+
# Disable the ingress rate limiter on teardown.
478+
async def teardown():
479+
await admin_client.admin.command(
480+
"setParameter", 1, ingressConnectionEstablishmentRateLimiterEnabled=False
481+
)
482+
483+
self.addAsyncCleanup(teardown)
484+
485+
# Seed the collection with a document for us to query with a regex.
486+
await client.test.test.delete_many({})
487+
await client.test.test.insert_one({"str0": "abcdefg"})
488+
489+
# Run a regex operation to slow down the query.
490+
async def target():
491+
query = {"str0": {"$regex": "abcd"}}
492+
try:
493+
await client.test.test.find_one(query)
494+
except OperationFailure:
495+
pass
496+
497+
# Warm the pool with 10 tasks so there are existing connections.
498+
tasks = []
499+
for i in range(10):
500+
tasks.append(asyncio.create_task(target()))
501+
await asyncio.wait(tasks)
502+
503+
# Run 100 parallel operations that contend for connections.
504+
tasks = []
505+
for i in range(100):
506+
tasks.append(asyncio.create_task(target()))
507+
await asyncio.wait(tasks)
508+
509+
# Verify there were at least 10 connection checkout failed event but no pool cleared events.
510+
self.assertGreater(len(listener.events_by_type(ConnectionCheckOutFailedEvent)), 10)
511+
self.assertEqual(len(listener.events_by_type(PoolClearedEvent)), 0)
512+
513+
449514
class TestServerMonitoringMode(AsyncIntegrationTest):
450515
@async_client_context.require_no_load_balancer
451516
async def asyncSetUp(self):

test/test_discovery_and_monitoring.py

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,12 @@
6767
)
6868
from pymongo.hello import Hello, HelloCompat
6969
from pymongo.helpers_shared import _check_command_response, _check_write_command_response
70-
from pymongo.monitoring import ServerHeartbeatFailedEvent, ServerHeartbeatStartedEvent
70+
from pymongo.monitoring import (
71+
ConnectionCheckOutFailedEvent,
72+
PoolClearedEvent,
73+
ServerHeartbeatFailedEvent,
74+
ServerHeartbeatStartedEvent,
75+
)
7176
from pymongo.server_description import SERVER_TYPE, ServerDescription
7277
from pymongo.synchronous.settings import TopologySettings
7378
from pymongo.synchronous.topology import Topology, _ErrorContext
@@ -444,6 +449,62 @@ def mock_close(self, reason):
444449
Connection.close_conn = original_close
445450

446451

452+
class TestPoolBackpressure(IntegrationTest):
453+
# @client_context.require_version_min(8, 0, 0)
454+
def test_connection_pool_is_not_cleared(self):
455+
listener = CMAPListener()
456+
457+
# Create a client that listens to CMAP events, with maxConnecting=100.
458+
client = self.rs_or_single_client(maxConnecting=100, event_listeners=[listener])
459+
460+
# Use an admin client for test setup and teardown to enable and disable the ingress rate limiter.
461+
admin_client = self.client
462+
admin_client.admin.command(
463+
"setParameter", 1, ingressConnectionEstablishmentRateLimiterEnabled=True
464+
)
465+
admin_client.admin.command("setParameter", 1, ingressConnectionEstablishmentRatePerSec=30)
466+
admin_client.admin.command(
467+
"setParameter", 1, ingressConnectionEstablishmentBurstCapacitySecs=1
468+
)
469+
admin_client.admin.command("setParameter", 1, ingressConnectionEstablishmentMaxQueueDepth=1)
470+
471+
# Disable the ingress rate limiter on teardown.
472+
def teardown():
473+
admin_client.admin.command(
474+
"setParameter", 1, ingressConnectionEstablishmentRateLimiterEnabled=False
475+
)
476+
477+
self.addCleanup(teardown)
478+
479+
# Seed the collection with a document for us to query with a regex.
480+
client.test.test.delete_many({})
481+
client.test.test.insert_one({"str0": "abcdefg"})
482+
483+
# Run a regex operation to slow down the query.
484+
def target():
485+
query = {"str0": {"$regex": "abcd"}}
486+
try:
487+
client.test.test.find_one(query)
488+
except OperationFailure:
489+
pass
490+
491+
# Warm the pool with 10 tasks so there are existing connections.
492+
tasks = []
493+
for i in range(10):
494+
tasks.append(asyncio.create_task(target()))
495+
asyncio.wait(tasks)
496+
497+
# Run 100 parallel operations that contend for connections.
498+
tasks = []
499+
for i in range(100):
500+
tasks.append(asyncio.create_task(target()))
501+
asyncio.wait(tasks)
502+
503+
# Verify there were at least 10 connection checkout failed event but no pool cleared events.
504+
self.assertGreater(len(listener.events_by_type(ConnectionCheckOutFailedEvent)), 10)
505+
self.assertEqual(len(listener.events_by_type(PoolClearedEvent)), 0)
506+
507+
447508
class TestServerMonitoringMode(IntegrationTest):
448509
@client_context.require_no_load_balancer
449510
def setUp(self):

0 commit comments

Comments
 (0)