@@ -22,77 +22,97 @@ import (
2222
2323var dbName = fmt .Sprintf ("goleak-%d" , time .Now ().Unix ())
2424
25- func TestMain (m * testing.M ) {
26- goleak .VerifyTestMain (m )
27- }
28-
2925// TestGoroutineLeak creates clients with various client configurations, runs
3026// some operations with each one, then disconnects the client. It asserts that
3127// no goroutines were leaked after the client is disconnected.
3228func TestGoroutineLeak (t * testing.T ) {
33- uri := "mongodb://localhost:27017"
34- if u := os .Getenv ("MONGODB_URI" ); u != "" {
35- uri = u
36- }
37-
3829 testCases := []struct {
3930 desc string
4031 opts * options.ClientOptions
4132 }{
4233 {
4334 desc : "base" ,
44- opts : options .Client (). ApplyURI ( uri ) ,
35+ opts : options .Client (),
4536 },
4637 {
4738 desc : "compressors=snappy" ,
48- opts : options .Client ().ApplyURI ( uri ). SetCompressors ([]string {"snappy" }),
39+ opts : options .Client ().SetCompressors ([]string {"snappy" }),
4940 },
5041 {
5142 desc : "compressors=zlib" ,
52- opts : options .Client ().ApplyURI ( uri ). SetCompressors ([]string {"zlib" }),
43+ opts : options .Client ().SetCompressors ([]string {"zlib" }),
5344 },
5445 {
5546 desc : "compressors=zstd" ,
56- opts : options .Client ().ApplyURI ( uri ). SetCompressors ([]string {"zstd" }),
47+ opts : options .Client ().SetCompressors ([]string {"zstd" }),
5748 },
5849 {
5950 desc : "minPoolSize=10" ,
60- opts : options .Client ().ApplyURI ( uri ). SetMinPoolSize (10 ),
51+ opts : options .Client ().SetMinPoolSize (10 ),
6152 },
6253 {
6354 desc : "serverMonitoringMode=poll" ,
64- opts : options .Client ().ApplyURI ( uri ). SetServerMonitoringMode (options .ServerMonitoringModePoll ),
55+ opts : options .Client ().SetServerMonitoringMode (options .ServerMonitoringModePoll ),
6556 },
6657 }
58+
6759 for _ , tc := range testCases {
6860 // These can't be run in parallel because goleak currently can't filter
6961 // out goroutines from other parallel subtests.
7062 t .Run (tc .desc , func (t * testing.T ) {
7163 defer goleak .VerifyNone (t )
7264
73- client , err := mongo .Connect (context .Background (), tc .opts )
65+ base := options .Client ()
66+ if u := os .Getenv ("MONGODB_URI" ); u != "" {
67+ base .ApplyURI (u )
68+ }
69+ client , err := mongo .Connect (context .Background (), base , tc .opts )
7470 require .NoError (t , err )
7571
7672 defer func () {
7773 err = client .Disconnect (context .Background ())
7874 require .NoError (t , err )
7975 }()
8076
81- coll := client .Database (dbName ). Collection ( collectionName ( t ) )
77+ db := client .Database (dbName )
8278 defer func () {
83- err := coll .Drop (context .Background ())
79+ err := db .Drop (context .Background ())
8480 require .NoError (t , err )
8581 }()
8682
87- _ , err = coll .InsertOne (context .Background (), bson.M {"x" : 123 })
83+ coll := db .Collection (collectionName (t ))
84+
85+ // Start a change stream to simulate a change listener workload.
86+ cs , err := coll .Watch (context .Background (), mongo.Pipeline {})
8887 require .NoError (t , err )
88+ defer cs .Close (context .Background ())
89+
90+ // Run some Insert and FindOne operations to simulate a writing and
91+ // reading workload. Run 50 iterations to increase the probability
92+ // that a goroutine leak will happen if a problem exists.
93+ for i := 0 ; i < 50 ; i ++ {
94+ _ , err = coll .InsertOne (context .Background (), bson.M {"x" : 123 })
95+ require .NoError (t , err )
8996
90- for i := 0 ; i < 20 ; i ++ {
9197 var res bson.D
9298 err = coll .FindOne (context .Background (), bson.D {}).Decode (& res )
9399 require .NoError (t , err )
94- time .Sleep (50 * time .Millisecond )
95100 }
101+
102+ // Intentionally cause some timeouts. Ignore any errors.
103+ for i := 0 ; i < 50 ; i ++ {
104+ ctx , cancel := context .WithTimeout (context .Background (), 10 * time .Microsecond )
105+ coll .FindOne (ctx , bson.D {}).Err ()
106+ cancel ()
107+ }
108+
109+ // Finish simulating the change listener workload. Use "Next" to
110+ // fetch at least one change stream document batch and decode the
111+ // first document.
112+ cs .Next (context .Background ())
113+ var res bson.D
114+ err = cs .Decode (& res )
115+ require .NoError (t , err )
96116 })
97117 }
98118}
0 commit comments