1
+ use std:: time:: Duration ;
2
+
3
+ use bson:: doc;
1
4
use tokio:: sync:: RwLockWriteGuard ;
2
5
3
- use crate :: test:: { run_spec_test, LOCK } ;
6
+ use crate :: {
7
+ test:: {
8
+ run_spec_test,
9
+ FailCommandOptions ,
10
+ FailPoint ,
11
+ FailPointMode ,
12
+ TestClient ,
13
+ CLIENT_OPTIONS ,
14
+ LOCK ,
15
+ } ,
16
+ RUNTIME ,
17
+ } ;
4
18
5
19
use super :: run_v2_test;
6
20
@@ -10,3 +24,37 @@ async fn run() {
10
24
let _guard: RwLockWriteGuard < ( ) > = LOCK . run_exclusively ( ) . await ;
11
25
run_spec_test ( & [ "retryable-reads" ] , run_v2_test) . await ;
12
26
}
27
+
28
+ /// Test ensures that the connection used in the first attempt of a retry is released back into the
29
+ /// pool before the second attempt.
30
+ #[ cfg_attr( feature = "tokio-runtime" , tokio:: test( flavor = "multi_thread" ) ) ]
31
+ #[ cfg_attr( feature = "async-std-runtime" , async_std:: test) ]
32
+ async fn retry_releases_connection ( ) {
33
+ let _guard: RwLockWriteGuard < ( ) > = LOCK . run_exclusively ( ) . await ;
34
+
35
+ let mut client_options = CLIENT_OPTIONS . clone ( ) ;
36
+ client_options. hosts . drain ( 1 ..) ;
37
+ client_options. retry_reads = Some ( true ) ;
38
+ client_options. max_pool_size = Some ( 1 ) ;
39
+
40
+ let client = TestClient :: with_options ( Some ( client_options) ) . await ;
41
+ if !client. supports_fail_command ( ) . await {
42
+ println ! ( "skipping retry_releases_connection due to failCommand not being supported" ) ;
43
+ return ;
44
+ }
45
+
46
+ let collection = client
47
+ . database ( "retry_releases_connection" )
48
+ . collection ( "retry_releases_connection" ) ;
49
+ collection. insert_one ( doc ! { "x" : 1 } , None ) . await . unwrap ( ) ;
50
+
51
+ let options = FailCommandOptions :: builder ( ) . error_code ( 91 ) . build ( ) ;
52
+ let failpoint = FailPoint :: fail_command ( & [ "find" ] , FailPointMode :: Times ( 1 ) , Some ( options) ) ;
53
+ let _fp_guard = client. enable_failpoint ( failpoint, None ) . await . unwrap ( ) ;
54
+
55
+ RUNTIME
56
+ . timeout ( Duration :: from_secs ( 1 ) , collection. find_one ( doc ! { } , None ) )
57
+ . await
58
+ . expect ( "operation should not time out" )
59
+ . expect ( "find should succeed" ) ;
60
+ }
0 commit comments