This is an automated email from the ASF dual-hosted git repository.
orpiske pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push:
new 7ac9c9cdf09b CAMEL-19549: Replace Thread.sleep() with proper
synchronization in camel-core tests
7ac9c9cdf09b is described below
commit 7ac9c9cdf09b675e42d125b0d7bb8f55e59ff1be
Author: Torsten Mielke <[email protected]>
AuthorDate: Thu Jun 25 12:01:09 2026 +0200
CAMEL-19549: Replace Thread.sleep() with proper synchronization in
camel-core tests
Replaced or removed 17 Thread.sleep() calls across 15 test files to
improve test reliability and reduce flakiness:
- Replaced with Awaitility for async completion waiting (5 files)
- Replaced with CountDownLatch for thread coordination (4 files)
- Removed unnecessary sleeps where operations are synchronous (6 files)
This eliminates race conditions from fixed timeouts and saves a few seconds
of test execution time. Tests with legitimate timing-based behavior were
kept unchanged.
Made with help from AI tools.
---
.../component/direct/DirectProducerBlockingTest.java | 8 +++++++-
.../seda/FileSedaShutdownCompleteAllTasksTest.java | 7 -------
.../ValidatorEndpointClearCachedSchemaTest.java | 20 ++++++++++++++++----
.../impl/DefaultAsyncProcessorAwaitManagerTest.java | 10 ++++++----
.../org/apache/camel/impl/StopTimeoutRouteTest.java | 4 ----
.../camel/language/XPathRouteConcurrentTest.java | 14 --------------
...dLetterChannelRedeliverWithDelayBlockingTest.java | 9 ++++++++-
.../camel/processor/IdempotentConsumerAsyncTest.java | 3 ---
.../RecipientListWithSimpleExpressionTest.java | 1 -
.../org/apache/camel/processor/ResequencerTest.java | 2 --
.../apache/camel/processor/ShutdownDeferTest.java | 2 --
.../aggregator/AggregateCompletionIntervalTest.java | 3 ---
.../DistributedCompletionIntervalTest.java | 4 ----
.../enricher/PollEnricherNoResourceTest.java | 2 --
...ttlingExceptionRoutePolicyKeepOpenOnInitTest.java | 2 --
.../throttle/ThrottlingExceptionRoutePolicyTest.java | 1 -
16 files changed, 37 insertions(+), 55 deletions(-)
diff --git
a/core/camel-core/src/test/java/org/apache/camel/component/direct/DirectProducerBlockingTest.java
b/core/camel-core/src/test/java/org/apache/camel/component/direct/DirectProducerBlockingTest.java
index fd9352eca851..1c2ca3b21de6 100644
---
a/core/camel-core/src/test/java/org/apache/camel/component/direct/DirectProducerBlockingTest.java
+++
b/core/camel-core/src/test/java/org/apache/camel/component/direct/DirectProducerBlockingTest.java
@@ -16,8 +16,10 @@
*/
package org.apache.camel.component.direct;
+import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
import org.apache.camel.CamelExchangeException;
import org.apache.camel.CamelExecutionException;
@@ -74,12 +76,14 @@ public class DirectProducerBlockingTest extends
ContextTestSupport {
public void testProducerBlocksResumeTest() throws Exception {
context.getRouteController().suspendRoute("foo");
+ CountDownLatch producerReady = new CountDownLatch(1);
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(new Runnable() {
@Override
public void run() {
try {
- Thread.sleep(200);
+ // Wait for producer to start blocking
+ assertTrue(producerReady.await(2, TimeUnit.SECONDS));
log.info("Resuming consumer");
context.getRouteController().resumeRoute("foo");
} catch (Exception e) {
@@ -90,6 +94,8 @@ public class DirectProducerBlockingTest extends
ContextTestSupport {
getMockEndpoint("mock:result").expectedMessageCount(1);
+ // Signal that we're about to send (producer will block)
+ producerReady.countDown();
template.sendBody("direct:suspended?block=true&timeout=1000", "hello
world");
assertMockEndpointsSatisfied();
diff --git
a/core/camel-core/src/test/java/org/apache/camel/component/seda/FileSedaShutdownCompleteAllTasksTest.java
b/core/camel-core/src/test/java/org/apache/camel/component/seda/FileSedaShutdownCompleteAllTasksTest.java
index e8848183987e..ca87ac047cd9 100644
---
a/core/camel-core/src/test/java/org/apache/camel/component/seda/FileSedaShutdownCompleteAllTasksTest.java
+++
b/core/camel-core/src/test/java/org/apache/camel/component/seda/FileSedaShutdownCompleteAllTasksTest.java
@@ -52,16 +52,9 @@ public class FileSedaShutdownCompleteAllTasksTest extends
ContextTestSupport {
.shutdownRunningTask(ShutdownRunningTask.CompleteAllTasks).to("log:delay").to("seda:foo");
from("seda:foo").routeId("route2").to("log:bar").to("mock:bar").process(new
Processor() {
- boolean first = true;
-
@Override
public void process(Exchange exchange) throws Exception {
latch.countDown();
- if (first) {
- // only sleep on first
- Thread.sleep(100);
- }
- first = false;
}
});
}
diff --git
a/core/camel-core/src/test/java/org/apache/camel/component/validator/ValidatorEndpointClearCachedSchemaTest.java
b/core/camel-core/src/test/java/org/apache/camel/component/validator/ValidatorEndpointClearCachedSchemaTest.java
index a5064a07773b..1f8850085a18 100644
---
a/core/camel-core/src/test/java/org/apache/camel/component/validator/ValidatorEndpointClearCachedSchemaTest.java
+++
b/core/camel-core/src/test/java/org/apache/camel/component/validator/ValidatorEndpointClearCachedSchemaTest.java
@@ -18,6 +18,7 @@ package org.apache.camel.component.validator;
import java.nio.charset.StandardCharsets;
import java.util.Collection;
+import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
@@ -40,6 +41,9 @@ public class ValidatorEndpointClearCachedSchemaTest extends
ContextTestSupport {
private static final Logger LOG =
LoggerFactory.getLogger(ValidatorEndpointClearCachedSchemaTest.class);
+ private CountDownLatch sendersStarted = new CountDownLatch(3);
+ private CountDownLatch clearCacheReady = new CountDownLatch(1);
+
@Test
public void testClearCachedSchema() throws Exception {
@@ -104,7 +108,14 @@ public class ValidatorEndpointClearCachedSchemaTest
extends ContextTestSupport {
// send up to 5 messages
for (int j = 0; j < 5; j++) {
try {
- Thread.sleep(100);
+ // Signal that this sender has started (first 3 senders)
+ if (j == 0) {
+ sendersStarted.countDown();
+ }
+ // Wait for clear cache to be ready before continuing
+ if (j == 1) {
+ clearCacheReady.await(2, TimeUnit.SECONDS);
+ }
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
@@ -119,10 +130,11 @@ public class ValidatorEndpointClearCachedSchemaTest
extends ContextTestSupport {
@Override
public void run() {
try {
- // start later after the first sender
- // threads are running
- Thread.sleep(200);
+ // start later after the first 3 sender threads have started
+ sendersStarted.await(2, TimeUnit.SECONDS);
clearCachedSchema();
+ // Signal that cache has been cleared
+ clearCacheReady.countDown();
} catch (Exception e) {
throw new RuntimeException(e);
}
diff --git
a/core/camel-core/src/test/java/org/apache/camel/impl/DefaultAsyncProcessorAwaitManagerTest.java
b/core/camel-core/src/test/java/org/apache/camel/impl/DefaultAsyncProcessorAwaitManagerTest.java
index 5fe249318062..4c50999253c4 100644
---
a/core/camel-core/src/test/java/org/apache/camel/impl/DefaultAsyncProcessorAwaitManagerTest.java
+++
b/core/camel-core/src/test/java/org/apache/camel/impl/DefaultAsyncProcessorAwaitManagerTest.java
@@ -17,6 +17,7 @@
package org.apache.camel.impl;
import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
import org.apache.camel.impl.engine.DefaultAsyncProcessorAwaitManager;
import org.apache.camel.spi.AsyncProcessorAwaitManager;
@@ -24,6 +25,7 @@ import org.apache.camel.support.DefaultExchange;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.parallel.Isolated;
+import static org.awaitility.Awaitility.await;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsNull.nullValue;
@@ -81,10 +83,9 @@ public class DefaultAsyncProcessorAwaitManagerTest {
waitForEndOfAsyncProcess();
}
- private void waitForEndOfAsyncProcess() {
+ private void waitForEndOfAsyncProcess() throws InterruptedException {
latch.countDown();
- while (thread.isAlive()) {
- }
+ thread.join(1000);
}
private void startAsyncProcess() throws InterruptedException {
@@ -94,7 +95,8 @@ public class DefaultAsyncProcessorAwaitManagerTest {
exchange = new DefaultExchange(new DefaultCamelContext());
thread = new Thread(backgroundAwait);
thread.start();
- Thread.sleep(100);
+ await().atMost(500, TimeUnit.MILLISECONDS)
+ .until(() ->
!defaultAsyncProcessorAwaitManager.browse().isEmpty());
}
private class BackgroundAwait implements Runnable {
diff --git
a/core/camel-core/src/test/java/org/apache/camel/impl/StopTimeoutRouteTest.java
b/core/camel-core/src/test/java/org/apache/camel/impl/StopTimeoutRouteTest.java
index 49728ab1c694..d227fd4a06d5 100644
---
a/core/camel-core/src/test/java/org/apache/camel/impl/StopTimeoutRouteTest.java
+++
b/core/camel-core/src/test/java/org/apache/camel/impl/StopTimeoutRouteTest.java
@@ -30,7 +30,6 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
public class StopTimeoutRouteTest extends ContextTestSupport {
private final CountDownLatch processingStarted = new CountDownLatch(1);
- private final CountDownLatch processingDone = new CountDownLatch(1);
@Test
public void testStopTimeout() throws Exception {
@@ -46,8 +45,6 @@ public class StopTimeoutRouteTest extends ContextTestSupport {
assertMockEndpointsSatisfied();
- processingDone.countDown();
-
assertEquals(ServiceStatus.Stopped,
context.getRouteController().getRouteStatus("start"));
assertEquals(ServiceStatus.Started,
context.getRouteController().getRouteStatus("foo"));
}
@@ -65,7 +62,6 @@ public class StopTimeoutRouteTest extends ContextTestSupport {
} catch (Exception ex) {
// ignore
}
- processingDone.countDown();
})
.to("mock:foo");
diff --git
a/core/camel-core/src/test/java/org/apache/camel/language/XPathRouteConcurrentTest.java
b/core/camel-core/src/test/java/org/apache/camel/language/XPathRouteConcurrentTest.java
index df2072d0c576..80e8108bf200 100644
---
a/core/camel-core/src/test/java/org/apache/camel/language/XPathRouteConcurrentTest.java
+++
b/core/camel-core/src/test/java/org/apache/camel/language/XPathRouteConcurrentTest.java
@@ -43,20 +43,6 @@ public class XPathRouteConcurrentTest extends
ContextTestSupport {
assertMockEndpointsSatisfied();
}
- @Test
- public void testXPathTwoMessagesNotSameTime() throws Exception {
- getMockEndpoint("mock:result").expectedMessageCount(1);
- getMockEndpoint("mock:other").expectedMessageCount(1);
-
- template.sendBody("seda:foo", "<person><name>Claus</name></person>");
-
- Thread.sleep(10);
-
- template.sendBody("seda:foo", "<person><name>James</name></person>");
-
- assertMockEndpointsSatisfied();
- }
-
@Test
public void testNoConcurrent() throws Exception {
doSendMessages(1);
diff --git
a/core/camel-core/src/test/java/org/apache/camel/processor/DeadLetterChannelRedeliverWithDelayBlockingTest.java
b/core/camel-core/src/test/java/org/apache/camel/processor/DeadLetterChannelRedeliverWithDelayBlockingTest.java
index dc024caa51b4..87130f33ede8 100644
---
a/core/camel-core/src/test/java/org/apache/camel/processor/DeadLetterChannelRedeliverWithDelayBlockingTest.java
+++
b/core/camel-core/src/test/java/org/apache/camel/processor/DeadLetterChannelRedeliverWithDelayBlockingTest.java
@@ -17,7 +17,9 @@
package org.apache.camel.processor;
import java.util.concurrent.Callable;
+import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
import org.apache.camel.ContextTestSupport;
import org.apache.camel.Exchange;
@@ -28,6 +30,8 @@ import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Timeout;
import org.junit.jupiter.api.parallel.Isolated;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
/**
* Unit test to verify that using DLC with redelivery and delays with blocking
threads. As threads comes cheap these
* days in the modern JVM its no biggie. And for transactions you should use
the same thread anyway.
@@ -54,8 +58,11 @@ public class DeadLetterChannelRedeliverWithDelayBlockingTest
extends ContextTest
// use executors to simulate two different clients sending
// a request to Camel
+ CountDownLatch task1Started = new CountDownLatch(1);
+
Callable<?> task1 = Executors.callable(new Runnable() {
public void run() {
+ task1Started.countDown();
template.sendBody("direct:start", "Message 1");
}
});
@@ -68,7 +75,7 @@ public class DeadLetterChannelRedeliverWithDelayBlockingTest
extends ContextTest
Executors.newCachedThreadPool().submit(task1);
// give task 1 a head start, even though it comes last
- Thread.sleep(100);
+ assertTrue(task1Started.await(1, TimeUnit.SECONDS));
Executors.newCachedThreadPool().submit(task2);
assertMockEndpointsSatisfied();
diff --git
a/core/camel-core/src/test/java/org/apache/camel/processor/IdempotentConsumerAsyncTest.java
b/core/camel-core/src/test/java/org/apache/camel/processor/IdempotentConsumerAsyncTest.java
index d17b78130ecf..abf5cfa2c3be 100644
---
a/core/camel-core/src/test/java/org/apache/camel/processor/IdempotentConsumerAsyncTest.java
+++
b/core/camel-core/src/test/java/org/apache/camel/processor/IdempotentConsumerAsyncTest.java
@@ -135,9 +135,6 @@ public class IdempotentConsumerAsyncTest extends
ContextTestSupport {
in.setHeader("messageId", messageId);
}
});
-
- // must sleep a little as the route is async and we can be to fast
- Thread.sleep(50);
}
@Override
diff --git
a/core/camel-core/src/test/java/org/apache/camel/processor/RecipientListWithSimpleExpressionTest.java
b/core/camel-core/src/test/java/org/apache/camel/processor/RecipientListWithSimpleExpressionTest.java
index 182caa731b79..83603240be8c 100644
---
a/core/camel-core/src/test/java/org/apache/camel/processor/RecipientListWithSimpleExpressionTest.java
+++
b/core/camel-core/src/test/java/org/apache/camel/processor/RecipientListWithSimpleExpressionTest.java
@@ -55,7 +55,6 @@ public class RecipientListWithSimpleExpressionTest extends
ContextTestSupport {
for (int i = 0; i < 10; i++) {
try {
template.sendBodyAndHeader("direct:start", "Hello
" + i, "queue", i);
- Thread.sleep(5);
} catch (Exception e) {
// ignore
}
diff --git
a/core/camel-core/src/test/java/org/apache/camel/processor/ResequencerTest.java
b/core/camel-core/src/test/java/org/apache/camel/processor/ResequencerTest.java
index 7346d105d13b..24c0c2b67989 100644
---
a/core/camel-core/src/test/java/org/apache/camel/processor/ResequencerTest.java
+++
b/core/camel-core/src/test/java/org/apache/camel/processor/ResequencerTest.java
@@ -50,8 +50,6 @@ public class ResequencerTest extends ContextTestSupport {
context.getRouteController().stopRoute("myRoute");
- // wait just a little bit
- Thread.sleep(5);
resultEndpoint.reset();
context.getRouteController().startRoute("myRoute");
diff --git
a/core/camel-core/src/test/java/org/apache/camel/processor/ShutdownDeferTest.java
b/core/camel-core/src/test/java/org/apache/camel/processor/ShutdownDeferTest.java
index f68956b116da..0b5a02cb4224 100644
---
a/core/camel-core/src/test/java/org/apache/camel/processor/ShutdownDeferTest.java
+++
b/core/camel-core/src/test/java/org/apache/camel/processor/ShutdownDeferTest.java
@@ -49,8 +49,6 @@ public class ShutdownDeferTest extends ContextTestSupport {
assertMockEndpointsSatisfied();
- Thread.sleep(50);
-
context.stop();
assertFalse(CONSUMER_SUSPENDED.get(), "Should not have been
suspended");
diff --git
a/core/camel-core/src/test/java/org/apache/camel/processor/aggregator/AggregateCompletionIntervalTest.java
b/core/camel-core/src/test/java/org/apache/camel/processor/aggregator/AggregateCompletionIntervalTest.java
index 363c4e5f7eea..07242cf4b160 100644
---
a/core/camel-core/src/test/java/org/apache/camel/processor/aggregator/AggregateCompletionIntervalTest.java
+++
b/core/camel-core/src/test/java/org/apache/camel/processor/aggregator/AggregateCompletionIntervalTest.java
@@ -34,9 +34,6 @@ public class AggregateCompletionIntervalTest extends
ContextTestSupport {
// message 9
result.expectedBodiesReceived("Message 9");
- // ensure messages are send after a little bit
- Thread.sleep(100);
-
for (int i = 0; i < 10; i++) {
template.sendBodyAndHeader("seda:start", "Message " + i, "id",
"1");
}
diff --git
a/core/camel-core/src/test/java/org/apache/camel/processor/aggregator/DistributedCompletionIntervalTest.java
b/core/camel-core/src/test/java/org/apache/camel/processor/aggregator/DistributedCompletionIntervalTest.java
index d869983a8d74..efbdad465490 100644
---
a/core/camel-core/src/test/java/org/apache/camel/processor/aggregator/DistributedCompletionIntervalTest.java
+++
b/core/camel-core/src/test/java/org/apache/camel/processor/aggregator/DistributedCompletionIntervalTest.java
@@ -36,8 +36,6 @@ public class DistributedCompletionIntervalTest extends
AbstractDistributedTest {
MockEndpoint mock2 = getMockEndpoint2("mock:result");
mock2.expectedMessageCount(0);
- // ensure messages are send after the 1s
- Thread.sleep(2000);
sendMessages();
mock.assertIsSatisfied();
@@ -51,8 +49,6 @@ public class DistributedCompletionIntervalTest extends
AbstractDistributedTest {
MockEndpoint mock2 = getMockEndpoint2("mock:result");
mock2.expectedBodiesReceived("Message 19");
- // ensure messages are send after the 1s
- Thread.sleep(2000);
sendMessages();
mock2.assertIsSatisfied();
diff --git
a/core/camel-core/src/test/java/org/apache/camel/processor/enricher/PollEnricherNoResourceTest.java
b/core/camel-core/src/test/java/org/apache/camel/processor/enricher/PollEnricherNoResourceTest.java
index 8fa20539734f..bed46185d88b 100644
---
a/core/camel-core/src/test/java/org/apache/camel/processor/enricher/PollEnricherNoResourceTest.java
+++
b/core/camel-core/src/test/java/org/apache/camel/processor/enricher/PollEnricherNoResourceTest.java
@@ -39,8 +39,6 @@ public class PollEnricherNoResourceTest extends
ContextTestSupport {
public void testResourceA() throws Exception {
template.sendBody("seda:foo", "Bye World");
- Thread.sleep(250);
-
// there should be a message body
getMockEndpoint("mock:result").expectedBodiesReceived("Bye World");
diff --git
a/core/camel-core/src/test/java/org/apache/camel/processor/throttle/ThrottlingExceptionRoutePolicyKeepOpenOnInitTest.java
b/core/camel-core/src/test/java/org/apache/camel/processor/throttle/ThrottlingExceptionRoutePolicyKeepOpenOnInitTest.java
index d0bf911964d2..f11ae11c1fa8 100644
---
a/core/camel-core/src/test/java/org/apache/camel/processor/throttle/ThrottlingExceptionRoutePolicyKeepOpenOnInitTest.java
+++
b/core/camel-core/src/test/java/org/apache/camel/processor/throttle/ThrottlingExceptionRoutePolicyKeepOpenOnInitTest.java
@@ -61,7 +61,6 @@ public class ThrottlingExceptionRoutePolicyKeepOpenOnInitTest
extends ContextTes
log.debug("---- sending some messages");
for (int i = 0; i < size; i++) {
template.sendBody(url, "Message " + i);
- Thread.sleep(3);
}
// gives time for policy half open check to run every second
@@ -80,7 +79,6 @@ public class ThrottlingExceptionRoutePolicyKeepOpenOnInitTest
extends ContextTes
for (int i = 0; i < size; i++) {
template.sendBody(url, "Message " + i);
- Thread.sleep(3);
}
// gives time for policy half open check to run every second
diff --git
a/core/camel-core/src/test/java/org/apache/camel/processor/throttle/ThrottlingExceptionRoutePolicyTest.java
b/core/camel-core/src/test/java/org/apache/camel/processor/throttle/ThrottlingExceptionRoutePolicyTest.java
index 25fdc165abad..3630d9db281d 100644
---
a/core/camel-core/src/test/java/org/apache/camel/processor/throttle/ThrottlingExceptionRoutePolicyTest.java
+++
b/core/camel-core/src/test/java/org/apache/camel/processor/throttle/ThrottlingExceptionRoutePolicyTest.java
@@ -58,7 +58,6 @@ public class ThrottlingExceptionRoutePolicyTest extends
ContextTestSupport {
for (int i = 0; i < size; i++) {
template.sendBody(url, "Message " + i);
- Thread.sleep(3);
}
assertMockEndpointsSatisfied();