This is an automated email from the ASF dual-hosted git repository.
Croway 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 efec0169e148 CAMEL-25440 / CAMEL-25880: Stabilize port binding and
speed up camel-cxf tests
efec0169e148 is described below
commit efec0169e14820e94e116442721e43c8b4eaacae
Author: Aurélien Pupier <[email protected]>
AuthorDate: Tue Oct 20 15:31:46 2026 +0200
CAMEL-25440 / CAMEL-25880: Stabilize port binding and speed up camel-cxf
tests
- Fix port collision and Undertow flakiness (CAMEL-25440):
* Removed 'org.apache.cxf.transports.http_undertow.DontClosePort=true' in
CXFTestSupport.
Previously, Undertow server engines retained open TCP listeners across
tests, leaving
lingering listeners on shared ports and causing 'Address already in
use' BindExceptions.
* Replaced deprecated getNextRandomAvailable() range probing with
AvailablePortFinder.find()
to leverage OS kernel-assigned ephemeral ports (port 0) and register
port reservations.
* Migrated 'Camel1145RouteTest' away from the deprecated
'AvailablePortFinder.getSpecificPort'
API to use CXFTestSupport's dynamic port allocation.
* Improved 'CxfCustomerStartStopTest' to use 'System.clearProperty' for
cleaner property
restoring of 'DontClosePort'.
- Parallelize test execution and reduce build time (CAMEL-25880):
* Added <camel.surefire.forkCount>0.5C</camel.surefire.forkCount> to
components/camel-cxf/pom.xml.
* Because reuseForks=false was configured in camel-cxf-spring-soap and
camel-cxf-spring-rest,
forkCount=1 sequentially created and destroyed a JVM per test class
(~50 test classes in
camel-cxf-spring-soap), adding substantial JVM startup overhead.
* Parallelizing across forks eliminates sequential JVM startup
bottlenecks while clean Undertow
socket teardown prevents cross-fork port collisions.
Benchmark results for components/camel-cxf (all tests passing):
- With -T1C:
* Baseline: 03:57 min (camel-cxf-spring-soap: 03:18 min,
camel-cxf-spring-rest: 59.4s)
* Optimized: 01:46 min (camel-cxf-spring-soap: 01:04 min,
camel-cxf-spring-rest: 29.1s) -> 2.24x speedup
- Without -T1C:
* Baseline: > 05:00 min
* Optimized: 02:06 min -> >2.3x speedup
Co-authored-by: IBM Bob 2.2.1
Signed-off-by: Aurélien Pupier <[email protected]>
---
.../camel/component/cxf/common/CXFTestSupport.java | 54 +++++++++++-----------
.../camel/component/cxf/Camel1145RouteTest.java | 10 +---
.../component/cxf/CxfCustomerStartStopTest.java | 14 ++++--
.../camel/component/cxf/RouteBuilderCxfTracer.java | 3 +-
components/camel-cxf/pom.xml | 4 ++
5 files changed, 44 insertions(+), 41 deletions(-)
diff --git
a/components/camel-cxf/camel-cxf-common/src/test/java/org/apache/camel/component/cxf/common/CXFTestSupport.java
b/components/camel-cxf/camel-cxf-common/src/test/java/org/apache/camel/component/cxf/common/CXFTestSupport.java
index e16b51e88b87..64dc441ed98e 100644
---
a/components/camel-cxf/camel-cxf-common/src/test/java/org/apache/camel/component/cxf/common/CXFTestSupport.java
+++
b/components/camel-cxf/camel-cxf-common/src/test/java/org/apache/camel/component/cxf/common/CXFTestSupport.java
@@ -19,72 +19,70 @@ package org.apache.camel.component.cxf.common;
import org.apache.camel.test.AvailablePortFinder;
/**
- * For test cases that use unique contexts, they can share the ports which
will make things a bit faster as ports aren't
- * opened and closed all the time.
+ * Provides pre-allocated port numbers as system properties for test cases and
Spring XML contexts.
*/
public final class CXFTestSupport {
- static final int PORT1 = AvailablePortFinder.getNextRandomAvailable();
- static final int PORT2 = AvailablePortFinder.getNextRandomAvailable();
- static final int PORT3 = AvailablePortFinder.getNextRandomAvailable();
- static final int PORT4 = AvailablePortFinder.getNextRandomAvailable();
- static final int PORT5 = AvailablePortFinder.getNextRandomAvailable();
- static final int PORT6 = AvailablePortFinder.getNextRandomAvailable();
- static final int PORT7 = AvailablePortFinder.getNextRandomAvailable();
- static final int SSL_PORT = AvailablePortFinder.getNextRandomAvailable();
+ static final AvailablePortFinder.Port PORT1 = AvailablePortFinder.find();
+ static final AvailablePortFinder.Port PORT2 = AvailablePortFinder.find();
+ static final AvailablePortFinder.Port PORT3 = AvailablePortFinder.find();
+ static final AvailablePortFinder.Port PORT4 = AvailablePortFinder.find();
+ static final AvailablePortFinder.Port PORT5 = AvailablePortFinder.find();
+ static final AvailablePortFinder.Port PORT6 = AvailablePortFinder.find();
+ static final AvailablePortFinder.Port PORT7 = AvailablePortFinder.find();
+ static final AvailablePortFinder.Port SSL_PORT =
AvailablePortFinder.find();
static {
//set them as system properties so Spring can use the property
placeholder
//things to set them into the URL's in the spring contexts
- System.setProperty("CXFTestSupport.port1", Integer.toString(PORT1));
- System.setProperty("CXFTestSupport.port2", Integer.toString(PORT2));
- System.setProperty("CXFTestSupport.port3", Integer.toString(PORT3));
- System.setProperty("CXFTestSupport.port4", Integer.toString(PORT4));
- System.setProperty("CXFTestSupport.port5", Integer.toString(PORT5));
- System.setProperty("CXFTestSupport.port6", Integer.toString(PORT6));
- System.setProperty("CXFTestSupport.port7", Integer.toString(PORT7));
- System.setProperty("CXFTestSupport.sslPort",
Integer.toString(SSL_PORT));
-
System.setProperty("org.apache.cxf.transports.http_undertow.DontClosePort",
"true");
+ System.setProperty("CXFTestSupport.port1", PORT1.toString());
+ System.setProperty("CXFTestSupport.port2", PORT2.toString());
+ System.setProperty("CXFTestSupport.port3", PORT3.toString());
+ System.setProperty("CXFTestSupport.port4", PORT4.toString());
+ System.setProperty("CXFTestSupport.port5", PORT5.toString());
+ System.setProperty("CXFTestSupport.port6", PORT6.toString());
+ System.setProperty("CXFTestSupport.port7", PORT7.toString());
+ System.setProperty("CXFTestSupport.sslPort", SSL_PORT.toString());
}
private CXFTestSupport() {
}
public static int getPort(String name) {
- int port = AvailablePortFinder.getNextRandomAvailable();
+ int port = AvailablePortFinder.find().getPort();
System.setProperty(name, Integer.toString(port));
return port;
}
public static int getPort1() {
- return PORT1;
+ return PORT1.getPort();
}
public static int getPort2() {
- return PORT2;
+ return PORT2.getPort();
}
public static int getPort3() {
- return PORT3;
+ return PORT3.getPort();
}
public static int getPort4() {
- return PORT4;
+ return PORT4.getPort();
}
public static int getPort5() {
- return PORT5;
+ return PORT5.getPort();
}
public static int getPort6() {
- return PORT6;
+ return PORT6.getPort();
}
public static int getPort7() {
- return PORT7;
+ return PORT7.getPort();
}
public static int getSslPort() {
- return SSL_PORT;
+ return SSL_PORT.getPort();
}
}
diff --git
a/components/camel-cxf/camel-cxf-spring-soap/src/test/java/org/apache/camel/component/cxf/Camel1145RouteTest.java
b/components/camel-cxf/camel-cxf-spring-soap/src/test/java/org/apache/camel/component/cxf/Camel1145RouteTest.java
index 0e49e897ba42..b66f51aea745 100644
---
a/components/camel-cxf/camel-cxf-spring-soap/src/test/java/org/apache/camel/component/cxf/Camel1145RouteTest.java
+++
b/components/camel-cxf/camel-cxf-spring-soap/src/test/java/org/apache/camel/component/cxf/Camel1145RouteTest.java
@@ -20,11 +20,11 @@ import java.net.URL;
import javax.xml.namespace.QName;
+import org.apache.camel.component.cxf.common.CXFTestSupport;
import org.apache.camel.non_wrapper.Person;
import org.apache.camel.non_wrapper.PersonService;
import org.apache.camel.non_wrapper.types.GetPerson;
import org.apache.camel.non_wrapper.types.GetPersonResponse;
-import org.apache.camel.test.AvailablePortFinder;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@@ -32,21 +32,15 @@ import
org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assumptions.assumeTrue;
@ContextConfiguration(locations = {
"/org/apache/camel/component/cxf/context-camel-1145.xml" })
@ExtendWith(SpringExtension.class)
public class Camel1145RouteTest {
private static int port;
- public static int portNotAvailableHandler(boolean allocated) {
- assumeTrue(allocated);
- return -1;
- }
-
@BeforeAll
public static void getPort() {
- port = AvailablePortFinder.getSpecificPort(9000, false,
Camel1145RouteTest::portNotAvailableHandler);
+ port = CXFTestSupport.getPort1();
}
@Test
diff --git
a/components/camel-cxf/camel-cxf-spring-soap/src/test/java/org/apache/camel/component/cxf/CxfCustomerStartStopTest.java
b/components/camel-cxf/camel-cxf-spring-soap/src/test/java/org/apache/camel/component/cxf/CxfCustomerStartStopTest.java
index a582235b3979..6ecd6f3fddf8 100644
---
a/components/camel-cxf/camel-cxf-spring-soap/src/test/java/org/apache/camel/component/cxf/CxfCustomerStartStopTest.java
+++
b/components/camel-cxf/camel-cxf-spring-soap/src/test/java/org/apache/camel/component/cxf/CxfCustomerStartStopTest.java
@@ -58,8 +58,11 @@ public class CxfCustomerStartStopTest {
// Need to call the bus shutdown ourselves.
String orig =
System.setProperty("org.apache.cxf.transports.http_undertow.DontClosePort",
"false");
bus.shutdown(true);
-
System.setProperty("org.apache.cxf.transports.http_undertow.DontClosePort",
- orig == null ? "true" : "false");
+ if (orig == null) {
+
System.clearProperty("org.apache.cxf.transports.http_undertow.DontClosePort");
+ } else {
+
System.setProperty("org.apache.cxf.transports.http_undertow.DontClosePort",
orig);
+ }
engine = factory.retrieveUndertowHTTPServerEngine(PORT1);
assertNull(engine, "Undertow engine should be removed");
}
@@ -74,8 +77,11 @@ public class CxfCustomerStartStopTest {
// Bus shutdown will be called when the application context is closed.
String orig =
System.setProperty("org.apache.cxf.transports.http_undertow.DontClosePort",
"false");
IOHelper.close(applicationContext);
-
System.setProperty("org.apache.cxf.transports.http_undertow.DontClosePort",
- orig == null ? "true" : "false");
+ if (orig == null) {
+
System.clearProperty("org.apache.cxf.transports.http_undertow.DontClosePort");
+ } else {
+
System.setProperty("org.apache.cxf.transports.http_undertow.DontClosePort",
orig);
+ }
UndertowHTTPServerEngineFactory factory =
bus.getExtension(UndertowHTTPServerEngineFactory.class);
// test if the port is still used
UndertowHTTPServerEngine engine =
factory.retrieveUndertowHTTPServerEngine(PORT2);
diff --git
a/components/camel-cxf/camel-cxf-spring-soap/src/test/java/org/apache/camel/component/cxf/RouteBuilderCxfTracer.java
b/components/camel-cxf/camel-cxf-spring-soap/src/test/java/org/apache/camel/component/cxf/RouteBuilderCxfTracer.java
index 52b823c37642..6c1be6ae5375 100644
---
a/components/camel-cxf/camel-cxf-spring-soap/src/test/java/org/apache/camel/component/cxf/RouteBuilderCxfTracer.java
+++
b/components/camel-cxf/camel-cxf-spring-soap/src/test/java/org/apache/camel/component/cxf/RouteBuilderCxfTracer.java
@@ -19,6 +19,7 @@ package org.apache.camel.component.cxf;
import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.cxf.common.CXFTestSupport;
import org.apache.camel.non_wrapper.types.GetPerson;
import org.apache.camel.non_wrapper.types.GetPersonResponse;
import org.apache.cxf.message.MessageContentsList;
@@ -26,7 +27,7 @@ import org.apache.cxf.message.MessageContentsList;
public class RouteBuilderCxfTracer extends RouteBuilder {
@Override
public void configure() throws Exception {
- from("cxf:http://localhost:9000/PersonService/"
+ from("cxf:http://localhost:" + CXFTestSupport.getPort1() +
"/PersonService/"
+ "?serviceClass=org.apache.camel.non_wrapper.Person"
+
"&serviceName={http://camel.apache.org/non-wrapper}PersonService"
+ "&portName={http://camel.apache.org/non-wrapper}soap"
diff --git a/components/camel-cxf/pom.xml b/components/camel-cxf/pom.xml
index 03816ee74723..369933a0f7e9 100644
--- a/components/camel-cxf/pom.xml
+++ b/components/camel-cxf/pom.xml
@@ -32,6 +32,10 @@
<name>Camel :: CXF :: Parent</name>
<description>Camel CXF parent</description>
+ <properties>
+ <camel.surefire.forkCount>0.5C</camel.surefire.forkCount>
+ </properties>
+
<modules>
<module>camel-cxf-common</module>
<module>camel-cxf-transport</module>