This is an automated email from the ASF dual-hosted git repository.
davsclaus 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 9029aebadecc CAMEL-19528: camel-jpa - replace Thread.sleep with
Awaitility in tests
9029aebadecc is described below
commit 9029aebadecc42f452dc76accd8d598d3005f1a5
Author: Rohit Jangid <[email protected]>
AuthorDate: Thu Jun 11 12:10:02 2026 +0530
CAMEL-19528: camel-jpa - replace Thread.sleep with Awaitility in tests
Migrate Thread.sleep() calls to Awaitility in camel-jpa tests for more
robust async assertions: poll database state with untilAsserted(),
handle transaction timing with ignoreExceptions(), and use
MockEndpoint.setAssertPeriod() for negative file-consumer assertions.
Closes #23928
---
components/camel-jpa/pom.xml | 6 ++
.../camel/component/jpa/AbstractJpaMethodTest.java | 14 ++--
.../camel/component/jpa/JpaWithNamedQueryTest.java | 74 +++++++++++-----------
.../jpa/FileConsumerJpaIdempotentTest.java | 11 ++--
4 files changed, 58 insertions(+), 47 deletions(-)
diff --git a/components/camel-jpa/pom.xml b/components/camel-jpa/pom.xml
index ae6dd5210b0e..75cfc96d1722 100644
--- a/components/camel-jpa/pom.xml
+++ b/components/camel-jpa/pom.xml
@@ -118,6 +118,12 @@
<version>${jakarta-transaction-api-version}</version>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.awaitility</groupId>
+ <artifactId>awaitility</artifactId>
+ <version>${awaitility-version}</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<profiles>
diff --git
a/components/camel-jpa/src/test/java/org/apache/camel/component/jpa/AbstractJpaMethodTest.java
b/components/camel-jpa/src/test/java/org/apache/camel/component/jpa/AbstractJpaMethodTest.java
index a07f51b11693..b06a6de7c3a5 100644
---
a/components/camel-jpa/src/test/java/org/apache/camel/component/jpa/AbstractJpaMethodTest.java
+++
b/components/camel-jpa/src/test/java/org/apache/camel/component/jpa/AbstractJpaMethodTest.java
@@ -29,6 +29,7 @@ import org.apache.camel.examples.Address;
import org.apache.camel.examples.Customer;
import org.junit.jupiter.api.Test;
+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;
@@ -115,7 +116,12 @@ public abstract class AbstractJpaMethodTest extends
AbstractJpaMethodSupport {
assertTrue(latch.await(50, TimeUnit.SECONDS));
consumer.stop();
- Thread.sleep(1000);
+
+ // wait for the consumer to delete the entities once done, so the
database is empty
+ await().atMost(10, TimeUnit.SECONDS).untilAsserted(() -> {
+ assertEntitiesInDatabase(0, Customer.class.getName());
+ assertEntitiesInDatabase(0, Address.class.getName());
+ });
assertNotNull(receivedCustomer);
assertEquals(customer.getName(), receivedCustomer.getName());
@@ -123,12 +129,6 @@ public abstract class AbstractJpaMethodTest extends
AbstractJpaMethodSupport {
assertEquals(customer.getAddress().getAddressLine1(),
receivedCustomer.getAddress().getAddressLine1());
assertEquals(customer.getAddress().getAddressLine2(),
receivedCustomer.getAddress().getAddressLine2());
assertEquals(customer.getAddress().getId(),
receivedCustomer.getAddress().getId());
-
- // give a bit time for consumer to delete after done
- Thread.sleep(1000);
-
- assertEntitiesInDatabase(0, Customer.class.getName());
- assertEntitiesInDatabase(0, Address.class.getName());
}
}
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 b9f256243faa..66410c85ad7b 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
@@ -41,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;
@@ -108,43 +109,44 @@ public class JpaWithNamedQueryTest {
assertReceivedResult(receivedExchange);
- // lets now test that the database is updated
- // we need to sleep as we will be invoked from inside the transaction!
- // org.apache.openjpa.persistence.InvalidStateException: This
operation cannot be performed while a Transaction is active.
- Thread.sleep(2000);
-
- transactionTemplate.execute(new TransactionCallback<Object>() {
- public Object doInTransaction(TransactionStatus status) {
- // make use of the EntityManager having the relevant
persistence-context
- EntityManager entityManager2
- =
receivedExchange.getIn().getHeader(JpaConstants.ENTITY_MANAGER,
EntityManager.class);
- if (!entityManager2.isOpen()) {
- entityManager2 =
endpoint.getEntityManagerFactory().createEntityManager();
- }
- entityManager2.joinTransaction();
-
- // now lets assert that there are still 2 entities left
- List<?> rows = entityManager2.createQuery("select x from
MultiSteps x").getResultList();
- assertEquals(2, rows.size(), "Number of entities: " + rows);
-
- int counter = 1;
- for (Object rowObj : rows) {
- assertTrue(rowObj instanceof MultiSteps, "Rows are not
instances of MultiSteps");
- final MultiSteps row = (MultiSteps) rowObj;
- LOG.info("entity: {} = {}", counter++, row);
-
- if (row.getAddress().equals("[email protected]")) {
- LOG.info("Found updated row: {}", row);
- assertEquals(getUpdatedStepValue(), row.getStep(),
"Updated row step for: " + row);
- } else {
- // dummy row
- assertEquals(4, row.getStep(), "dummy row step for: "
+ row);
- assertEquals("cheese", row.getAddress(), "Not the
expected row: " + row);
+ // lets now test that the database is updated.
+ // the consumer updates the row from within its own transaction, so we
poll until that
+ // transaction has committed - we cannot read it while that
transaction is still active
+ // (org.apache.openjpa.persistence.InvalidStateException: This
operation cannot be performed
+ // while a Transaction is active).
+ await().atMost(10, TimeUnit.SECONDS).ignoreExceptions().untilAsserted(
+ () -> transactionTemplate.execute(new
TransactionCallback<Object>() {
+ public Object doInTransaction(TransactionStatus status) {
+ // make use of the EntityManager having the relevant
persistence-context
+ EntityManager entityManager2
+ =
receivedExchange.getIn().getHeader(JpaConstants.ENTITY_MANAGER,
EntityManager.class);
+ if (!entityManager2.isOpen()) {
+ entityManager2 =
endpoint.getEntityManagerFactory().createEntityManager();
+ }
+ entityManager2.joinTransaction();
+
+ // now lets assert that there are still 2 entities left
+ List<?> rows = entityManager2.createQuery("select x
from MultiSteps x").getResultList();
+ assertEquals(2, rows.size(), "Number of entities: " +
rows);
+
+ int counter = 1;
+ for (Object rowObj : rows) {
+ assertTrue(rowObj instanceof MultiSteps, "Rows are
not instances of MultiSteps");
+ final MultiSteps row = (MultiSteps) rowObj;
+ LOG.info("entity: {} = {}", counter++, row);
+
+ if (row.getAddress().equals("[email protected]")) {
+ LOG.info("Found updated row: {}", row);
+ assertEquals(getUpdatedStepValue(),
row.getStep(), "Updated row step for: " + row);
+ } else {
+ // dummy row
+ assertEquals(4, row.getStep(), "dummy row step
for: " + row);
+ assertEquals("cheese", row.getAddress(), "Not
the expected row: " + row);
+ }
+ }
+ return null;
}
- }
- return null;
- }
- });
+ }));
JpaConsumer jpaConsumer = (JpaConsumer) consumer;
assertURIQueryOption(jpaConsumer);
diff --git
a/components/camel-jpa/src/test/java/org/apache/camel/processor/jpa/FileConsumerJpaIdempotentTest.java
b/components/camel-jpa/src/test/java/org/apache/camel/processor/jpa/FileConsumerJpaIdempotentTest.java
index f9c013908760..dc21194e9457 100644
---
a/components/camel-jpa/src/test/java/org/apache/camel/processor/jpa/FileConsumerJpaIdempotentTest.java
+++
b/components/camel-jpa/src/test/java/org/apache/camel/processor/jpa/FileConsumerJpaIdempotentTest.java
@@ -18,6 +18,7 @@ package org.apache.camel.processor.jpa;
import java.io.File;
import java.util.List;
+import java.util.concurrent.TimeUnit;
import jakarta.persistence.Query;
@@ -31,6 +32,7 @@ import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import static org.apache.camel.test.junit6.TestSupport.deleteDirectory;
+import static org.awaitility.Awaitility.await;
/**
* Unit test using jpa idempotent repository for the file consumer.
@@ -90,19 +92,20 @@ public class FileConsumerJpaIdempotentTest extends
AbstractJpaTest {
MockEndpoint.assertIsSatisfied(context);
- Thread.sleep(1000);
+ // wait for the consumed file to be moved to the done directory
+ File file = new File("target/idempotent/done/report.txt");
+ await().atMost(5, TimeUnit.SECONDS).until(file::exists);
// reset mock and set new expectations
mock.reset();
mock.expectedMessageCount(0);
// move file back
- File file = new File("target/idempotent/done/report.txt");
File renamed = new File("target/idempotent/report.txt");
file.renameTo(renamed);
- // should NOT consume the file again, let 2 secs pass to let the
consumer try to consume it but it should not
- Thread.sleep(2000);
+ // should NOT consume the file again, assert for 2 secs that the
consumer does not consume it again
+ mock.setAssertPeriod(2000);
MockEndpoint.assertIsSatisfied(context);
}