Browse Source

Make @​Retryable and RetryTemplate timeout tests more robust

See gh-35963
pull/35990/head
Sam Brannen 1 week ago
parent
commit
d0be180a69
  1. 14
      spring-context/src/test/java/org/springframework/resilience/ReactiveRetryInterceptorTests.java
  2. 10
      spring-context/src/test/java/org/springframework/resilience/RetryInterceptorTests.java
  3. 26
      spring-core/src/test/java/org/springframework/core/retry/RetryTemplateTests.java

14
spring-context/src/test/java/org/springframework/resilience/ReactiveRetryInterceptorTests.java

@ -351,7 +351,7 @@ class ReactiveRetryInterceptorTests {
.satisfies(isReactiveException()) .satisfies(isReactiveException())
.havingCause() .havingCause()
.isInstanceOf(TimeoutException.class) .isInstanceOf(TimeoutException.class)
.withMessageContaining("within 5ms"); .withMessageContaining("within 20ms");
// 1 initial attempt + 0 retries // 1 initial attempt + 0 retries
assertThat(target.counter).hasValue(1); assertThat(target.counter).hasValue(1);
} }
@ -363,7 +363,7 @@ class ReactiveRetryInterceptorTests {
.satisfies(isReactiveException()) .satisfies(isReactiveException())
.havingCause() .havingCause()
.isInstanceOf(TimeoutException.class) .isInstanceOf(TimeoutException.class)
.withMessageContaining("within 5ms"); .withMessageContaining("within 20ms");
// 1 initial attempt + 0 retries // 1 initial attempt + 0 retries
assertThat(target.counter).hasValue(1); assertThat(target.counter).hasValue(1);
} }
@ -464,16 +464,16 @@ class ReactiveRetryInterceptorTests {
}); });
} }
@Retryable(timeout = 5, delay = 0) @Retryable(timeout = 20, delay = 0)
public Mono<Object> retryOperationWithTimeoutExceededAfterInitialFailure() { public Mono<Object> retryOperationWithTimeoutExceededAfterInitialFailure() {
return Mono.fromCallable(() -> { return Mono.fromCallable(() -> {
counter.incrementAndGet(); counter.incrementAndGet();
Thread.sleep(20); Thread.sleep(100);
throw new IOException(counter.toString()); throw new IOException(counter.toString());
}); });
} }
@Retryable(timeout = 5, delay = 10) @Retryable(timeout = 20, delay = 100) // Delay > Timeout
public Mono<Object> retryOperationWithTimeoutExceededAfterFirstDelayButBeforeFirstRetry() { public Mono<Object> retryOperationWithTimeoutExceededAfterFirstDelayButBeforeFirstRetry() {
return Mono.fromCallable(() -> { return Mono.fromCallable(() -> {
counter.incrementAndGet(); counter.incrementAndGet();
@ -486,7 +486,7 @@ class ReactiveRetryInterceptorTests {
return Mono.fromCallable(() -> { return Mono.fromCallable(() -> {
counter.incrementAndGet(); counter.incrementAndGet();
if (counter.get() == 2) { if (counter.get() == 2) {
Thread.sleep(50); Thread.sleep(100);
} }
throw new IOException(counter.toString()); throw new IOException(counter.toString());
}); });
@ -497,7 +497,7 @@ class ReactiveRetryInterceptorTests {
return Mono.fromCallable(() -> { return Mono.fromCallable(() -> {
counter.incrementAndGet(); counter.incrementAndGet();
if (counter.get() == 3) { if (counter.get() == 3) {
Thread.sleep(50); Thread.sleep(100);
} }
throw new IOException(counter.toString()); throw new IOException(counter.toString());
}); });

10
spring-context/src/test/java/org/springframework/resilience/RetryInterceptorTests.java

@ -426,14 +426,14 @@ class RetryInterceptorTests {
throw new IOException(Integer.toString(counter)); throw new IOException(Integer.toString(counter));
} }
@Retryable(timeout = 5, delay = 10) @Retryable(timeout = 20, delay = 0)
public void retryOperationWithTimeoutExceededAfterInitialFailure() throws Exception { public void retryOperationWithTimeoutExceededAfterInitialFailure() throws Exception {
counter++; counter++;
Thread.sleep(10); Thread.sleep(100);
throw new IOException(Integer.toString(counter)); throw new IOException(Integer.toString(counter));
} }
@Retryable(timeout = 5, delay = 10) @Retryable(timeout = 20, delay = 100) // Delay > Timeout
public void retryOperationWithTimeoutExceededAfterFirstDelayButBeforeFirstRetry() throws IOException { public void retryOperationWithTimeoutExceededAfterFirstDelayButBeforeFirstRetry() throws IOException {
counter++; counter++;
throw new IOException(Integer.toString(counter)); throw new IOException(Integer.toString(counter));
@ -443,7 +443,7 @@ class RetryInterceptorTests {
public void retryOperationWithTimeoutExceededAfterFirstRetry() throws Exception { public void retryOperationWithTimeoutExceededAfterFirstRetry() throws Exception {
counter++; counter++;
if (counter == 2) { if (counter == 2) {
Thread.sleep(50); Thread.sleep(100);
} }
throw new IOException(Integer.toString(counter)); throw new IOException(Integer.toString(counter));
} }
@ -452,7 +452,7 @@ class RetryInterceptorTests {
public void retryOperationWithTimeoutExceededAfterSecondRetry() throws Exception { public void retryOperationWithTimeoutExceededAfterSecondRetry() throws Exception {
counter++; counter++;
if (counter == 3) { if (counter == 3) {
Thread.sleep(50); Thread.sleep(100);
} }
throw new IOException(Integer.toString(counter)); throw new IOException(Integer.toString(counter));
} }

26
spring-core/src/test/java/org/springframework/core/retry/RetryTemplateTests.java

@ -413,14 +413,14 @@ class RetryTemplateTests {
@Test @Test
void retryWithImmediateSuccessAndTimeoutExceeded() throws Exception { void retryWithImmediateSuccessAndTimeoutExceeded() throws Exception {
RetryPolicy retryPolicy = RetryPolicy.builder().timeout(Duration.ofMillis(5)).build(); RetryPolicy retryPolicy = RetryPolicy.builder().timeout(Duration.ofMillis(10)).build();
RetryTemplate retryTemplate = new RetryTemplate(retryPolicy); RetryTemplate retryTemplate = new RetryTemplate(retryPolicy);
retryTemplate.setRetryListener(retryListener); retryTemplate.setRetryListener(retryListener);
AtomicInteger invocationCount = new AtomicInteger(); AtomicInteger invocationCount = new AtomicInteger();
Retryable<String> retryable = () -> { Retryable<String> retryable = () -> {
invocationCount.incrementAndGet(); invocationCount.incrementAndGet();
Thread.sleep(10); Thread.sleep(100);
return "always succeeds"; return "always succeeds";
}; };
@ -435,7 +435,7 @@ class RetryTemplateTests {
@Test @Test
void retryWithInitialFailureAndZeroRetriesRetryPolicyAndTimeoutExceeded() { void retryWithInitialFailureAndZeroRetriesRetryPolicyAndTimeoutExceeded() {
RetryPolicy retryPolicy = RetryPolicy.builder() RetryPolicy retryPolicy = RetryPolicy.builder()
.timeout(Duration.ofMillis(5)) .timeout(Duration.ofMillis(10))
.predicate(throwable -> false) // Zero retries .predicate(throwable -> false) // Zero retries
.build(); .build();
RetryTemplate retryTemplate = new RetryTemplate(retryPolicy); RetryTemplate retryTemplate = new RetryTemplate(retryPolicy);
@ -443,7 +443,7 @@ class RetryTemplateTests {
Exception exception = new RuntimeException("Boom!"); Exception exception = new RuntimeException("Boom!");
Retryable<String> retryable = () -> { Retryable<String> retryable = () -> {
Thread.sleep(10); Thread.sleep(100);
throw exception; throw exception;
}; };
@ -461,7 +461,7 @@ class RetryTemplateTests {
@Test @Test
void retryWithTimeoutExceededAfterInitialFailure() throws Exception { void retryWithTimeoutExceededAfterInitialFailure() throws Exception {
RetryPolicy retryPolicy = RetryPolicy.builder() RetryPolicy retryPolicy = RetryPolicy.builder()
.timeout(Duration.ofMillis(5)) .timeout(Duration.ofMillis(10))
.delay(Duration.ZERO) .delay(Duration.ZERO)
.build(); .build();
RetryTemplate retryTemplate = new RetryTemplate(retryPolicy); RetryTemplate retryTemplate = new RetryTemplate(retryPolicy);
@ -469,14 +469,14 @@ class RetryTemplateTests {
AtomicInteger invocationCount = new AtomicInteger(); AtomicInteger invocationCount = new AtomicInteger();
Retryable<String> retryable = () -> { Retryable<String> retryable = () -> {
Thread.sleep(10); Thread.sleep(100);
throw new CustomException("Boom " + invocationCount.incrementAndGet()); throw new CustomException("Boom " + invocationCount.incrementAndGet());
}; };
assertThat(invocationCount).hasValue(0); assertThat(invocationCount).hasValue(0);
assertThatExceptionOfType(RetryException.class) assertThatExceptionOfType(RetryException.class)
.isThrownBy(() -> retryTemplate.execute(retryable)) .isThrownBy(() -> retryTemplate.execute(retryable))
.withMessageMatching("Retry policy for operation '.+?' exceeded timeout \\(5ms\\); aborting execution") .withMessageMatching("Retry policy for operation '.+?' exceeded timeout \\(10ms\\); aborting execution")
.withCause(new CustomException("Boom 1")) .withCause(new CustomException("Boom 1"))
.satisfies(throwable -> inOrder.verify(retryListener).onRetryPolicyTimeout( .satisfies(throwable -> inOrder.verify(retryListener).onRetryPolicyTimeout(
eq(retryPolicy), eq(retryable), eq(throwable))); eq(retryPolicy), eq(retryable), eq(throwable)));
@ -488,8 +488,8 @@ class RetryTemplateTests {
@Test @Test
void retryWithTimeoutExceededAfterFirstDelayButBeforeFirstRetry() throws Exception { void retryWithTimeoutExceededAfterFirstDelayButBeforeFirstRetry() throws Exception {
RetryPolicy retryPolicy = RetryPolicy.builder() RetryPolicy retryPolicy = RetryPolicy.builder()
.timeout(Duration.ofMillis(5)) .timeout(Duration.ofMillis(20))
.delay(Duration.ofMillis(10)) // Delay > Timeout .delay(Duration.ofMillis(100)) // Delay > Timeout
.build(); .build();
RetryTemplate retryTemplate = new RetryTemplate(retryPolicy); RetryTemplate retryTemplate = new RetryTemplate(retryPolicy);
retryTemplate.setRetryListener(retryListener); retryTemplate.setRetryListener(retryListener);
@ -503,8 +503,8 @@ class RetryTemplateTests {
assertThatExceptionOfType(RetryException.class) assertThatExceptionOfType(RetryException.class)
.isThrownBy(() -> retryTemplate.execute(retryable)) .isThrownBy(() -> retryTemplate.execute(retryable))
.withMessageMatching(""" .withMessageMatching("""
Retry policy for operation '.+?' would exceed timeout \\(5ms\\) \ Retry policy for operation '.+?' would exceed timeout \\(20ms\\) \
due to pending sleep time \\(10ms\\); preemptively aborting execution\ due to pending sleep time \\(100ms\\); preemptively aborting execution\
""") """)
.withCause(new CustomException("Boom 1")) .withCause(new CustomException("Boom 1"))
.satisfies(throwable -> inOrder.verify(retryListener).onRetryPolicyTimeout( .satisfies(throwable -> inOrder.verify(retryListener).onRetryPolicyTimeout(
@ -527,7 +527,7 @@ class RetryTemplateTests {
Retryable<String> retryable = () -> { Retryable<String> retryable = () -> {
int currentInvocation = invocationCount.incrementAndGet(); int currentInvocation = invocationCount.incrementAndGet();
if (currentInvocation == 2) { if (currentInvocation == 2) {
Thread.sleep(50); Thread.sleep(100);
} }
throw new CustomException("Boom " + currentInvocation); throw new CustomException("Boom " + currentInvocation);
}; };
@ -562,7 +562,7 @@ class RetryTemplateTests {
Retryable<String> retryable = () -> { Retryable<String> retryable = () -> {
int currentInvocation = invocationCount.incrementAndGet(); int currentInvocation = invocationCount.incrementAndGet();
if (currentInvocation == 3) { if (currentInvocation == 3) {
Thread.sleep(50); Thread.sleep(100);
} }
throw new CustomException("Boom " + currentInvocation); throw new CustomException("Boom " + currentInvocation);
}; };

Loading…
Cancel
Save