7
7
package integration
8
8
9
9
import (
10
+ "errors"
11
+ "fmt"
10
12
"io/ioutil"
11
13
"path"
12
14
"reflect"
@@ -247,8 +249,9 @@ func runSpecTestCase(mt *mtest.T, test *testCase, testFile testFile) {
247
249
248
250
// run operations
249
251
mt .ClearEvents ()
250
- for _ , op := range test .Operations {
251
- runOperation (mt , test , op , sess0 , sess1 )
252
+ for idx , op := range test .Operations {
253
+ err := runOperation (mt , test , op , sess0 , sess1 )
254
+ assert .Nil (mt , err , "error running operation %q at index %d: %v" , op .Name , idx , err )
252
255
}
253
256
254
257
// Needs to be done here (in spite of defer) because some tests
@@ -285,7 +288,7 @@ func createBucket(mt *mtest.T, testFile testFile, testCase *testCase) {
285
288
assert .Nil (mt , err , "NewBucket error: %v" , err )
286
289
}
287
290
288
- func runOperation (mt * mtest.T , testCase * testCase , op * operation , sess0 , sess1 mongo.Session ) {
291
+ func runOperation (mt * mtest.T , testCase * testCase , op * operation , sess0 , sess1 mongo.Session ) error {
289
292
if op .Name == "count" {
290
293
mt .Skip ("count has been deprecated" )
291
294
}
@@ -299,13 +302,12 @@ func runOperation(mt *mtest.T, testCase *testCase, op *operation, sess0, sess1 m
299
302
case "session1" :
300
303
sess = sess1
301
304
default :
302
- mt . Fatalf ("unrecognized session identifier: %v" , sessStr )
305
+ return fmt . Errorf ("unrecognized session identifier: %v" , sessStr )
303
306
}
304
307
}
305
308
306
309
if op .Object == "testRunner" {
307
- executeTestRunnerOperation (mt , op , sess )
308
- return
310
+ return executeTestRunnerOperation (mt , op , sess )
309
311
}
310
312
311
313
mt .CloneDatabase (createDatabaseOptions (mt , op .DatabaseOptions ))
@@ -328,7 +330,7 @@ func runOperation(mt *mtest.T, testCase *testCase, op *operation, sess0, sess1 m
328
330
case "client" :
329
331
err = executeClientOperation (mt , op , sess )
330
332
default :
331
- mt . Fatalf ("unrecognized operation object: %v" , op .Object )
333
+ return fmt . Errorf ("unrecognized operation object: %v" , op .Object )
332
334
}
333
335
334
336
op .opError = errorFromResult (mt , op .Result )
@@ -338,7 +340,7 @@ func runOperation(mt *mtest.T, testCase *testCase, op *operation, sess0, sess1 m
338
340
if op .Error && op .Result == nil {
339
341
op .opError = & operationError {}
340
342
}
341
- verifyError (mt , op .opError , err )
343
+ return verifyError (op .opError , err )
342
344
}
343
345
344
346
func executeGridFSOperation (mt * mtest.T , bucket * gridfs.Bucket , op * operation ) error {
@@ -358,107 +360,146 @@ func executeGridFSOperation(mt *mtest.T, bucket *gridfs.Bucket, op *operation) e
358
360
return nil
359
361
}
360
362
361
- func executeTestRunnerOperation (mt * mtest.T , op * operation , sess mongo.Session ) {
363
+ func executeTestRunnerOperation (mt * mtest.T , op * operation , sess mongo.Session ) error {
362
364
var clientSession * session.Client
363
365
if sess != nil {
364
366
xsess , ok := sess .(mongo.XSession )
365
- assert .True (mt , ok , "expected %T to implement mongo.XSession" , sess )
367
+ if ! ok {
368
+ return fmt .Errorf ("expected session type %T to implement mongo.XSession" , sess )
369
+ }
366
370
clientSession = xsess .ClientSession ()
367
371
}
368
372
369
373
switch op .Name {
370
374
case "targetedFailPoint" :
371
- fpDoc , err := op .Arguments .LookupErr ("failPoint" )
372
- assert .Nil (mt , err , "failPoint not found in arguments" )
375
+ fpDoc := op .Arguments .Lookup ("failPoint" )
373
376
374
377
var fp mtest.FailPoint
375
- err = bson .Unmarshal (fpDoc .Document (), & fp )
376
- assert .Nil (mt , err , "error creating fail point: %v" , err )
378
+ if err := bson .Unmarshal (fpDoc .Document (), & fp ); err != nil {
379
+ return fmt .Errorf ("Unmarshal error: %v" , err )
380
+ }
377
381
378
382
targetHost := clientSession .PinnedServer .Addr .String ()
379
383
opts := options .Client ().ApplyURI (mt .ConnString ()).SetHosts ([]string {targetHost })
380
384
client , err := mongo .Connect (mtest .Background , opts )
381
- assert .Nil (mt , err , "error creating targeted client: %v" , err )
385
+ if err != nil {
386
+ return fmt .Errorf ("Connect error for targeted client: %v" , err )
387
+ }
382
388
defer func () { _ = client .Disconnect (mtest .Background ) }()
383
389
384
- err = client .Database ("admin" ).RunCommand (mtest .Background , fp ).Err ()
385
- assert .Nil (mt , err , "error setting targeted fail point: %v" , err )
390
+ if err = client .Database ("admin" ).RunCommand (mtest .Background , fp ).Err (); err != nil {
391
+ return fmt .Errorf ("error setting targeted fail point: %v" , err )
392
+ }
386
393
mt .TrackFailPoint (fp .ConfigureFailPoint )
387
394
case "assertSessionPinned" :
388
- assert .NotNil (mt , clientSession .PinnedServer , "expected pinned server but got nil" )
395
+ if clientSession .PinnedServer == nil {
396
+ return errors .New ("expected pinned server, got nil" )
397
+ }
389
398
case "assertSessionUnpinned" :
390
- assert .Nil (mt , clientSession .PinnedServer ,
391
- "expected pinned server to be nil but got %v" , clientSession .PinnedServer )
399
+ // We don't use a combined helper for assertSessionPinned and assertSessionUnpinned because the unpinned
400
+ // case provides the pinned server address in the error msg for debugging.
401
+ if clientSession .PinnedServer != nil {
402
+ return fmt .Errorf ("expected pinned server to be nil but got %q" , clientSession .PinnedServer .Addr )
403
+ }
392
404
case "assertSessionDirty" :
393
- assert .NotNil (mt , clientSession .Server , "expected server session but got nil" )
394
- assert .True (mt , clientSession .Server .Dirty , "expected server session to be marked dirty but was not" )
405
+ return verifyDirtySessionState (clientSession , true )
395
406
case "assertSessionNotDirty" :
396
- assert .NotNil (mt , clientSession .Server , "expected server session but got nil" )
397
- assert .False (mt , clientSession .Server .Dirty , "expected server session not to be marked dirty but was" )
407
+ return verifyDirtySessionState (clientSession , false )
398
408
case "assertSameLsidOnLastTwoCommands" :
399
409
first , second := lastTwoIDs (mt )
400
- assert .Equal (mt , first , second , "expected last two lsids to be equal but got %v and %v" , first , second )
410
+ if ! first .Equal (second ) {
411
+ return fmt .Errorf ("expected last two lsids to be equal but got %v and %v" , first , second )
412
+ }
401
413
case "assertDifferentLsidOnLastTwoCommands" :
402
414
first , second := lastTwoIDs (mt )
403
- assert .NotEqual (mt , first , second , "expected last two lsids to be not equal but got %v and %v" , first , second )
415
+ if first .Equal (second ) {
416
+ return fmt .Errorf ("expected last two lsids to be not equal but both were %v" , first )
417
+ }
404
418
case "assertCollectionExists" :
405
- assertCollectionState (mt , op , true )
419
+ return verifyCollectionState (mt , op , true )
406
420
case "assertCollectionNotExists" :
407
- assertCollectionState (mt , op , false )
421
+ return verifyCollectionState (mt , op , false )
408
422
case "assertIndexExists" :
409
- assertIndexState (mt , op , true )
423
+ return verifyIndexState (mt , op , true )
410
424
case "assertIndexNotExists" :
411
- assertIndexState (mt , op , false )
425
+ return verifyIndexState (mt , op , false )
412
426
default :
413
427
mt .Fatalf ("unrecognized testRunner operation %v" , op .Name )
414
428
}
429
+
430
+ return nil
431
+ }
432
+
433
+ func verifyDirtySessionState (clientSession * session.Client , expectedDirty bool ) error {
434
+ if clientSession .Server == nil {
435
+ return errors .New ("expected valid server session, got nil" )
436
+ }
437
+ if markedDirty := clientSession .Server .Dirty ; markedDirty != expectedDirty {
438
+ return fmt .Errorf ("expected server session to be marked dirty: %v, got %v" , expectedDirty , markedDirty )
439
+ }
440
+ return nil
415
441
}
416
442
417
- func assertIndexState (mt * mtest.T , op * operation , shouldExist bool ) {
443
+ func verifyIndexState (mt * mtest.T , op * operation , shouldExist bool ) error {
418
444
db := op .Arguments .Lookup ("database" ).StringValue ()
419
445
coll := op .Arguments .Lookup ("collection" ).StringValue ()
420
446
index := op .Arguments .Lookup ("index" ).StringValue ()
421
- exists := indexExists (mt , db , coll , index )
422
447
423
- assert .Equal (mt , shouldExist , exists ,
424
- "index state mismatch for index %s in namespace %s.%s; should exist: %v, exists: %v" , index , db , coll ,
425
- shouldExist , exists )
448
+ exists , err := indexExists (mt , db , coll , index )
449
+ if err != nil {
450
+ return err
451
+ }
452
+ if exists != shouldExist {
453
+ return fmt .Errorf ("index state mismatch for index %s in namespace %s.%s; should exist: %v, exists: %v" ,
454
+ index , db , coll , shouldExist , exists )
455
+ }
456
+ return nil
426
457
}
427
458
428
- func indexExists (mt * mtest.T , dbName , collName , indexName string ) bool {
459
+ func indexExists (mt * mtest.T , dbName , collName , indexName string ) ( bool , error ) {
429
460
// Use global client because listIndexes cannot be executed inside a transaction.
430
461
iv := mt .GlobalClient ().Database (dbName ).Collection (collName ).Indexes ()
431
462
cursor , err := iv .List (mtest .Background )
432
- assert .Nil (mt , err , "IndexView.List error: %v" , err )
463
+ if err != nil {
464
+ return false , fmt .Errorf ("IndexView.List error: %v" , err )
465
+ }
433
466
defer cursor .Close (mtest .Background )
434
467
435
468
for cursor .Next (mtest .Background ) {
436
469
if cursor .Current .Lookup ("name" ).StringValue () == indexName {
437
- return true
470
+ return true , nil
438
471
}
439
472
}
440
- assert .Nil (mt , cursor .Err (), "unexpected cursor iteration error: %v" , cursor .Err ())
441
- return false
473
+ return false , cursor .Err ()
442
474
}
443
475
444
- func assertCollectionState (mt * mtest.T , op * operation , shouldExist bool ) {
476
+ func verifyCollectionState (mt * mtest.T , op * operation , shouldExist bool ) error {
445
477
db := op .Arguments .Lookup ("database" ).StringValue ()
446
478
coll := op .Arguments .Lookup ("collection" ).StringValue ()
447
- exists := collectionExists (mt , db , coll )
448
- assert .Equal (mt , shouldExist , exists , "collection state mismatch for %s:%s; should exist: %v, exists: %v" ,
449
- db , coll , shouldExist , coll )
479
+
480
+ exists , err := collectionExists (mt , db , coll )
481
+ if err != nil {
482
+ return err
483
+ }
484
+ if exists != shouldExist {
485
+ return fmt .Errorf ("collection state mismatch for %s.%s; should exist %v, exists: %v" , db , coll , shouldExist ,
486
+ exists )
487
+ }
488
+ return nil
450
489
}
451
490
452
- func collectionExists (mt * mtest.T , dbName , collName string ) bool {
491
+ func collectionExists (mt * mtest.T , dbName , collName string ) ( bool , error ) {
453
492
filter := bson.D {
454
493
{"name" , collName },
455
494
}
456
495
457
496
// Use global client because listCollections cannot be executed inside a transaction.
458
497
collections , err := mt .GlobalClient ().Database (dbName ).ListCollectionNames (mtest .Background , filter )
459
- assert .Nil (mt , err , "ListCollectionNames error: %v" , err )
498
+ if err != nil {
499
+ return false , fmt .Errorf ("ListCollectionNames error: %v" , err )
500
+ }
460
501
461
- return len (collections ) > 0
502
+ return len (collections ) > 0 , nil
462
503
}
463
504
464
505
func lastTwoIDs (mt * mtest.T ) (bson.RawValue , bson.RawValue ) {
0 commit comments