Skip to content

Commit 748d78f

Browse files
committedMar 31, 2025··
Fix race condition in the LockRequestHandlerAdviceTests
The timeout of `5 seconds` might not be enough on slow environment like GHA. * Rework the test logic to rely on the `CountDownLatch` instead. This way the `longer_process` would wait for it to be fulfilled, while we count down only when another request has failed with timeout for locking.
1 parent 3f3d4d8 commit 748d78f

File tree

1 file changed

+20
-3
lines changed

1 file changed

+20
-3
lines changed
 

‎spring-integration-core/src/test/java/org/springframework/integration/handler/advice/LockRequestHandlerAdviceTests.java

+20-3
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package org.springframework.integration.handler.advice;
1818

19+
import java.util.concurrent.CountDownLatch;
1920
import java.util.concurrent.ExecutionException;
2021
import java.util.concurrent.Future;
2122
import java.util.concurrent.TimeUnit;
@@ -60,6 +61,9 @@ public class LockRequestHandlerAdviceTests {
6061
@Autowired
6162
QueueChannel discardChannel;
6263

64+
@Autowired
65+
Config config;
66+
6367
@Test
6468
void verifyLockAroundHandler() throws ExecutionException, InterruptedException, TimeoutException {
6569
AsyncMessagingTemplate messagingTemplate = new AsyncMessagingTemplate();
@@ -89,12 +93,16 @@ void verifyLockAroundHandler() throws ExecutionException, InterruptedException,
8993
Future<Object> test4 =
9094
messagingTemplate.asyncConvertSendAndReceive(this.inputChannel, "test4", messagePostProcessor);
9195

92-
assertThat(test3.get(10, TimeUnit.SECONDS)).isEqualTo("longer_process-1");
93-
96+
// It is hard to achieve exclusive access in time, so expect failure first,
97+
// then unblock count-down-latch barrier to let success pass.
9498
assertThat(test4).failsWithin(10, TimeUnit.SECONDS)
9599
.withThrowableOfType(ExecutionException.class)
96100
.withRootCauseInstanceOf(TimeoutException.class)
97101
.withStackTraceContaining("Could not acquire the lock in time: PT1S");
102+
103+
this.config.longProcessLatch.countDown();
104+
105+
assertThat(test3.get(10, TimeUnit.SECONDS)).isEqualTo("longer_process-1");
98106
}
99107

100108
@Configuration
@@ -122,10 +130,19 @@ LockRequestHandlerAdvice lockRequestHandlerAdvice(LockRegistry lockRegistry, Que
122130

123131
AtomicInteger counter = new AtomicInteger();
124132

133+
CountDownLatch longProcessLatch = new CountDownLatch(1);
134+
125135
@ServiceActivator(inputChannel = "inputChannel", adviceChain = "lockRequestHandlerAdvice")
126136
String handleWithDelay(String payload) throws InterruptedException {
127137
int currentCount = this.counter.incrementAndGet();
128-
Thread.sleep("longer_process".equals(payload) ? 5000 : 500);
138+
if ("longer_process".equals(payload)) {
139+
// Hard to achieve blocking expectations just with timeouts.
140+
// So, wait for count-down-latch to be fulfilled.
141+
longProcessLatch.await(10, TimeUnit.SECONDS);
142+
}
143+
else {
144+
Thread.sleep(500);
145+
}
129146
try {
130147
return payload + "-" + currentCount;
131148
}

0 commit comments

Comments
 (0)
Please sign in to comment.