Skip to content

Commit 3be7f76

Browse files
authored
PYTHON-4203 Update prose tests for mongos deprioritization during retryable ops (#2430)
1 parent 83fcf7c commit 3be7f76

File tree

2 files changed

+84
-18
lines changed

2 files changed

+84
-18
lines changed

test/asynchronous/test_retryable_reads.py

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
import threading
2222
from test.asynchronous.utils import async_set_fail_point
2323

24-
from pymongo.errors import AutoReconnect
24+
from pymongo.errors import OperationFailure
2525

2626
sys.path[0:0] = [""]
2727

@@ -147,15 +147,11 @@ async def test_pool_paused_error_is_retryable(self):
147147
class TestRetryableReads(AsyncIntegrationTest):
148148
@async_client_context.require_multiple_mongoses
149149
@async_client_context.require_failCommand_fail_point
150-
async def test_retryable_reads_in_sharded_cluster_multiple_available(self):
150+
async def test_retryable_reads_are_retried_on_a_different_mongos_when_one_is_available(self):
151151
fail_command = {
152152
"configureFailPoint": "failCommand",
153153
"mode": {"times": 1},
154-
"data": {
155-
"failCommands": ["find"],
156-
"closeConnection": True,
157-
"appName": "retryableReadTest",
158-
},
154+
"data": {"failCommands": ["find"], "errorCode": 6},
159155
}
160156

161157
mongos_clients = []
@@ -168,12 +164,11 @@ async def test_retryable_reads_in_sharded_cluster_multiple_available(self):
168164
listener = OvertCommandListener()
169165
client = await self.async_rs_or_single_client(
170166
async_client_context.mongos_seeds(),
171-
appName="retryableReadTest",
172167
event_listeners=[listener],
173168
retryReads=True,
174169
)
175170

176-
with self.assertRaises(AutoReconnect):
171+
with self.assertRaises(OperationFailure):
177172
await client.t.t.find_one({})
178173

179174
# Disable failpoints on each mongos
@@ -184,6 +179,45 @@ async def test_retryable_reads_in_sharded_cluster_multiple_available(self):
184179
self.assertEqual(len(listener.failed_events), 2)
185180
self.assertEqual(len(listener.succeeded_events), 0)
186181

182+
# Assert that both events occurred on different mongos.
183+
assert listener.failed_events[0].connection_id != listener.failed_events[1].connection_id
184+
185+
@async_client_context.require_multiple_mongoses
186+
@async_client_context.require_failCommand_fail_point
187+
async def test_retryable_reads_are_retried_on_the_same_mongos_when_no_others_are_available(
188+
self
189+
):
190+
fail_command = {
191+
"configureFailPoint": "failCommand",
192+
"mode": {"times": 1},
193+
"data": {"failCommands": ["find"], "errorCode": 6},
194+
}
195+
196+
host = async_client_context.mongos_seeds().split(",")[0]
197+
mongos_client = await self.async_rs_or_single_client(host)
198+
await async_set_fail_point(mongos_client, fail_command)
199+
200+
listener = OvertCommandListener()
201+
client = await self.async_rs_or_single_client(
202+
host,
203+
directConnection=False,
204+
event_listeners=[listener],
205+
retryReads=True,
206+
)
207+
208+
await client.t.t.find_one({})
209+
210+
# Disable failpoint.
211+
fail_command["mode"] = "off"
212+
await async_set_fail_point(mongos_client, fail_command)
213+
214+
# Assert that exactly one failed command event and one succeeded command event occurred.
215+
self.assertEqual(len(listener.failed_events), 1)
216+
self.assertEqual(len(listener.succeeded_events), 1)
217+
218+
# Assert that both events occurred on the same mongos.
219+
assert listener.succeeded_events[0].connection_id == listener.failed_events[0].connection_id
220+
187221

188222
if __name__ == "__main__":
189223
unittest.main()

test/test_retryable_reads.py

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
import threading
2222
from test.utils import set_fail_point
2323

24-
from pymongo.errors import AutoReconnect
24+
from pymongo.errors import OperationFailure
2525

2626
sys.path[0:0] = [""]
2727

@@ -147,15 +147,11 @@ def test_pool_paused_error_is_retryable(self):
147147
class TestRetryableReads(IntegrationTest):
148148
@client_context.require_multiple_mongoses
149149
@client_context.require_failCommand_fail_point
150-
def test_retryable_reads_in_sharded_cluster_multiple_available(self):
150+
def test_retryable_reads_are_retried_on_a_different_mongos_when_one_is_available(self):
151151
fail_command = {
152152
"configureFailPoint": "failCommand",
153153
"mode": {"times": 1},
154-
"data": {
155-
"failCommands": ["find"],
156-
"closeConnection": True,
157-
"appName": "retryableReadTest",
158-
},
154+
"data": {"failCommands": ["find"], "errorCode": 6},
159155
}
160156

161157
mongos_clients = []
@@ -168,12 +164,11 @@ def test_retryable_reads_in_sharded_cluster_multiple_available(self):
168164
listener = OvertCommandListener()
169165
client = self.rs_or_single_client(
170166
client_context.mongos_seeds(),
171-
appName="retryableReadTest",
172167
event_listeners=[listener],
173168
retryReads=True,
174169
)
175170

176-
with self.assertRaises(AutoReconnect):
171+
with self.assertRaises(OperationFailure):
177172
client.t.t.find_one({})
178173

179174
# Disable failpoints on each mongos
@@ -184,6 +179,43 @@ def test_retryable_reads_in_sharded_cluster_multiple_available(self):
184179
self.assertEqual(len(listener.failed_events), 2)
185180
self.assertEqual(len(listener.succeeded_events), 0)
186181

182+
# Assert that both events occurred on different mongos.
183+
assert listener.failed_events[0].connection_id != listener.failed_events[1].connection_id
184+
185+
@client_context.require_multiple_mongoses
186+
@client_context.require_failCommand_fail_point
187+
def test_retryable_reads_are_retried_on_the_same_mongos_when_no_others_are_available(self):
188+
fail_command = {
189+
"configureFailPoint": "failCommand",
190+
"mode": {"times": 1},
191+
"data": {"failCommands": ["find"], "errorCode": 6},
192+
}
193+
194+
host = client_context.mongos_seeds().split(",")[0]
195+
mongos_client = self.rs_or_single_client(host)
196+
set_fail_point(mongos_client, fail_command)
197+
198+
listener = OvertCommandListener()
199+
client = self.rs_or_single_client(
200+
host,
201+
directConnection=False,
202+
event_listeners=[listener],
203+
retryReads=True,
204+
)
205+
206+
client.t.t.find_one({})
207+
208+
# Disable failpoint.
209+
fail_command["mode"] = "off"
210+
set_fail_point(mongos_client, fail_command)
211+
212+
# Assert that exactly one failed command event and one succeeded command event occurred.
213+
self.assertEqual(len(listener.failed_events), 1)
214+
self.assertEqual(len(listener.succeeded_events), 1)
215+
216+
# Assert that both events occurred on the same mongos.
217+
assert listener.succeeded_events[0].connection_id == listener.failed_events[0].connection_id
218+
187219

188220
if __name__ == "__main__":
189221
unittest.main()

0 commit comments

Comments
 (0)