2121import threading
2222from test .asynchronous .utils import async_set_fail_point
2323
24- from pymongo .errors import AutoReconnect
24+ from pymongo .errors import OperationFailure
2525
2626sys .path [0 :0 ] = ["" ]
2727
@@ -147,15 +147,11 @@ async def test_pool_paused_error_is_retryable(self):
147147class 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
188222if __name__ == "__main__" :
189223 unittest .main ()
0 commit comments