Skip to content

Commit 18f9a56

Browse files
committed
Fix for flaky ShutdownDuringValidationIT
1 parent 0335c17 commit 18f9a56

File tree

2 files changed

+58
-22
lines changed

2 files changed

+58
-22
lines changed

AGENTS.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -593,16 +593,19 @@ Do **not** modify existing headers’ years.
593593
* `mvn -o verify` (long; only when appropriate)
594594
* Slow tests (entire repo):
595595
596-
* `mvn -o verify -PslowTestsOnly,-skipSlowTests,-formatting -Dmaven.javadoc.skip -Djapicmp.skip -Denforcer.skip -Danimal.sniffer.skip | tail -500`
596+
* `mvn -o verify -PslowTestsOnly,-skipSlowTests | tail -500`
597597
* Slow tests (by module):
598598
599-
* `mvn -o -pl <module> verify -PslowTestsOnly,-skipSlowTests,-formatting -Dmaven.javadoc.skip -Djapicmp.skip -Denforcer.skip -Danimal.sniffer.skip | tail -500`
599+
* `mvn -o -pl <module> verify -PslowTestsOnly,-skipSlowTests | tail -500`
600+
* Slow tests (specific test):
601+
602+
* `mvn -o -pl core/sail/shacl -PslowTestsOnly,-skipSlowTests -Dtest=ClassName#method verify | tail -500`
600603
* Integration tests (entire repo):
601604
602-
* `mvn -o verify -PskipUnitTests,-formatting -Dmaven.javadoc.skip -Denforcer.skip -Danimal.sniffer.skip | tail -500`
605+
* `mvn -o verify -PskipUnitTests | tail -500`
603606
* Integration tests (by module):
604607
605-
* `mvn -o -pl <module> verify -PskipUnitTests,-formatting -Dmaven.javadoc.skip -Denforcer.skip -Danimal.sniffer.skip | tail -500`
608+
* `mvn -o -pl <module> verify -PskipUnitTests | tail -500`
606609
* Useful flags:
607610
608611
* `-Dtest=ClassName`

core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/ShutdownDuringValidationIT.java

