@@ -84,6 +84,11 @@ type WriteConcernErrorData struct {
84
84
ErrInfo bson.Raw `bson:"errInfo,omitempty"`
85
85
}
86
86
87
+ type failPoint struct {
88
+ name string
89
+ client * mongo.Client
90
+ }
91
+
87
92
// T is a wrapper around testing.T.
88
93
type T struct {
89
94
// connsCheckedOut is the net number of connections checked out during test execution.
@@ -103,7 +108,7 @@ type T struct {
103
108
createdColls []* Collection // collections created in this test
104
109
proxyDialer * proxyDialer
105
110
dbName , collName string
106
- failPointNames [] string
111
+ failPoints [] failPoint
107
112
minServerVersion string
108
113
maxServerVersion string
109
114
validTopologies []TopologyKind
@@ -128,14 +133,16 @@ type T struct {
128
133
succeeded []* event.CommandSucceededEvent
129
134
failed []* event.CommandFailedEvent
130
135
131
- Client * mongo.Client
132
- DB * mongo.Database
133
- Coll * mongo.Collection
136
+ Client * mongo.Client
137
+ fpClients map [* mongo.Client ]bool
138
+ DB * mongo.Database
139
+ Coll * mongo.Collection
134
140
}
135
141
136
142
func newT (wrapped * testing.T , opts ... * Options ) * T {
137
143
t := & T {
138
- T : wrapped ,
144
+ T : wrapped ,
145
+ fpClients : make (map [* mongo.Client ]bool ),
139
146
}
140
147
for _ , opt := range opts {
141
148
for _ , optFn := range opt .optFuncs {
@@ -202,6 +209,12 @@ func (t *T) cleanup() {
202
209
// always disconnect the client regardless of clientType because Client.Disconnect will work against
203
210
// all deployments
204
211
_ = t .Client .Disconnect (context .Background ())
212
+ for client , v := range t .fpClients {
213
+ if v {
214
+ client .Disconnect (context .Background ())
215
+ }
216
+ }
217
+ t .fpClients = nil
205
218
}
206
219
207
220
// Run creates a new T instance for a sub-test and runs the given callback. It also creates a new collection using the
@@ -254,9 +267,11 @@ func (t *T) RunOpts(name string, opts *Options, callback func(mt *T)) {
254
267
sub .ClearFailPoints ()
255
268
sub .ClearCollections ()
256
269
}
257
- // only disconnect client if it's not being shared
270
+ // only disconnect client if it's not being shared and not used by fail points.
258
271
if sub .shareClient == nil || ! * sub .shareClient {
259
- _ = sub .Client .Disconnect (context .Background ())
272
+ if _ , ok := sub .fpClients [sub .Client ]; ! ok {
273
+ _ = sub .Client .Disconnect (context .Background ())
274
+ }
260
275
}
261
276
assert .Equal (sub , 0 , sessions , "%v sessions checked out" , sessions )
262
277
assert .Equal (sub , 0 , conns , "%v connections checked out" , conns )
@@ -405,7 +420,10 @@ func (t *T) ResetClient(opts *options.ClientOptions) {
405
420
t .clientOpts = opts
406
421
}
407
422
408
- _ = t .Client .Disconnect (context .Background ())
423
+ // Disconnect client if it is not being used by fail points.
424
+ if _ , ok := t .fpClients [t .Client ]; ! ok {
425
+ _ = t .Client .Disconnect (context .Background ())
426
+ }
409
427
t .createTestClient ()
410
428
t .DB = t .Client .Database (t .dbName )
411
429
t .Coll = t .DB .Collection (t .collName , t .collOpts )
@@ -562,7 +580,8 @@ func (t *T) SetFailPoint(fp FailPoint) {
562
580
if err := SetFailPoint (fp , t .Client ); err != nil {
563
581
t .Fatal (err )
564
582
}
565
- t .failPointNames = append (t .failPointNames , fp .ConfigureFailPoint )
583
+ t .fpClients [t .Client ] = true
584
+ t .failPoints = append (t .failPoints , failPoint {fp .ConfigureFailPoint , t .Client })
566
585
}
567
586
568
587
// SetFailPointFromDocument sets the fail point represented by the given document for the client associated with T. This
@@ -574,30 +593,35 @@ func (t *T) SetFailPointFromDocument(fp bson.Raw) {
574
593
t .Fatal (err )
575
594
}
576
595
596
+ t .fpClients [t .Client ] = true
577
597
name := fp .Index (0 ).Value ().StringValue ()
578
- t .failPointNames = append (t .failPointNames , name )
598
+ t .failPoints = append (t .failPoints , failPoint { name , t . Client } )
579
599
}
580
600
581
601
// TrackFailPoint adds the given fail point to the list of fail points to be disabled when the current test finishes.
582
602
// This function does not create a fail point on the server.
583
- func (t * T ) TrackFailPoint (fpName string ) {
584
- t .failPointNames = append (t .failPointNames , fpName )
603
+ func (t * T ) TrackFailPoint (fpName string , client * mongo.Client ) {
604
+ t .fpClients [client ] = true
605
+ t .failPoints = append (t .failPoints , failPoint {fpName , client })
585
606
}
586
607
587
608
// ClearFailPoints disables all previously set failpoints for this test.
588
609
func (t * T ) ClearFailPoints () {
589
- db := t .Client .Database ("admin" )
590
- for _ , fp := range t .failPointNames {
610
+ for _ , fp := range t .failPoints {
591
611
cmd := bson.D {
592
- {"configureFailPoint" , fp },
612
+ {"configureFailPoint" , fp . name },
593
613
{"mode" , "off" },
594
614
}
595
- err := db .RunCommand (context .Background (), cmd ).Err ()
615
+ err := fp . client . Database ( "admin" ) .RunCommand (context .Background (), cmd ).Err ()
596
616
if err != nil {
597
- t .Fatalf ("error clearing fail point %s: %v" , fp , err )
617
+ t .Fatalf ("error clearing fail point %s: %v" , fp .name , err )
618
+ }
619
+ if fp .client != t .Client {
620
+ _ = fp .client .Disconnect (context .Background ())
621
+ t .fpClients [fp .client ] = false
598
622
}
599
623
}
600
- t .failPointNames = t .failPointNames [:0 ]
624
+ t .failPoints = t .failPoints [:0 ]
601
625
}
602
626
603
627
// CloneDatabase modifies the default database for this test to match the given options.
@@ -684,19 +708,17 @@ func (t *T) createTestClient() {
684
708
})
685
709
}
686
710
687
- var err error
711
+ var uriOpts * options. ClientOptions
688
712
switch t .clientType {
689
713
case Pinned :
690
714
// pin to first mongos
691
715
pinnedHostList := []string {testContext .connString .Hosts [0 ]}
692
- uriOpts := options .Client ().ApplyURI (testContext .connString .Original ).SetHosts (pinnedHostList )
693
- t .Client , err = mongo .NewClient (uriOpts , clientOpts )
716
+ uriOpts = options .Client ().ApplyURI (testContext .connString .Original ).SetHosts (pinnedHostList )
694
717
case Mock :
695
718
// clear pool monitor to avoid configuration error
696
719
clientOpts .PoolMonitor = nil
697
720
t .mockDeployment = newMockDeployment ()
698
721
clientOpts .Deployment = t .mockDeployment
699
- t .Client , err = mongo .NewClient (clientOpts )
700
722
case Proxy :
701
723
t .proxyDialer = newProxyDialer ()
702
724
clientOpts .SetDialer (t .proxyDialer )
@@ -706,16 +728,17 @@ func (t *T) createTestClient() {
706
728
case Default :
707
729
// Use a different set of options to specify the URI because clientOpts may already have a URI or host seedlist
708
730
// specified.
709
- var uriOpts * options.ClientOptions
710
731
if clientOpts .Deployment == nil {
711
732
// Only specify URI if the deployment is not set to avoid setting topology/server options along with the
712
733
// deployment.
713
734
uriOpts = options .Client ().ApplyURI (testContext .connString .Original )
714
735
}
715
-
716
- // Pass in uriOpts first so clientOpts wins if there are any conflicting settings.
717
- t .Client , err = mongo .NewClient (uriOpts , clientOpts )
718
736
}
737
+ t .clientOpts = options .MergeClientOptions (uriOpts , clientOpts )
738
+
739
+ var err error
740
+ // Pass in uriOpts first so clientOpts wins if there are any conflicting settings.
741
+ t .Client , err = mongo .NewClient (t .clientOpts )
719
742
if err != nil {
720
743
t .Fatalf ("error creating client: %v" , err )
721
744
}
0 commit comments