Skip to content

Commit feab409

Browse files
gnodetclaude
andauthored
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 <noreply@anthropic.com>
1 parent aa5f99e commit feab409

6 files changed

Lines changed: 20 additions & 36 deletions

File tree

components/camel-jpa/src/test/java/org/apache/camel/component/jpa/JpaTest.java

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818

1919
import java.util.ArrayList;
2020
import java.util.List;
21-
import java.util.concurrent.CountDownLatch;
2221
import java.util.concurrent.TimeUnit;
2322

2423
import jakarta.persistence.EntityManager;
@@ -41,6 +40,7 @@
4140
import org.springframework.transaction.support.TransactionCallback;
4241
import org.springframework.transaction.support.TransactionTemplate;
4342

43+
import static org.awaitility.Awaitility.await;
4444
import static org.junit.jupiter.api.Assertions.assertEquals;
4545
import static org.junit.jupiter.api.Assertions.assertNotNull;
4646
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -55,8 +55,7 @@ public class JpaTest {
5555
protected EntityManager entityManager;
5656
protected TransactionTemplate transactionTemplate;
5757
protected Consumer consumer;
58-
protected Exchange receivedExchange;
59-
protected CountDownLatch latch = new CountDownLatch(1);
58+
protected volatile Exchange receivedExchange;
6059
protected String entityName = SendEmail.class.getName();
6160
protected String queryText = "select o from " + entityName + " o";
6261

@@ -80,20 +79,19 @@ public void process(Exchange exchange) {
8079
public void process(Exchange e) {
8180
LOG.info("Received exchange: {}", e.getIn());
8281
receivedExchange = e;
83-
// should have a EntityManager
84-
EntityManager entityManager = e.getIn().getHeader(JpaConstants.ENTITY_MANAGER, EntityManager.class);
85-
assertNotNull(entityManager, "Should have a EntityManager as header");
86-
latch.countDown();
8782
}
8883
});
8984
consumer.start();
9085

91-
assertTrue(latch.await(50, TimeUnit.SECONDS));
92-
93-
assertNotNull(receivedExchange);
94-
SendEmail result = receivedExchange.getIn().getBody(SendEmail.class);
95-
assertNotNull(result, "Received a POJO");
96-
assertEquals("foo@bar.com", result.getAddress(), "address property");
86+
await().atMost(10, TimeUnit.SECONDS).untilAsserted(() -> {
87+
assertNotNull(receivedExchange);
88+
// should have a EntityManager
89+
EntityManager em = receivedExchange.getIn().getHeader(JpaConstants.ENTITY_MANAGER, EntityManager.class);
90+
assertNotNull(em, "Should have a EntityManager as header");
91+
SendEmail result = receivedExchange.getIn().getBody(SendEmail.class);
92+
assertNotNull(result, "Received a POJO");
93+
assertEquals("foo@bar.com", result.getAddress(), "address property");
94+
});
9795
}
9896

9997
@Test

components/camel-jpa/src/test/java/org/apache/camel/component/jpa/JpaWithNamedQueryAndParametersTest.java

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
import java.util.HashMap;
2020
import java.util.List;
2121
import java.util.Map;
22-
import java.util.concurrent.CountDownLatch;
2322
import java.util.concurrent.TimeUnit;
2423

2524
import jakarta.persistence.EntityManager;
@@ -42,6 +41,7 @@
4241
import org.springframework.transaction.support.TransactionCallback;
4342
import org.springframework.transaction.support.TransactionTemplate;
4443

44+
import static org.awaitility.Awaitility.await;
4545
import static org.junit.jupiter.api.Assertions.assertEquals;
4646
import static org.junit.jupiter.api.Assertions.assertNotNull;
4747
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -56,8 +56,7 @@ public class JpaWithNamedQueryAndParametersTest {
5656
protected EntityManager entityManager;
5757
protected TransactionTemplate transactionTemplate;
5858
protected Consumer consumer;
59-
protected Exchange receivedExchange;
60-
protected CountDownLatch latch = new CountDownLatch(1);
59+
protected volatile Exchange receivedExchange;
6160
protected String entityName = Customer.class.getName();
6261
protected String queryText = "select o from " + entityName + " o where o.name like 'Willem'";
6362

@@ -99,14 +98,12 @@ public void process(Exchange exchange) {
9998
public void process(Exchange e) {
10099
LOG.info("Received exchange: {}", e.getIn());
101100
receivedExchange = e;
102-
latch.countDown();
103101
}
104102
});
105103
consumer.start();
106104

