Skip to content

Commit 98c002a

Browse files
authored
PYTHON-3689 Fix flaky test_load_balancing without @flaky decorator (#2845)
1 parent fff9bbf commit 98c002a

4 files changed

Lines changed: 40 additions & 6 deletions

File tree

test/asynchronous/test_server_selection_in_window.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
from pathlib import Path
2222
from test.asynchronous import AsyncIntegrationTest, async_client_context, unittest
2323
from test.asynchronous.helpers import ConcurrentRunner
24-
from test.asynchronous.utils import flaky
2524
from test.asynchronous.utils_selection_tests import create_topology
2625
from test.asynchronous.utils_spec_runner import AsyncSpecTestCreator
2726
from test.utils_shared import (
@@ -138,7 +137,6 @@ async def frequencies(self, client, listener, n_finds=10):
138137

139138
@async_client_context.require_failCommand_appName
140139
@async_client_context.require_multiple_mongoses
141-
@flaky(reason="PYTHON-3689")
142140
async def test_load_balancing(self):
143141
listener = OvertCommandListener()
144142
cmap_listener = CMAPListener()
@@ -165,12 +163,32 @@ async def test_load_balancing(self):
165163
"appName": "loadBalancingTest",
166164
},
167165
}
166+
coll = client.test.test
167+
N_TASKS = 10
168168
async with self.fail_point(delay_finds):
169169
nodes = async_client_context.client.nodes
170170
self.assertEqual(len(nodes), 1)
171171
delayed_server = next(iter(nodes))
172+
# Start background tasks to build up op_count on the delayed server.
173+
# This ensures the measurement phase sees a stable op_count imbalance
174+
# rather than a 50/50 random distribution from equal initial counts.
175+
background_tasks = [FinderTask(coll, 1) for _ in range(N_TASKS)]
176+
for task in background_tasks:
177+
await task.start()
178+
# Wait until all background finds are dispatched so the delayed
179+
# server's finds are in-flight (each blocked for 500ms).
180+
await async_wait_until(
181+
lambda: len(listener.started_events) >= N_TASKS,
182+
"background tasks to dispatch finds",
183+
)
184+
# Measure distribution while the delayed server is busy.
185+
listener.reset()
172186
freqs = await self.frequencies(client, listener)
173187
self.assertLessEqual(freqs[delayed_server], 0.25)
188+
for task in background_tasks:
189+
await task.join()
190+
for task in background_tasks:
191+
self.assertTrue(task.passed)
174192
listener.reset()
175193
freqs = await self.frequencies(client, listener, n_finds=150)
176194
self.assertAlmostEqual(freqs[delayed_server], 0.50, delta=0.15)

test/asynchronous/unified_format.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1470,7 +1470,6 @@ async def run_scenario(self, spec, uri=None):
14701470
("PYTHON-5174", ".*Driver_extends_timeout_while_streaming"),
14711471
("PYTHON-5315", ".*TestSrvPolling.test_recover_from_initially_.*"),
14721472
("PYTHON-4987", ".*UnknownTransactionCommitResult_labels_to_connection_errors"),
1473-
("PYTHON-3689", ".*TestProse.test_load_balancing"),
14741473
("PYTHON-3522", ".*csot.*"),
14751474
]
14761475
for reason, flaky_test in flaky_tests:

test/test_server_selection_in_window.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
from pathlib import Path
2222
from test import IntegrationTest, client_context, unittest
2323
from test.helpers import ConcurrentRunner
24-
from test.utils import flaky
2524
from test.utils_selection_tests import create_topology
2625
from test.utils_shared import (
2726
CMAPListener,
@@ -138,7 +137,6 @@ def frequencies(self, client, listener, n_finds=10):
138137

139138
@client_context.require_failCommand_appName
140139
@client_context.require_multiple_mongoses
141-
@flaky(reason="PYTHON-3689")
142140
def test_load_balancing(self):
143141
listener = OvertCommandListener()
144142
cmap_listener = CMAPListener()
@@ -165,12 +163,32 @@ def test_load_balancing(self):
165163
"appName": "loadBalancingTest",
166164
},
167165
}
166+
coll = client.test.test
167+
N_TASKS = 10
168168
with self.fail_point(delay_finds):
169169
nodes = client_context.client.nodes
170170
self.assertEqual(len(nodes), 1)
171171
delayed_server = next(iter(nodes))
172+
# Start background tasks to build up op_count on the delayed server.
173+
# This ensures the measurement phase sees a stable op_count imbalance
174+
# rather than a 50/50 random distribution from equal initial counts.
175+
background_tasks = [FinderTask(coll, 1) for _ in range(N_TASKS)]
176+
for task in background_tasks:
177+
task.start()
178+
# Wait until all background finds are dispatched so the delayed
179+
# server's finds are in-flight (each blocked for 500ms).
180+
wait_until(
181+
lambda: len(listener.started_events) >= N_TASKS,
182+
"background tasks to dispatch finds",
183+
)
184+
# Measure distribution while the delayed server is busy.
185+
listener.reset()
172186
freqs = self.frequencies(client, listener)
173187
self.assertLessEqual(freqs[delayed_server], 0.25)
188+
for task in background_tasks:
189+
task.join()
190+
for task in background_tasks:
191+
self.assertTrue(task.passed)
174192
listener.reset()
175193
freqs = self.frequencies(client, listener, n_finds=150)
176194
self.assertAlmostEqual(freqs[delayed_server], 0.50, delta=0.15)

test/unified_format.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1457,7 +1457,6 @@ def run_scenario(self, spec, uri=None):
14571457
("PYTHON-5174", ".*Driver_extends_timeout_while_streaming"),
14581458
("PYTHON-5315", ".*TestSrvPolling.test_recover_from_initially_.*"),
14591459
("PYTHON-4987", ".*UnknownTransactionCommitResult_labels_to_connection_errors"),
1460-
("PYTHON-3689", ".*TestProse.test_load_balancing"),
14611460
("PYTHON-3522", ".*csot.*"),
14621461
]
14631462
for reason, flaky_test in flaky_tests:

0 commit comments

Comments
 (0)