This is an automated email from the ASF dual-hosted git repository.
gnodet 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 d5b4dba33e19 CAMEL-23907: Fix flaky ThreadsRejectedExecutionTest
(#24423)
d5b4dba33e19 is described below
commit d5b4dba33e19aca84ec21bef8ba99fa2cdcaf77f
Author: Guillaume Nodet <[email protected]>
AuthorDate: Mon Jul 6 08:11:35 2026 +0200
CAMEL-23907: Fix flaky ThreadsRejectedExecutionTest (#24423)
* CAMEL-23907: Fix flaky ThreadsRejectedExecutionTest
Replace fixed-timeout assertions (assertMockEndpointsSatisfied,
NotifyBuilder.matchesWaitTime, immediate inflight check) with
Awaitility-based polling in testThreadsRejectedAbortNoRedelivery
and sibling test methods. This eliminates timing sensitivity that
caused failures on JDK 25 where thread pool scheduling differs.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
* CAMEL-23907: Address review - capture counters in local variables
Capture getReceivedCounter() in local variables before assertions
to avoid duplicate calls and improve readability of failure messages.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
---------
Co-authored-by: Claude Opus 4.6 <[email protected]>
---
.../processor/ThreadsRejectedExecutionTest.java | 46 +++++++++++++---------
1 file changed, 27 insertions(+), 19 deletions(-)
diff --git
a/core/camel-core/src/test/java/org/apache/camel/processor/ThreadsRejectedExecutionTest.java
b/core/camel-core/src/test/java/org/apache/camel/processor/ThreadsRejectedExecutionTest.java
index 78839584924e..eb3a2f864d3d 100644
---
a/core/camel-core/src/test/java/org/apache/camel/processor/ThreadsRejectedExecutionTest.java
+++
b/core/camel-core/src/test/java/org/apache/camel/processor/ThreadsRejectedExecutionTest.java
@@ -26,6 +26,7 @@ import org.apache.camel.builder.NotifyBuilder;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.mock.MockEndpoint;
import org.apache.camel.util.concurrent.ThreadPoolRejectedPolicy;
+import org.awaitility.Awaitility;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
@@ -119,16 +120,18 @@ public class ThreadsRejectedExecutionTest extends
ContextTestSupport {
NotifyBuilder notify = new
NotifyBuilder(context).whenDone(10).create();
- getMockEndpoint("mock:result").expectedMinimumMessageCount(2);
for (int i = 0; i < 10; i++) {
template.sendBody("seda:start", "Message " + i);
}
- assertMockEndpointsSatisfied();
- assertTrue(notify.matchesWaitTime());
+ // use Awaitility to wait for all exchanges to be done and inflight to
drain
+ Awaitility.await().atMost(30, TimeUnit.SECONDS)
+ .untilAsserted(() -> assertTrue(notify.matches()));
+ Awaitility.await().atMost(10, TimeUnit.SECONDS)
+ .untilAsserted(() -> assertEquals(0,
context.getInflightRepository().size()));
- int inflight = context.getInflightRepository().size();
- assertEquals(0, inflight);
+ int resultCount = getMockEndpoint("mock:result").getReceivedCounter();
+ assertTrue(resultCount >= 2, "Expected at least 2 messages at
mock:result but got " + resultCount);
}
@Test
@@ -145,16 +148,18 @@ public class ThreadsRejectedExecutionTest extends
ContextTestSupport {
NotifyBuilder notify = new
NotifyBuilder(context).whenDone(10).create();
- getMockEndpoint("mock:result").expectedMessageCount(10);
for (int i = 0; i < 10; i++) {
template.sendBody("seda:start", "Message " + i);
}
- assertMockEndpointsSatisfied();
- assertTrue(notify.matchesWaitTime());
+ // use Awaitility to wait for all exchanges to be done and inflight to
drain
+ Awaitility.await().atMost(30, TimeUnit.SECONDS)
+ .untilAsserted(() -> assertTrue(notify.matches()));
+ Awaitility.await().atMost(10, TimeUnit.SECONDS)
+ .untilAsserted(() -> assertEquals(0,
context.getInflightRepository().size()));
- int inflight = context.getInflightRepository().size();
- assertEquals(0, inflight);
+ // CallerRuns policy means all messages should eventually complete
+ assertEquals(10, getMockEndpoint("mock:result").getReceivedCounter());
}
@Test
@@ -173,20 +178,23 @@ public class ThreadsRejectedExecutionTest extends
ContextTestSupport {
NotifyBuilder notify = new
NotifyBuilder(context).whenDone(10).create();
- // there should be error handling for aborted tasks (eg no redeliveries
- // and no error handling)
- getMockEndpoint("mock:error").expectedMessageCount(0);
-
- getMockEndpoint("mock:result").expectedMinimumMessageCount(2);
for (int i = 0; i < 10; i++) {
template.sendBody("seda:start", "Message " + i);
}
- assertMockEndpointsSatisfied();
- assertTrue(notify.matchesWaitTime());
+ // use Awaitility to wait for all exchanges to be done and inflight to
drain
+ Awaitility.await().atMost(30, TimeUnit.SECONDS)
+ .untilAsserted(() -> assertTrue(notify.matches()));
+ Awaitility.await().atMost(10, TimeUnit.SECONDS)
+ .untilAsserted(() -> assertEquals(0,
context.getInflightRepository().size()));
+
+ // at least 2 messages should have made it through the thread pool
+ int resultCount = getMockEndpoint("mock:result").getReceivedCounter();
+ assertTrue(resultCount >= 2, "Expected at least 2 messages at
mock:result but got " + resultCount);
- int inflight = context.getInflightRepository().size();
- assertEquals(0, inflight);
+ // there should be no error handling for aborted tasks (no
redeliveries and no error handling)
+ int errorCount = getMockEndpoint("mock:error").getReceivedCounter();
+ assertEquals(0, errorCount, "Expected 0 messages at mock:error but got
" + errorCount);
}
}