From 10069fd33c046c7d0d2a8b5fa82780b50ab5836f Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Thu, 13 Aug 2026 09:06:59 -0500 Subject: [PATCH 1/2] PYTHON-6003 Fix flaky test_pool_unpause The default streaming SDAM protocol starts a separate RTT monitor that issues its own hello calls with the same appName, racing against the test's failCommand (mode.times=2) for the SDAM heartbeat monitor's own hello calls. When the RTT monitor's hello wins the race, the SDAM monitor never sees a failure and ServerHeartbeatFailedEvent never fires. Force serverMonitoringMode="poll" to remove the RTT monitor and the race. --- test/asynchronous/test_discovery_and_monitoring.py | 8 +++++++- test/test_discovery_and_monitoring.py | 8 +++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/test/asynchronous/test_discovery_and_monitoring.py b/test/asynchronous/test_discovery_and_monitoring.py index 6fc0e09a19..7ef98f11df 100644 --- a/test/asynchronous/test_discovery_and_monitoring.py +++ b/test/asynchronous/test_discovery_and_monitoring.py @@ -360,8 +360,14 @@ class TestPoolManagement(AsyncIntegrationTest): async def test_pool_unpause(self): # This test implements the prose test "AsyncConnection Pool Management" listener = CMAPHeartbeatListener() + # Force polling: streaming's RTT monitor sends its own hello calls with the same + # appName, which can consume the failCommand's mode.times budget below the SDAM + # heartbeat monitor, so ServerHeartbeatFailedEvent never fires (PYTHON-6003). _ = await self.async_single_client( - appName="SDAMPoolManagementTest", heartbeatFrequencyMS=500, event_listeners=[listener] + appName="SDAMPoolManagementTest", + heartbeatFrequencyMS=500, + event_listeners=[listener], + serverMonitoringMode="poll", ) # Assert that AsyncConnectionPoolReadyEvent occurs after the first # ServerHeartbeatSucceededEvent. diff --git a/test/test_discovery_and_monitoring.py b/test/test_discovery_and_monitoring.py index 612d52afbf..57c7c35066 100644 --- a/test/test_discovery_and_monitoring.py +++ b/test/test_discovery_and_monitoring.py @@ -360,8 +360,14 @@ class TestPoolManagement(IntegrationTest): def test_pool_unpause(self): # This test implements the prose test "Connection Pool Management" listener = CMAPHeartbeatListener() + # Force polling: streaming's RTT monitor sends its own hello calls with the same + # appName, which can consume the failCommand's mode.times budget below the SDAM + # heartbeat monitor, so ServerHeartbeatFailedEvent never fires (PYTHON-6003). _ = self.single_client( - appName="SDAMPoolManagementTest", heartbeatFrequencyMS=500, event_listeners=[listener] + appName="SDAMPoolManagementTest", + heartbeatFrequencyMS=500, + event_listeners=[listener], + serverMonitoringMode="poll", ) # Assert that ConnectionPoolReadyEvent occurs after the first # ServerHeartbeatSucceededEvent. From fac2e35ab75456a930be0472fdbbf715ffd83092 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Thu, 13 Aug 2026 10:24:20 -0500 Subject: [PATCH 2/2] PYTHON-6003 Clarify race condition wording in test_pool_unpause comment --- test/asynchronous/test_discovery_and_monitoring.py | 4 ++-- test/test_discovery_and_monitoring.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/asynchronous/test_discovery_and_monitoring.py b/test/asynchronous/test_discovery_and_monitoring.py index 7ef98f11df..84382cf86f 100644 --- a/test/asynchronous/test_discovery_and_monitoring.py +++ b/test/asynchronous/test_discovery_and_monitoring.py @@ -361,8 +361,8 @@ async def test_pool_unpause(self): # This test implements the prose test "AsyncConnection Pool Management" listener = CMAPHeartbeatListener() # Force polling: streaming's RTT monitor sends its own hello calls with the same - # appName, which can consume the failCommand's mode.times budget below the SDAM - # heartbeat monitor, so ServerHeartbeatFailedEvent never fires (PYTHON-6003). + # appName, which can consume the failCommand's mode.times budget before the SDAM + # heartbeat monitor's hello does, so ServerHeartbeatFailedEvent never fires (PYTHON-6003). _ = await self.async_single_client( appName="SDAMPoolManagementTest", heartbeatFrequencyMS=500, diff --git a/test/test_discovery_and_monitoring.py b/test/test_discovery_and_monitoring.py index 57c7c35066..7b36cc318a 100644 --- a/test/test_discovery_and_monitoring.py +++ b/test/test_discovery_and_monitoring.py @@ -361,8 +361,8 @@ def test_pool_unpause(self): # This test implements the prose test "Connection Pool Management" listener = CMAPHeartbeatListener() # Force polling: streaming's RTT monitor sends its own hello calls with the same - # appName, which can consume the failCommand's mode.times budget below the SDAM - # heartbeat monitor, so ServerHeartbeatFailedEvent never fires (PYTHON-6003). + # appName, which can consume the failCommand's mode.times budget before the SDAM + # heartbeat monitor's hello does, so ServerHeartbeatFailedEvent never fires (PYTHON-6003). _ = self.single_client( appName="SDAMPoolManagementTest", heartbeatFrequencyMS=500,