37
37
import com .mongodb .connection .SocketSettings ;
38
38
import com .mongodb .connection .SslSettings ;
39
39
import com .mongodb .event .CommandEvent ;
40
+ import com .mongodb .event .CommandStartedEvent ;
40
41
import com .mongodb .internal .connection .TestCommandListener ;
41
42
import com .mongodb .lang .Nullable ;
42
43
import org .bson .BsonArray ;
52
53
import org .junit .Test ;
53
54
import org .junit .runner .RunWith ;
54
55
import org .junit .runners .Parameterized ;
55
- import util .JsonPoweredTestHelper ;
56
56
57
- import java .io .File ;
58
- import java .io .IOException ;
59
- import java .net .URISyntaxException ;
60
57
import java .util .ArrayList ;
61
- import java .util .Collection ;
62
58
import java .util .HashMap ;
63
59
import java .util .List ;
64
60
import java .util .Map ;
65
61
import java .util .concurrent .TimeUnit ;
66
62
67
63
import static com .mongodb .ClusterFixture .getMultiMongosConnectionString ;
68
- import static com .mongodb .JsonTestServerVersionChecker .skipTest ;
69
64
import static com .mongodb .async .client .Fixture .getConnectionString ;
70
65
import static com .mongodb .async .client .Fixture .getDefaultDatabaseName ;
71
66
import static com .mongodb .async .client .Fixture .isSharded ;
75
70
import static java .util .concurrent .TimeUnit .MILLISECONDS ;
76
71
import static org .junit .Assert .assertEquals ;
77
72
import static org .junit .Assert .assertFalse ;
73
+ import static org .junit .Assert .assertNotEquals ;
78
74
import static org .junit .Assert .assertNotNull ;
79
75
import static org .junit .Assert .assertNull ;
80
76
import static org .junit .Assert .assertTrue ;
84
80
85
81
// See https://github.com/mongodb/specifications/tree/master/source/transactions/tests
86
82
@ RunWith (Parameterized .class )
87
- public class TransactionsTest {
83
+ public abstract class AbstractUnifiedTest {
88
84
89
85
private final String filename ;
90
86
private final String description ;
@@ -104,8 +100,8 @@ public class TransactionsTest {
104
100
105
101
private static final long MIN_HEARTBEAT_FREQUENCY_MS = 50L ;
106
102
107
- public TransactionsTest (final String filename , final String description , final BsonArray data , final BsonDocument definition ,
108
- final boolean skipTest ) {
103
+ public AbstractUnifiedTest (final String filename , final String description , final BsonArray data , final BsonDocument definition ,
104
+ final boolean skipTest ) {
109
105
this .filename = filename ;
110
106
this .description = description ;
111
107
this .databaseName = getDefaultDatabaseName ();
@@ -353,7 +349,7 @@ private void executeOperations(final BsonArray operations, final boolean throwEx
353
349
BsonValue expectedResult = operation .get ("result" );
354
350
String receiver = operation .getString ("object" ).getValue ();
355
351
final ClientSession clientSession = receiver .startsWith ("session" ) ? sessionsMap .get (receiver )
356
- : (operation .getDocument ("arguments" ).containsKey ("session" )
352
+ : (operation .getDocument ("arguments" , new BsonDocument () ).containsKey ("session" )
357
353
? sessionsMap .get (operation .getDocument ("arguments" ).getString ("session" ).getValue ()) : null );
358
354
try {
359
355
if (operationName .equals ("startTransaction" )) {
@@ -401,13 +397,31 @@ public void execute() {
401
397
} else {
402
398
assertFalse (session .hasActiveTransaction ());
403
399
}
400
+ } else if (operationName .equals ("endSession" )) {
401
+ clientSession .close ();
404
402
} else if (operation .getBoolean ("error" , BsonBoolean .FALSE ).getValue ()) {
405
403
try {
406
404
helper .getOperationResults (operation , clientSession );
407
405
fail ("Error expected but none thrown" );
408
406
} catch (Exception e ) {
409
407
// Expected failure ignore
410
408
}
409
+ } else if (operationName .equals ("assertDifferentLsidOnLastTwoCommands" )) {
410
+ List <CommandEvent > events = lastTwoCommandEvents ();
411
+ assertNotEquals (((CommandStartedEvent ) events .get (0 )).getCommand ().getDocument ("lsid" ),
412
+ ((CommandStartedEvent ) events .get (1 )).getCommand ().getDocument ("lsid" ));
413
+ } else if (operationName .equals ("assertSameLsidOnLastTwoCommands" )) {
414
+ List <CommandEvent > events = lastTwoCommandEvents ();
415
+ assertEquals (((CommandStartedEvent ) events .get (0 )).getCommand ().getDocument ("lsid" ),
416
+ ((CommandStartedEvent ) events .get (1 )).getCommand ().getDocument ("lsid" ));
417
+ } else if (operationName .equals ("assertSessionDirty" )) {
418
+ assertNotNull (clientSession );
419
+ assertNotNull (clientSession .getServerSession ());
420
+ assertTrue (clientSession .getServerSession ().isMarkedDirty ());
421
+ } else if (operationName .equals ("assertSessionNotDirty" )) {
422
+ assertNotNull (clientSession );
423
+ assertNotNull (clientSession .getServerSession ());
424
+ assertFalse (clientSession .getServerSession ().isMarkedDirty ());
411
425
} else {
412
426
BsonDocument actualOutcome = helper .getOperationResults (operation , clientSession );
413
427
if (expectedResult != null ) {
@@ -426,46 +440,7 @@ public void execute() {
426
440
assertFalse (String .format ("Expected error code '%s' but none thrown for operation %s" ,
427
441
getErrorCodeNameField (expectedResult ), operationName ), hasErrorCodeNameField (expectedResult ));
428
442
} catch (RuntimeException e ) {
429
- boolean passedAssertion = false ;
430
- if (hasErrorLabelsContainField (expectedResult )) {
431
- if (e instanceof MongoException ) {
432
- MongoException mongoException = (MongoException ) e ;
433
- for (String curErrorLabel : getErrorLabelsContainField (expectedResult )) {
434
- assertTrue (String .format ("Expected error label '%s but found labels '%s' for operation %s" ,
435
- curErrorLabel , mongoException .getErrorLabels (), operationName ),
436
- mongoException .hasErrorLabel (curErrorLabel ));
437
- }
438
- passedAssertion = true ;
439
- }
440
- }
441
- if (hasErrorLabelsOmitField (expectedResult )) {
442
- if (e instanceof MongoException ) {
443
- MongoException mongoException = (MongoException ) e ;
444
- for (String curErrorLabel : getErrorLabelsOmitField (expectedResult )) {
445
- assertFalse (String .format ("Expected error label '%s omitted but found labels '%s' for operation %s" ,
446
- curErrorLabel , mongoException .getErrorLabels (), operationName ),
447
- mongoException .hasErrorLabel (curErrorLabel ));
448
- }
449
- passedAssertion = true ;
450
- }
451
- }
452
- if (hasErrorContainsField (expectedResult )) {
453
- String expectedError = getErrorContainsField (expectedResult );
454
- assertTrue (String .format ("Expected '%s' but got '%s' for operation %s" , expectedError , e .getMessage (),
455
- operationName ), e .getMessage ().toLowerCase ().contains (expectedError .toLowerCase ()));
456
- passedAssertion = true ;
457
- }
458
- if (hasErrorCodeNameField (expectedResult )) {
459
- String expectedErrorCodeName = getErrorCodeNameField (expectedResult );
460
- if (e instanceof MongoCommandException ) {
461
- assertEquals (expectedErrorCodeName , ((MongoCommandException ) e ).getErrorCodeName ());
462
- passedAssertion = true ;
463
- } else if (e instanceof MongoWriteConcernException ) {
464
- assertEquals (expectedErrorCodeName , ((MongoWriteConcernException ) e ).getWriteConcernError ().getCodeName ());
465
- passedAssertion = true ;
466
- }
467
- }
468
- if (!passedAssertion || throwExceptions ) {
443
+ if (!assertExceptionState (e , expectedResult , operationName ) || throwExceptions ) {
469
444
throw e ;
470
445
}
471
446
}
@@ -477,6 +452,55 @@ public void execute() {
477
452
}
478
453
}
479
454
455
+ private boolean assertExceptionState (final RuntimeException e , final BsonValue expectedResult , final String operationName ) {
456
+ boolean passedAssertion = false ;
457
+ if (hasErrorLabelsContainField (expectedResult )) {
458
+ if (e instanceof MongoException ) {
459
+ MongoException mongoException = (MongoException ) e ;
460
+ for (String curErrorLabel : getErrorLabelsContainField (expectedResult )) {
461
+ assertTrue (String .format ("Expected error label '%s but found labels '%s' for operation %s" ,
462
+ curErrorLabel , mongoException .getErrorLabels (), operationName ),
463
+ mongoException .hasErrorLabel (curErrorLabel ));
464
+ }
465
+ passedAssertion = true ;
466
+ }
467
+ }
468
+ if (hasErrorLabelsOmitField (expectedResult )) {
469
+ if (e instanceof MongoException ) {
470
+ MongoException mongoException = (MongoException ) e ;
471
+ for (String curErrorLabel : getErrorLabelsOmitField (expectedResult )) {
472
+ assertFalse (String .format ("Expected error label '%s omitted but found labels '%s' for operation %s" ,
473
+ curErrorLabel , mongoException .getErrorLabels (), operationName ),
474
+ mongoException .hasErrorLabel (curErrorLabel ));
475
+ }
476
+ passedAssertion = true ;
477
+ }
478
+ }
479
+ if (hasErrorContainsField (expectedResult )) {
480
+ String expectedError = getErrorContainsField (expectedResult );
481
+ assertTrue (String .format ("Expected '%s' but got '%s' for operation %s" , expectedError , e .getMessage (),
482
+ operationName ), e .getMessage ().toLowerCase ().contains (expectedError .toLowerCase ()));
483
+ passedAssertion = true ;
484
+ }
485
+ if (hasErrorCodeNameField (expectedResult )) {
486
+ String expectedErrorCodeName = getErrorCodeNameField (expectedResult );
487
+ if (e instanceof MongoCommandException ) {
488
+ assertEquals (expectedErrorCodeName , ((MongoCommandException ) e ).getErrorCodeName ());
489
+ passedAssertion = true ;
490
+ } else if (e instanceof MongoWriteConcernException ) {
491
+ assertEquals (expectedErrorCodeName , ((MongoWriteConcernException ) e ).getWriteConcernError ().getCodeName ());
492
+ passedAssertion = true ;
493
+ }
494
+ }
495
+ return passedAssertion ;
496
+ }
497
+
498
+ private List <CommandEvent > lastTwoCommandEvents () {
499
+ List <CommandEvent > events = commandListener .getCommandStartedEvents ();
500
+ assertTrue (events .size () >= 2 );
501
+ return events .subList (events .size () - 2 , events .size ());
502
+ }
503
+
480
504
private TransactionOptions createTransactionOptions (final BsonDocument options ) {
481
505
TransactionOptions .Builder builder = TransactionOptions .builder ();
482
506
if (options .containsKey ("writeConcern" )) {
@@ -554,19 +578,6 @@ private ClientSession nonNullClientSession(@Nullable final ClientSession clientS
554
578
return clientSession ;
555
579
}
556
580
557
- @ Parameterized .Parameters (name = "{0}: {1}" )
558
- public static Collection <Object []> data () throws URISyntaxException , IOException {
559
- List <Object []> data = new ArrayList <Object []>();
560
- for (File file : JsonPoweredTestHelper .getTestFiles ("/transactions" )) {
561
- BsonDocument testDocument = JsonPoweredTestHelper .getTestDocument (file );
562
- for (BsonValue test : testDocument .getArray ("tests" )) {
563
- data .add (new Object []{file .getName (), test .asDocument ().getString ("description" ).getValue (),
564
- testDocument .getArray ("data" ), test .asDocument (), skipTest (testDocument , test .asDocument ())});
565
- }
566
- }
567
- return data ;
568
- }
569
-
570
581
private class TargetedFailPoint {
571
582
private final BsonDocument failPointDocument ;
572
583
private final MongoDatabase adminDB ;
0 commit comments