17
17
package com .mongodb .client .unified ;
18
18
19
19
import com .mongodb .assertions .Assertions ;
20
+ import org .opentest4j .AssertionFailedError ;
20
21
21
22
import java .util .ArrayList ;
22
23
import java .util .Arrays ;
23
24
import java .util .List ;
25
+ import java .util .function .Function ;
24
26
import java .util .function .Supplier ;
25
27
26
28
import static com .mongodb .ClusterFixture .isDataLakeTest ;
27
29
import static com .mongodb .ClusterFixture .isDiscoverableReplicaSet ;
28
30
import static com .mongodb .ClusterFixture .isServerlessTest ;
29
31
import static com .mongodb .ClusterFixture .isSharded ;
30
32
import static com .mongodb .ClusterFixture .serverVersionLessThan ;
31
- import static com .mongodb .client .unified .UnifiedTestModifications .Modifier .FORCE_FLAKY ;
32
33
import static com .mongodb .assertions .Assertions .assertNotNull ;
33
34
import static com .mongodb .client .unified .UnifiedTestModifications .Modifier .IGNORE_EXTRA_EVENTS ;
35
+ import static com .mongodb .client .unified .UnifiedTestModifications .Modifier .RETRY ;
34
36
import static com .mongodb .client .unified .UnifiedTestModifications .Modifier .SKIP ;
35
37
import static com .mongodb .client .unified .UnifiedTestModifications .Modifier .SLEEP_AFTER_CURSOR_CLOSE ;
36
38
import static com .mongodb .client .unified .UnifiedTestModifications .Modifier .SLEEP_AFTER_CURSOR_OPEN ;
37
39
import static com .mongodb .client .unified .UnifiedTestModifications .Modifier .WAIT_FOR_BATCH_CURSOR_CREATION ;
38
40
39
41
public final class UnifiedTestModifications {
40
- public static void doSkips (final TestDef def ) {
42
+ public static void applyCustomizations (final TestDef def ) {
41
43
42
44
// TODO reasons for retry
43
- def .modify (FORCE_FLAKY )
44
- // Exception in encryption library: ChangeCipherSpec message sequence violation
45
- .test ("client-side-encryption" , "namedKMS-createDataKey" , "create datakey with named KMIP KMS provider" )
46
- // Number of checked out connections must match expected
47
- .test ("load-balancers" , "cursors are correctly pinned to connections for load-balanced clusters" , "pinned connections are returned after a network error during a killCursors request" )
45
+ // Exception in encryption library: ChangeCipherSpec message sequence violation
46
+ def .retry ("TODO reason" )
47
+ .whenExceptionContains ("ChangeCipherSpec message sequence violation" )
48
+ .test ("client-side-encryption" , "namedKMS-createDataKey" , "create datakey with named KMIP KMS provider" );
49
+
50
+ def .retry ("TODO reason" )
51
+ .whenExceptionContains ("Number of checked out connections must match expected" )
52
+ .test ("load-balancers" , "cursors are correctly pinned to connections for load-balanced clusters" , "pinned connections are returned after a network error during a killCursors request" );
53
+
54
+ def .retry ("TODO reason" )
48
55
.test ("client-side-encryption" , "namedKMS-rewrapManyDataKey" , "rewrap to kmip:name1" );
49
56
50
57
// atlas-data-lake
@@ -288,6 +295,7 @@ public static final class TestDef {
288
295
private final boolean reactive ;
289
296
290
297
private final List <Modifier > modifiers = new ArrayList <>();
298
+ private Function <AssertionFailedError , Boolean > matchesError ;
291
299
292
300
private TestDef (final String dir , final String file , final String test , final boolean reactive ) {
293
301
this .dir = dir ;
@@ -332,7 +340,8 @@ public TestApplicator skipNoncompliant(final String reason) {
332
340
* @param reason reason for skipping the test
333
341
*/
334
342
public TestApplicator skipNoncompliantReactive (final String reason ) {
335
- return new TestApplicator (this , reason , SKIP );
343
+ return new TestApplicator (this , reason , SKIP )
344
+ .when (() -> isReactive ());
336
345
}
337
346
338
347
/**
@@ -350,6 +359,14 @@ public TestApplicator skipUnknownReason(final String reason) {
350
359
return new TestApplicator (this , reason , SKIP );
351
360
}
352
361
362
+
363
+ /**
364
+ * The test will be retried, for the reason provided
365
+ */
366
+ public TestApplicator retry (final String reason ) {
367
+ return new TestApplicator (this , reason , RETRY );
368
+ }
369
+
353
370
public TestApplicator modify (final Modifier ... modifiers ) {
354
371
return new TestApplicator (this , null , modifiers );
355
372
}
@@ -361,24 +378,33 @@ public boolean isReactive() {
361
378
public boolean wasAssignedModifier (final Modifier modifier ) {
362
379
return this .modifiers .contains (modifier );
363
380
}
381
+
382
+ public boolean matchesError (final AssertionFailedError e ) {
383
+ if (matchesError != null ) {
384
+ return matchesError .apply (e );
385
+ }
386
+ return false ;
387
+ }
364
388
}
365
389
366
390
/**
367
391
* Applies settings to the underlying test definition. Chainable.
368
392
*/
369
393
public static final class TestApplicator {
370
394
private final TestDef testDef ;
371
- private final List <Modifier > modifiersToApply ;
372
395
private Supplier <Boolean > precondition ;
373
396
private boolean matchWasPerformed = false ;
374
397
398
+ private final List <Modifier > modifiersToApply ;
399
+ private Function <AssertionFailedError , Boolean > matchesError ;
400
+
375
401
private TestApplicator (
376
402
final TestDef testDef ,
377
403
final String reason ,
378
404
final Modifier ... modifiersToApply ) {
379
405
this .testDef = testDef ;
380
406
this .modifiersToApply = Arrays .asList (modifiersToApply );
381
- if (this .modifiersToApply .contains (SKIP )) {
407
+ if (this .modifiersToApply .contains (SKIP ) || this . modifiersToApply . contains ( RETRY ) ) {
382
408
assertNotNull (reason );
383
409
}
384
410
}
@@ -390,6 +416,7 @@ private TestApplicator onMatch(final boolean match) {
390
416
}
391
417
if (match ) {
392
418
this .testDef .modifiers .addAll (this .modifiersToApply );
419
+ this .testDef .matchesError = this .matchesError ;
393
420
}
394
421
return this ;
395
422
}
@@ -481,6 +508,13 @@ public TestApplicator when(final Supplier<Boolean> precondition) {
481
508
this .precondition = precondition ;
482
509
return this ;
483
510
}
511
+
512
+ public TestApplicator whenExceptionContains (final String fragment ) {
513
+ this .matchesError = (final AssertionFailedError e ) -> {
514
+ return e .getCause ().getMessage ().contains (fragment );
515
+ };
516
+ return this ;
517
+ }
484
518
}
485
519
486
520
public enum Modifier {
0 commit comments