107-
assertTrue(latch.await(10, TimeUnit.SECONDS));
108-
109-
assertReceivedResult(receivedExchange);
105+
await().atMost(10, TimeUnit.SECONDS)
106+
.untilAsserted(() -> assertReceivedResult(receivedExchange));
110107

111108
JpaConsumer jpaConsumer = (JpaConsumer) consumer;
112109
assertURIQueryOption(jpaConsumer);

components/camel-jpa/src/test/java/org/apache/camel/component/jpa/JpaWithNamedQueryTest.java

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package org.apache.camel.component.jpa;
1818

1919
import java.util.List;
20-
import java.util.concurrent.CountDownLatch;
2120
import java.util.concurrent.TimeUnit;
2221

2322
import jakarta.persistence.EntityManager;
@@ -57,8 +56,7 @@ public class JpaWithNamedQueryTest {
5756
protected EntityManager entityManager;
5857
protected TransactionTemplate transactionTemplate;
5958
protected Consumer consumer;
60-
protected Exchange receivedExchange;
61-
protected CountDownLatch latch = new CountDownLatch(1);
59+
protected volatile Exchange receivedExchange;
6260
protected String entityName = MultiSteps.class.getName();
6361
protected String queryText = "select o from " + entityName + " o where o.step = 1";
6462

@@ -100,14 +98,12 @@ public void process(Exchange e) {
10098
LOG.info("Received exchange: {}", e.getIn());
10199
// make defensive copy
102100
receivedExchange = e.copy();
103-
latch.countDown();
104101
}
105102
});
106103
consumer.start();
107104

108-
assertTrue(latch.await(10, TimeUnit.SECONDS));
109-
110-
assertReceivedResult(receivedExchange);
105+
await().atMost(10, TimeUnit.SECONDS)
106+
.untilAsserted(() -> assertReceivedResult(receivedExchange));
111107

112108
// lets now test that the database is updated.
113109
// the consumer updates the row from within its own transaction, so we poll until that

components/camel-jpa/src/test/java/org/apache/camel/component/jpa/JpaWithNativeQueryTest.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,11 @@
1919
import org.apache.camel.Exchange;
2020
import org.apache.camel.examples.MultiSteps;
2121
import org.junit.jupiter.api.Timeout;
22-
import org.junit.jupiter.api.condition.DisabledIfSystemProperty;
2322

2423
import static org.junit.jupiter.api.Assertions.assertEquals;
2524
import static org.junit.jupiter.api.Assertions.assertNotNull;
2625

2726
@Timeout(30)
28-
@DisabledIfSystemProperty(named = "ci.env.name", matches = ".*",
29-
disabledReason = "Apache CI is hanging on this test")
3027
public class JpaWithNativeQueryTest extends JpaWithNamedQueryTest {
3128

3229
/**

components/camel-jpa/src/test/java/org/apache/camel/component/jpa/JpaWithNativeQueryWithResultClassTest.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,12 @@
1818

1919
import org.apache.camel.Exchange;
2020
import org.apache.camel.examples.MultiSteps;
21-
import org.junit.jupiter.api.condition.DisabledIfSystemProperty;
21+
import org.junit.jupiter.api.Timeout;
2222

2323
import static org.junit.jupiter.api.Assertions.assertEquals;
2424
import static org.junit.jupiter.api.Assertions.assertNotNull;
2525

26-
@DisabledIfSystemProperty(named = "ci.env.name", matches = ".*",
27-
disabledReason = "Apache CI is hanging on this test")
26+
@Timeout(30)
2827
public class JpaWithNativeQueryWithResultClassTest extends JpaWithNamedQueryTest {
2928

3029
/**

components/camel-jpa/src/test/java/org/apache/camel/component/jpa/JpaWithQueryTest.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,10 @@
1818

1919
import org.apache.camel.examples.MultiSteps;
2020
import org.junit.jupiter.api.Timeout;
21-
import org.junit.jupiter.api.condition.DisabledIfSystemProperty;
2221

2322
import static org.junit.jupiter.api.Assertions.assertEquals;
2423

2524
@Timeout(30)
26-
@DisabledIfSystemProperty(named = "ci.env.name", matches = ".*",
27-
disabledReason = "Apache CI is hanging on this test")
2825
public class JpaWithQueryTest extends JpaWithNamedQueryTest {
2926

3027
@Override

0 commit comments

Comments
 (0)