Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
test: Add interruption tests for RetryInterceptor to validate behavio…
…r during retries
  • Loading branch information
reeshika-h committed Jan 23, 2026
commit ba967d780bb09e7cf5ab3f5d750c0d615f277637
88 changes: 88 additions & 0 deletions src/test/java/com/contentstack/sdk/RetryInterceptorTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -1022,5 +1022,93 @@ void testHasCustomBackoffStatus() {
assertTrue(retryOptions.hasCustomBackoff(),
"Should have custom backoff after setting it");
}

// ===========================
// Interruption Tests
// ===========================

@Test
@DisplayName("Test thread interruption during HTTP retry sleep")
void testThreadInterruptionDuringHttpRetrySleep() throws IOException {
Request request = createTestRequest();
Response failureResponse = createMockResponse(503);

MockChain chain = new MockChain(request);
chain.setResponse(failureResponse);

// Set a long delay and interrupt the thread
retryOptions.setRetryLimit(3).setRetryDelay(10000L);
interceptor = new RetryInterceptor(retryOptions);

// Interrupt the thread before calling intercept
Thread testThread = new Thread(() -> {
try {
Thread.sleep(50); // Wait a bit for the retry to start
Thread.currentThread().interrupt();
} catch (InterruptedException ignored) {
}
});
testThread.start();

// Simulate interruption by using a custom backoff that interrupts
retryOptions.setCustomBackoffStrategy((attempt, statusCode, exception) -> {
Thread.currentThread().interrupt();
return 10L;
});
interceptor = new RetryInterceptor(retryOptions);

IOException thrown = assertThrows(IOException.class,
() -> interceptor.intercept(chain),
"Should throw IOException when interrupted");

assertTrue(thrown.getMessage().contains("Retry interrupted"),
"Exception message should indicate interruption");
assertTrue(Thread.interrupted(), "Thread interrupt flag should be set");
}

@Test
@DisplayName("Test thread interruption during IOException retry sleep")
void testThreadInterruptionDuringIOExceptionRetrySleep() {
Request request = createTestRequest();
MockChain chain = new MockChain(request);
chain.setException(new IOException("Network error"));

retryOptions.setRetryLimit(3).setRetryDelay(10000L);

// Use custom backoff to trigger interruption
retryOptions.setCustomBackoffStrategy((attempt, statusCode, exception) -> {
Thread.currentThread().interrupt();
return 10L;
});
interceptor = new RetryInterceptor(retryOptions);

IOException thrown = assertThrows(IOException.class,
() -> interceptor.intercept(chain),
"Should throw IOException when interrupted");

assertTrue(thrown.getMessage().contains("Retry interrupted"),
"Exception message should indicate interruption");
assertTrue(Thread.interrupted(), "Thread interrupt flag should be set");
}

@Test
@DisplayName("Test response is closed on interruption")
void testResponseClosedOnInterruption() {
Request request = createTestRequest();
Response failureResponse = createMockResponse(503);

MockChain chain = new MockChain(request);
chain.setResponse(failureResponse);

// Use custom backoff to trigger interruption
retryOptions.setCustomBackoffStrategy((attempt, statusCode, exception) -> {
Thread.currentThread().interrupt();
return 10L;
});
interceptor = new RetryInterceptor(retryOptions);

assertThrows(IOException.class, () -> interceptor.intercept(chain));
assertTrue(Thread.interrupted(), "Thread should be interrupted");
}
}

Loading