Skip to content

Commit 52d5a17

Browse files
committed
Add whenExceptionContains, fixes
1 parent 6b53427 commit 52d5a17

File tree

2 files changed

+57
-16
lines changed

2 files changed

+57
-16
lines changed

Diff for: driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedTest.java

+13-6
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,8 @@
8484
import static com.mongodb.client.test.CollectionHelper.getCurrentClusterTime;
8585
import static com.mongodb.client.test.CollectionHelper.killAllSessions;
8686
import static com.mongodb.client.unified.RunOnRequirementsMatcher.runOnRequirementsMet;
87-
import static com.mongodb.client.unified.UnifiedTestModifications.doSkips;
87+
import static com.mongodb.client.unified.UnifiedTestModifications.Modifier;
88+
import static com.mongodb.client.unified.UnifiedTestModifications.applyCustomizations;
8889
import static com.mongodb.client.unified.UnifiedTestModifications.testDef;
8990
import static java.util.Collections.singletonList;
9091
import static java.util.stream.Collectors.toList;
@@ -173,10 +174,10 @@ protected static Collection<Arguments> getTestData(final String directory, final
173174
String testDescription = testDocument.getString("description").getValue();
174175
String fileDescription = fileDocument.getString("description").getValue();
175176
TestDef testDef = testDef(directory, fileDescription, testDescription, isReactive);
176-
doSkips(testDef);
177+
applyCustomizations(testDef);
177178

178-
boolean forceFlaky = testDef.wasAssignedModifier(UnifiedTestModifications.Modifier.FORCE_FLAKY);
179-
boolean retry = forceFlaky || testDef.wasAssignedModifier(UnifiedTestModifications.Modifier.RETRY);
179+
boolean forceFlaky = testDef.wasAssignedModifier(Modifier.FORCE_FLAKY);
180+
boolean retry = forceFlaky || testDef.wasAssignedModifier(Modifier.RETRY);
180181

181182
int attempts = retry ? ATTEMPTS : 1;
182183
if (forceFlaky) {
@@ -241,9 +242,9 @@ public void setUp(
241242
rootContext.getAssertionContext().push(ContextElement.ofTest(definition));
242243
ignoreExtraEvents = false;
243244
testDef = testDef(directoryName, fileDescription, testDescription, isReactive());
244-
UnifiedTestModifications.doSkips(testDef);
245+
applyCustomizations(testDef);
245246

246-
boolean skip = testDef.wasAssignedModifier(UnifiedTestModifications.Modifier.SKIP);
247+
boolean skip = testDef.wasAssignedModifier(Modifier.SKIP);
247248
assumeFalse(skip, "Skipping test");
248249
skips(fileDescription, testDescription);
249250

@@ -369,6 +370,12 @@ public void shouldPassAllOutcomes(
369370
compareLogMessages(rootContext, definition, tweaks);
370371
}
371372
} catch (AssertionFailedError e) {
373+
assertTrue(testDef.wasAssignedModifier(Modifier.RETRY));
374+
if (!testDef.matchesError(e)) {
375+
// if the error is not matched, test definitions were not intended to apply; throw it
376+
throw e;
377+
}
378+
372379
completed.remove(testName);
373380
boolean lastAttempt = attemptNumber == Math.abs(totalAttempts);
374381
if (forceFlaky || lastAttempt) {

Diff for: driver-sync/src/test/functional/com/mongodb/client/unified/UnifiedTestModifications.java

+44-10
Original file line numberDiff line numberDiff line change
@@ -17,34 +17,41 @@
1717
package com.mongodb.client.unified;
1818

1919
import com.mongodb.assertions.Assertions;
20+
import org.opentest4j.AssertionFailedError;
2021

2122
import java.util.ArrayList;
2223
import java.util.Arrays;
2324
import java.util.List;
25+
import java.util.function.Function;
2426
import java.util.function.Supplier;
2527

2628
import static com.mongodb.ClusterFixture.isDataLakeTest;
2729
import static com.mongodb.ClusterFixture.isDiscoverableReplicaSet;
2830
import static com.mongodb.ClusterFixture.isServerlessTest;
2931
import static com.mongodb.ClusterFixture.isSharded;
3032
import static com.mongodb.ClusterFixture.serverVersionLessThan;
31-
import static com.mongodb.client.unified.UnifiedTestModifications.Modifier.FORCE_FLAKY;
3233
import static com.mongodb.assertions.Assertions.assertNotNull;
3334
import static com.mongodb.client.unified.UnifiedTestModifications.Modifier.IGNORE_EXTRA_EVENTS;
35+
import static com.mongodb.client.unified.UnifiedTestModifications.Modifier.RETRY;
3436
import static com.mongodb.client.unified.UnifiedTestModifications.Modifier.SKIP;
3537
import static com.mongodb.client.unified.UnifiedTestModifications.Modifier.SLEEP_AFTER_CURSOR_CLOSE;
3638
import static com.mongodb.client.unified.UnifiedTestModifications.Modifier.SLEEP_AFTER_CURSOR_OPEN;
3739
import static com.mongodb.client.unified.UnifiedTestModifications.Modifier.WAIT_FOR_BATCH_CURSOR_CREATION;
3840

3941
public final class UnifiedTestModifications {
40-
public static void doSkips(final TestDef def) {
42+
public static void applyCustomizations(final TestDef def) {
4143

4244
// 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")
4855
.test("client-side-encryption", "namedKMS-rewrapManyDataKey", "rewrap to kmip:name1");
4956

5057
// atlas-data-lake
@@ -288,6 +295,7 @@ public static final class TestDef {
288295
private final boolean reactive;
289296

290297
private final List<Modifier> modifiers = new ArrayList<>();
298+
private Function<AssertionFailedError, Boolean> matchesError;
291299

292300
private TestDef(final String dir, final String file, final String test, final boolean reactive) {
293301
this.dir = dir;
@@ -332,7 +340,8 @@ public TestApplicator skipNoncompliant(final String reason) {
332340
* @param reason reason for skipping the test
333341
*/
334342
public TestApplicator skipNoncompliantReactive(final String reason) {
335-
return new TestApplicator(this, reason, SKIP);
343+
return new TestApplicator(this, reason, SKIP)
344+
.when(() -> isReactive());
336345
}
337346

338347
/**
@@ -350,6 +359,14 @@ public TestApplicator skipUnknownReason(final String reason) {
350359
return new TestApplicator(this, reason, SKIP);
351360
}
352361

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+
353370
public TestApplicator modify(final Modifier... modifiers) {
354371
return new TestApplicator(this, null, modifiers);
355372
}
@@ -361,24 +378,33 @@ public boolean isReactive() {
361378
public boolean wasAssignedModifier(final Modifier modifier) {
362379
return this.modifiers.contains(modifier);
363380
}
381+
382+
public boolean matchesError(final AssertionFailedError e) {
383+
if (matchesError != null) {
384+
return matchesError.apply(e);
385+
}
386+
return false;
387+
}
364388
}
365389

366390
/**
367391
* Applies settings to the underlying test definition. Chainable.
368392
*/
369393
public static final class TestApplicator {
370394
private final TestDef testDef;
371-
private final List<Modifier> modifiersToApply;
372395
private Supplier<Boolean> precondition;
373396
private boolean matchWasPerformed = false;
374397

398+
private final List<Modifier> modifiersToApply;
399+
private Function<AssertionFailedError, Boolean> matchesError;
400+
375401
private TestApplicator(
376402
final TestDef testDef,
377403
final String reason,
378404
final Modifier... modifiersToApply) {
379405
this.testDef = testDef;
380406
this.modifiersToApply = Arrays.asList(modifiersToApply);
381-
if (this.modifiersToApply.contains(SKIP)) {
407+
if (this.modifiersToApply.contains(SKIP) || this.modifiersToApply.contains(RETRY)) {
382408
assertNotNull(reason);
383409
}
384410
}
@@ -390,6 +416,7 @@ private TestApplicator onMatch(final boolean match) {
390416
}
391417
if (match) {
392418
this.testDef.modifiers.addAll(this.modifiersToApply);
419+
this.testDef.matchesError = this.matchesError;
393420
}
394421
return this;
395422
}
@@ -481,6 +508,13 @@ public TestApplicator when(final Supplier<Boolean> precondition) {
481508
this.precondition = precondition;
482509
return this;
483510
}
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+
}
484518
}
485519

486520
public enum Modifier {

0 commit comments

Comments
 (0)