Lines changed: 51 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import org.junit.jupiter.api.BeforeAll;
4040
import org.junit.jupiter.api.BeforeEach;
4141
import org.junit.jupiter.api.Tag;
42+
import org.junit.jupiter.api.Test;
4243
import org.junit.jupiter.api.parallel.Execution;
4344
import org.junit.jupiter.api.parallel.ExecutionMode;
4445
import org.junit.jupiter.params.ParameterizedTest;
@@ -127,7 +128,7 @@ public void shutdownDuringValidation(int sleepMillis) {
127128
commitAndExpect(connection, EXPECTED_REPOSITORY_SIZE, 0);
128129

129130
} catch (RepositoryException e) {
130-
if (e.getCause() instanceof InterruptedException) {
131+
if (causedByInterruptedException(e)) {
131132
return;
132133
}
133134
logger.error("Error during test execution", e);
@@ -146,15 +147,15 @@ public void shutdownDuringValidation(int sleepMillis) {
146147
}
147148

148149
} catch (RepositoryException e) {
149-
if (e.getCause() instanceof InterruptedException) {
150+
if (causedByInterruptedException(e)) {
150151
// ignore this exception
151152
return;
152153
} else {
153154
throw e;
154155
}
155156
}
156157
} catch (Exception e) {
157-
if (e instanceof RepositoryException && e.getCause() instanceof InterruptedException) {
158+
if (e instanceof RepositoryException && causedByInterruptedException(e)) {
158159
System.out.println(e);
159160
return;
160161
}
@@ -193,7 +194,7 @@ public void shutdownDuringValidationTransactional(int sleepMillis) {
193194

194195
commitAndExpect(connection, EXPECTED_REPOSITORY_SIZE + 1, 1);
195196
} catch (RepositoryException e) {
196-
if (e.getCause() instanceof InterruptedException) {
197+
if (causedByInterruptedException(e)) {
197198
// ignore this exception
198199
return;
199200
}
@@ -211,15 +212,15 @@ public void shutdownDuringValidationTransactional(int sleepMillis) {
211212
.isIn(0L, 1L, (long) (EXPECTED_REPOSITORY_SIZE + 1));
212213

213214
} catch (RepositoryException e) {
214-
if (e.getCause() instanceof InterruptedException) {
215+
if (causedByInterruptedException(e)) {
215216
// ignore this exception
216217
return;
217218
} else {
218219
throw e;
219220
}
220221
}
221222
} catch (Exception e) {
222-
if (e instanceof RepositoryException && e.getCause() instanceof InterruptedException) {
223+
if (e instanceof RepositoryException && causedByInterruptedException(e)) {
223224
System.out.println(e);
224225
return;
225226
}
@@ -256,7 +257,7 @@ public void shutdownDuringValidationFailure(int sleepMillis) {
256257

257258
commitAndExpect(connection, 0, 0);
258259
} catch (RepositoryException e) {
259-
if (e.getCause() instanceof InterruptedException) {
260+
if (causedByInterruptedException(e)) {
260261
// ignore this exception
261262
return;
262263
}
@@ -270,15 +271,15 @@ public void shutdownDuringValidationFailure(int sleepMillis) {
270271
assertEquals(0, size,
271272
"The repository should be empty because the transaction always fails validation.");
272273
} catch (RepositoryException e) {
273-
if (e.getCause() instanceof InterruptedException) {
274+
if (causedByInterruptedException(e)) {
274275
// ignore this exception
275276
return;
276277
} else {
277278
throw e;
278279
}
279280
}
280281
} catch (Exception e) {
281-
if (e instanceof RepositoryException && e.getCause() instanceof InterruptedException) {
282+
if (e instanceof RepositoryException && causedByInterruptedException(e)) {
282283
System.out.println(e);
283284
return;
284285
}
@@ -314,7 +315,7 @@ public void shutdownDuringValidationFailureNonParallel(int sleepMillis) {
314315

315316
commitAndExpect(connection, 0, 0);
316317
} catch (RepositoryException e) {
317-
if (e.getCause() instanceof InterruptedException) {
318+
if (causedByInterruptedException(e)) {
318319
// ignore this exception
319320
return;
320321
}
@@ -329,15 +330,15 @@ public void shutdownDuringValidationFailureNonParallel(int sleepMillis) {
329330
assertEquals(0, size,
330331
"The repository should be empty because the transaction always fails validation.");
331332
} catch (RepositoryException e) {
332-
if (e.getCause() instanceof InterruptedException) {
333+
if (causedByInterruptedException(e)) {
333334
// ignore this exception
334335
return;
335336
} else {
336337
throw e;
337338
}
338339
}
339340
} catch (Exception e) {
340-
if (e instanceof RepositoryException && e.getCause() instanceof InterruptedException) {
341+
if (e instanceof RepositoryException && causedByInterruptedException(e)) {
341342
System.out.println(e);
342343
return;
343344
}
@@ -382,7 +383,7 @@ public void shutdownDuringValidationTransactionalNonParallel(int sleepMillis) {
382383
// ignore this exception
383384
return;
384385
}
385-
if (e.getCause() instanceof InterruptedException) {
386+
if (causedByInterruptedException(e)) {
386387
// ignore this exception
387388
return;
388389
}
@@ -403,15 +404,15 @@ public void shutdownDuringValidationTransactionalNonParallel(int sleepMillis) {
403404
.as("Repository size")
404405
.isIn(0L, 1L, (long) (EXPECTED_REPOSITORY_SIZE + 1));
405406
} catch (RepositoryException e) {
406-
if (e.getCause() instanceof InterruptedException) {
407+
if (causedByInterruptedException(e)) {
407408
// ignore this exception
408409
return;
409410
} else {
410411
throw e;
411412
}
412413
}
413414
} catch (Exception e) {
414-
if (e instanceof RepositoryException && e.getCause() instanceof InterruptedException) {
415+
if (e instanceof RepositoryException && causedByInterruptedException(e)) {
415416
System.out.println(e);
416417
return;
417418
}
@@ -427,6 +428,40 @@ public void shutdownDuringValidationTransactionalNonParallel(int sleepMillis) {
427428
}
428429
}
429430

431+
@Test
432+
void nestedInterruptedExceptionShouldBeDetected() {
433+
InterruptedException interruptedException = new InterruptedException("nested");
434+
SailException sailException = new SailException("wrapper", new SailException("inner", interruptedException));
435+
RepositoryException repositoryException = new RepositoryException("top", sailException);
436+
437+
boolean handled = causedByInterruptedException(repositoryException);
438+
439+
assertThat(handled).as("Should detect nested InterruptedException").isTrue();
440+
}
441+
442+
private static boolean causedByInterruptedException(Throwable throwable) {
443+
return causedByInterruptedExceptionRecursion(throwable, 10);
444+
}
445+
446+
private static boolean causedByInterruptedExceptionRecursion(Throwable throwable, int maxDepth) {
447+
if (maxDepth < 0) {
448+
throw new IllegalStateException("Too deep");
449+
}
450+
if (throwable == null) {
451+
return false;
452+
}
453+
if (throwable instanceof InterruptedException) {
454+
return true;
455+
}
456+
if (throwable instanceof InterruptedSailException) {
457+
return true;
458+
}
459+
if (throwable.getCause() == throwable) {
460+
return false;
461+
}
462+
return causedByInterruptedExceptionRecursion(throwable.getCause(), maxDepth - 1);
463+
}
464+
430465
private static void commitAndExpect(SailRepositoryConnection connection, long expected, long failedExpected) {
431466
try {
432467
connection.commit();
@@ -442,9 +477,7 @@ private static void commitAndExpect(SailRepositoryConnection connection, long ex
442477
try {
443478
connection.rollback();
444479
} catch (Exception e) {
445-
if (e.getCause() instanceof InterruptedException) {
446-
// ignore this exception
447-
} else if (e.getCause() != null && e.getCause().getCause() instanceof InterruptedException) {
480+
if (causedByInterruptedException(e)) {
448481
// ignore this exception
449482
} else {
450483
throw e;

0 commit comments

Comments
 (0)