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 feab40915038 CAMEL-19528: Replace CountDownLatch with Awaitility in
camel-jpa tests (#24411)
feab40915038 is described below
commit feab40915038fffcdda086911da38ffcc021da46
Author: Guillaume Nodet <[email protected]>
AuthorDate: Sat Jul 4 08:49:25 2026 +0200
CAMEL-19528: Replace CountDownLatch with Awaitility in camel-jpa tests
(#24411)
Replace flaky CountDownLatch-based synchronization with Awaitility
polling in JPA consumer tests. The CountDownLatch pattern caused
intermittent hangs and timeouts in CI because the JPA consumer's
scheduled polling (1s initial delay, 500ms interval) could miss the
fixed deadline under load.
Changes:
- JpaWithNamedQueryTest: replace CountDownLatch + latch.await() with
Awaitility await().untilAsserted()
- JpaTest: same CountDownLatch to Awaitility migration
- JpaWithNamedQueryAndParametersTest: same migration
- Re-enable JpaWithQueryTest, JpaWithNativeQueryTest, and
JpaWithNativeQueryWithResultClassTest by removing
@DisabledIfSystemProperty annotations (the underlying timing
issue in their parent class is now fixed)
- Mark receivedExchange fields as volatile for thread-safe publication
Co-authored-by: Claude Opus 4.6 <[email protected]>
---
.../org/apache/camel/component/jpa/JpaTest.java | 24 ++++++++++------------
.../jpa/JpaWithNamedQueryAndParametersTest.java | 11 ++++------
.../camel/component/jpa/JpaWithNamedQueryTest.java | 10 +++------
.../component/jpa/JpaWithNativeQueryTest.java | 3 ---
.../jpa/JpaWithNativeQueryWithResultClassTest.java | 5 ++---
.../camel/component/jpa/JpaWithQueryTest.java | 3 ---
6 files changed, 20 insertions(+), 36 deletions(-)
diff --git
a/components/camel-jpa/src/test/java/org/apache/camel/component/jpa/JpaTest.java
b/components/camel-jpa/src/test/java/org/apache/camel/component/jpa/JpaTest.java
index 237adc73a5cc..22df220e5ece 100644
---
a/components/camel-jpa/src/test/java/org/apache/camel/component/jpa/JpaTest.java
+++
b/components/camel-jpa/src/test/java/org/apache/camel/component/jpa/JpaTest.java
@@ -18,7 +18,6 @@ package org.apache.camel.component.jpa;
import java.util.ArrayList;
import java.util.List;
-import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import jakarta.persistence.EntityManager;
@@ -41,6 +40,7 @@ import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
+import static org.awaitility.Awaitility.await;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -55,8 +55,7 @@ public class JpaTest {
protected EntityManager entityManager;
protected TransactionTemplate transactionTemplate;
protected Consumer consumer;
- protected Exchange receivedExchange;
- protected CountDownLatch latch = new CountDownLatch(1);
+ protected volatile Exchange receivedExchange;
protected String entityName = SendEmail.class.getName();
protected String queryText = "select o from " + entityName + " o";
@@ -80,20 +79,19 @@ public class JpaTest {
public void process(Exchange e) {
LOG.info("Received exchange: {}", e.getIn());
receivedExchange = e;
- // should have a EntityManager
- EntityManager entityManager =
e.getIn().getHeader(JpaConstants.ENTITY_MANAGER, EntityManager.class);
- assertNotNull(entityManager, "Should have a EntityManager as
header");
- latch.countDown();
}
});
consumer.start();
- assertTrue(latch.await(50, TimeUnit.SECONDS));
-
- assertNotNull(receivedExchange);
- SendEmail result = receivedExchange.getIn().getBody(SendEmail.class);
- assertNotNull(result, "Received a POJO");
- assertEquals("[email protected]", result.getAddress(), "address property");
+ await().atMost(10, TimeUnit.SECONDS).untilAsserted(() -> {
+ assertNotNull(receivedExchange);
+ // should have a EntityManager
+ EntityManager em =
receivedExchange.getIn().getHeader(JpaConstants.ENTITY_MANAGER,
EntityManager.class);
+ assertNotNull(em, "Should have a EntityManager as header");
+ SendEmail result =
receivedExchange.getIn().getBody(SendEmail.class);
+ assertNotNull(result, "Received a POJO");
+ assertEquals("[email protected]", result.getAddress(), "address
property");
+ });
}
@Test
diff --git
a/components/camel-jpa/src/test/java/org/apache/camel/component/jpa/JpaWithNamedQueryAndParametersTest.java
b/components/camel-jpa/src/test/java/org/apache/camel/component/jpa/JpaWithNamedQueryAndParametersTest.java
index 63766eb56e7d..800cb37b9f1d 100644
---
a/components/camel-jpa/src/test/java/org/apache/camel/component/jpa/JpaWithNamedQueryAndParametersTest.java
+++
b/components/camel-jpa/src/test/java/org/apache/camel/component/jpa/JpaWithNamedQueryAndParametersTest.java
@@ -19,7 +19,6 @@ package org.apache.camel.component.jpa;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import jakarta.persistence.EntityManager;
@@ -42,6 +41,7 @@ import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
+import static org.awaitility.Awaitility.await;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -56,8 +56,7 @@ public class JpaWithNamedQueryAndParametersTest {
protected EntityManager entityManager;
protected TransactionTemplate transactionTemplate;
protected Consumer consumer;
- protected Exchange receivedExchange;
- protected CountDownLatch latch = new CountDownLatch(1);
+ protected volatile Exchange receivedExchange;
protected String entityName = Customer.class.getName();
protected String queryText = "select o from " + entityName + " o where
o.name like 'Willem'";
@@ -99,14 +98,12 @@ public class JpaWithNamedQueryAndParametersTest {
public void process(Exchange e) {
LOG.info("Received exchange: {}", e.getIn());
receivedExchange = e;
- latch.countDown();
}
});
consumer.start();
- assertTrue(latch.await(10, TimeUnit.SECONDS));
-
- assertReceivedResult(receivedExchange);
+ await().atMost(10, TimeUnit.SECONDS)
+ .untilAsserted(() -> assertReceivedResult(receivedExchange));
JpaConsumer jpaConsumer = (JpaConsumer) consumer;
assertURIQueryOption(jpaConsumer);
diff --git
a/components/camel-jpa/src/test/java/org/apache/camel/component/jpa/JpaWithNamedQueryTest.java
b/components/camel-jpa/src/test/java/org/apache/camel/component/jpa/JpaWithNamedQueryTest.java
index 66410c85ad7b..c1ed8921e866 100644
---
a/components/camel-jpa/src/test/java/org/apache/camel/component/jpa/JpaWithNamedQueryTest.java
+++
b/components/camel-jpa/src/test/java/org/apache/camel/component/jpa/JpaWithNamedQueryTest.java
@@ -17,7 +17,6 @@
package org.apache.camel.component.jpa;
import java.util.List;
-import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import jakarta.persistence.EntityManager;
@@ -57,8 +56,7 @@ public class JpaWithNamedQueryTest {
protected EntityManager entityManager;
protected TransactionTemplate transactionTemplate;
protected Consumer consumer;
- protected Exchange receivedExchange;
- protected CountDownLatch latch = new CountDownLatch(1);
+ protected volatile Exchange receivedExchange;
protected String entityName = MultiSteps.class.getName();
protected String queryText = "select o from " + entityName + " o where
o.step = 1";
@@ -100,14 +98,12 @@ public class JpaWithNamedQueryTest {
LOG.info("Received exchange: {}", e.getIn());
// make defensive copy
receivedExchange = e.copy();
- latch.countDown();
}
});
consumer.start();
- assertTrue(latch.await(10, TimeUnit.SECONDS));
-
- assertReceivedResult(receivedExchange);
+ await().atMost(10, TimeUnit.SECONDS)
+ .untilAsserted(() -> assertReceivedResult(receivedExchange));
// lets now test that the database is updated.
// the consumer updates the row from within its own transaction, so we
poll until that
diff --git
a/components/camel-jpa/src/test/java/org/apache/camel/component/jpa/JpaWithNativeQueryTest.java
b/components/camel-jpa/src/test/java/org/apache/camel/component/jpa/JpaWithNativeQueryTest.java
index 4d10ac7e13be..200e0be9c95a 100644
---
a/components/camel-jpa/src/test/java/org/apache/camel/component/jpa/JpaWithNativeQueryTest.java
+++
b/components/camel-jpa/src/test/java/org/apache/camel/component/jpa/JpaWithNativeQueryTest.java
@@ -19,14 +19,11 @@ package org.apache.camel.component.jpa;
import org.apache.camel.Exchange;
import org.apache.camel.examples.MultiSteps;
import org.junit.jupiter.api.Timeout;
-import org.junit.jupiter.api.condition.DisabledIfSystemProperty;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
@Timeout(30)
-@DisabledIfSystemProperty(named = "ci.env.name", matches = ".*",
- disabledReason = "Apache CI is hanging on this test")
public class JpaWithNativeQueryTest extends JpaWithNamedQueryTest {
/**
diff --git
a/components/camel-jpa/src/test/java/org/apache/camel/component/jpa/JpaWithNativeQueryWithResultClassTest.java
b/components/camel-jpa/src/test/java/org/apache/camel/component/jpa/JpaWithNativeQueryWithResultClassTest.java
index 3060a94369ef..2c84c247df3b 100644
---
a/components/camel-jpa/src/test/java/org/apache/camel/component/jpa/JpaWithNativeQueryWithResultClassTest.java
+++
b/components/camel-jpa/src/test/java/org/apache/camel/component/jpa/JpaWithNativeQueryWithResultClassTest.java
@@ -18,13 +18,12 @@ package org.apache.camel.component.jpa;
import org.apache.camel.Exchange;
import org.apache.camel.examples.MultiSteps;
-import org.junit.jupiter.api.condition.DisabledIfSystemProperty;
+import org.junit.jupiter.api.Timeout;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
-@DisabledIfSystemProperty(named = "ci.env.name", matches = ".*",
- disabledReason = "Apache CI is hanging on this test")
+@Timeout(30)
public class JpaWithNativeQueryWithResultClassTest extends
JpaWithNamedQueryTest {
/**
diff --git
a/components/camel-jpa/src/test/java/org/apache/camel/component/jpa/JpaWithQueryTest.java
b/components/camel-jpa/src/test/java/org/apache/camel/component/jpa/JpaWithQueryTest.java
index 34274bedb4a9..5de363d72ecb 100644
---
a/components/camel-jpa/src/test/java/org/apache/camel/component/jpa/JpaWithQueryTest.java
+++
b/components/camel-jpa/src/test/java/org/apache/camel/component/jpa/JpaWithQueryTest.java
@@ -18,13 +18,10 @@ package org.apache.camel.component.jpa;
import org.apache.camel.examples.MultiSteps;
import org.junit.jupiter.api.Timeout;
-import org.junit.jupiter.api.condition.DisabledIfSystemProperty;
import static org.junit.jupiter.api.Assertions.assertEquals;
@Timeout(30)
-@DisabledIfSystemProperty(named = "ci.env.name", matches = ".*",
- disabledReason = "Apache CI is hanging on this test")
public class JpaWithQueryTest extends JpaWithNamedQueryTest {
@Override