Skip to content

Commit e89e1dd

Browse files
committed
Update retry extension to handle parameterized tests
Signed-off-by: Hal Spang <halspang@microsoft.com>
1 parent 351255f commit e89e1dd

File tree

2 files changed

+28
-24
lines changed

2 files changed

+28
-24
lines changed

client/src/test/java/com/microsoft/durabletask/ErrorHandlingIntegrationTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ void subOrchestrationException(boolean handleException) throws TimeoutException
198198
@ValueSource(ints = {1, 2, 10})
199199
public void retrySubOrchestratorFailures(int maxNumberOfAttempts) throws TimeoutException {
200200
// There is one task for each sub-orchestrator call and one task between each retry
201-
int expectedTaskCount = (maxNumberOfAttempts * 2) - 1;
201+
int expectedTaskCount = (maxNumberOfAttempts * 2);
202202
this.retryOnFailuresCoreTest(maxNumberOfAttempts, expectedTaskCount, ctx -> {
203203
RetryPolicy retryPolicy = getCommonRetryPolicy(maxNumberOfAttempts);
204204
ctx.callSubOrchestrator(
Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,37 @@
11
package com.microsoft.durabletask;
22

33
import org.junit.jupiter.api.extension.ExtensionContext;
4-
import org.junit.jupiter.api.extension.TestExecutionExceptionHandler;
5-
import org.junit.jupiter.api.extension.BeforeEachCallback;
6-
import org.junit.jupiter.api.extension.AfterEachCallback;
4+
import org.junit.jupiter.api.extension.InvocationInterceptor;
5+
import org.junit.jupiter.api.extension.ReflectiveInvocationContext;
6+
import java.lang.reflect.Method;
77

8-
public class TestRetryExtension implements TestExecutionExceptionHandler, BeforeEachCallback, AfterEachCallback {
8+
public class TestRetryExtension implements InvocationInterceptor {
99
private static final int MAX_RETRIES = 3;
10-
private int currentRetries = 0;
1110

1211
@Override
13-
public void beforeEach(ExtensionContext context) {
14-
currentRetries = 0;
15-
}
16-
17-
@Override
18-
public void handleTestExecutionException(ExtensionContext context, Throwable throwable) throws Throwable {
19-
if (currentRetries < MAX_RETRIES - 1) {
20-
currentRetries++;
21-
System.err.println(String.format("Test '%s' failed on attempt %d/%d", context.getDisplayName(), currentRetries + 1, MAX_RETRIES));
22-
context.getRequiredTestMethod().invoke(context.getRequiredTestInstance());
23-
} else {
24-
System.err.println(String.format("Test '%s' failed after %d attempts", context.getDisplayName(), MAX_RETRIES));
25-
throw throwable;
12+
public void interceptTestMethod(Invocation<Void> invocation,
13+
ReflectiveInvocationContext<Method> invocationContext,
14+
ExtensionContext extensionContext) throws Throwable {
15+
16+
Throwable lastException = null;
17+
18+
for (int attempt = 1; attempt <= MAX_RETRIES; attempt++) {
19+
try {
20+
invocation.proceed();
21+
return; // Success, exit the retry loop
22+
} catch (Throwable throwable) {
23+
lastException = throwable;
24+
if (attempt < MAX_RETRIES) {
25+
System.err.println(String.format("Test '%s' failed on attempt %d/%d: %s",
26+
extensionContext.getDisplayName(), attempt, MAX_RETRIES, throwable.getMessage()));
27+
} else {
28+
System.err.println(String.format("Test '%s' failed after %d attempts",
29+
extensionContext.getDisplayName(), MAX_RETRIES));
30+
}
31+
}
2632
}
27-
}
28-
29-
@Override
30-
public void afterEach(ExtensionContext context) {
31-
currentRetries = 0;
33+
34+
// If we get here, all retries failed
35+
throw lastException;
3236
}
3337
}

0 commit comments

Comments
 (0)