This is an automated email from the ASF dual-hosted git repository.
apupier 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 0fc8fcaa8b1c CAMEL-26628: camel-undertow - Fix flaky
UndertowHttpsSpringTest (Address already in use)
0fc8fcaa8b1c is described below
commit 0fc8fcaa8b1c1f2246c0340e4dae1ed0df11f2e5
Author: Aurélien Pupier <[email protected]>
AuthorDate: Thu Nov 5 11:18:56 2026 +0100
CAMEL-26628: camel-undertow - Fix flaky UndertowHttpsSpringTest (Address
already in use)
UndertowHttpsSpringTest (and UndertowHandlersSpringTest, which uses the same
pattern) obtained its port in the Spring XML through the deprecated
AvailablePortFinder.getNextAvailable(). That method releases the port as
soon
as it returns, so the port can be taken by another process before Undertow
binds to it, which fails the context startup with
"java.net.BindException: Address already in use".
The rerun of the failed test then fails with a different error,
"ApplicationContext failure threshold (1) exceeded", because since Spring
6.1
a context that failed to load is not loaded again by default. As a result
the
rerun could never recover from the port collision.
Changes:
- SpringTest.xml / HandlersSpringTest.xml: create the dynaPort bean with
AvailablePortFinder.find() (non deprecated API, port is also registered so
it is not handed out twice in the same JVM) and release it on context
shutdown with destroy-method="close". The endpoint URIs use
#{dynaPort.port}.
- UndertowHttpsSpringTest / UndertowHandlersSpringTest: inject the
AvailablePortFinder.Port bean instead of an Integer.
- Add src/test/resources/spring.properties with
spring.test.context.failure.threshold=3 so that a failed
ApplicationContext
load can be retried by the surefire reruns (rerunFailingTestsCount=2). The
context is then created again from scratch, including a new port.
Verified that the full camel-undertow test suite passes (293 tests, 0
failures, 0 errors).
Co-authored-by: IBM Bob 2.2.1
Signed-off-by: Aurélien Pupier <[email protected]>
---
.../undertow/UndertowHandlersSpringTest.java | 13 +++++--------
.../component/undertow/UndertowHttpsSpringTest.java | 12 +++++-------
.../src/test/resources/HandlersSpringTest.xml | 11 ++---------
.../src/test/resources/SpringTest.xml | 11 ++---------
.../src/test/resources/spring.properties | 21 +++++++++++++++++++++
5 files changed, 35 insertions(+), 33 deletions(-)
diff --git
a/components/camel-undertow/src/test/java/org/apache/camel/component/undertow/UndertowHandlersSpringTest.java
b/components/camel-undertow/src/test/java/org/apache/camel/component/undertow/UndertowHandlersSpringTest.java
index e49a2fcab0e4..cbc1b7ac8ba9 100644
---
a/components/camel-undertow/src/test/java/org/apache/camel/component/undertow/UndertowHandlersSpringTest.java
+++
b/components/camel-undertow/src/test/java/org/apache/camel/component/undertow/UndertowHandlersSpringTest.java
@@ -26,6 +26,7 @@ import org.apache.camel.Produce;
import org.apache.camel.ProducerTemplate;
import org.apache.camel.component.mock.MockEndpoint;
import org.apache.camel.http.base.HttpOperationFailedException;
+import org.apache.camel.test.AvailablePortFinder;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
@@ -40,7 +41,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
@ContextConfiguration(locations = { "/HandlersSpringTest.xml" })
public class UndertowHandlersSpringTest {
- private Integer port;
+ private AvailablePortFinder.Port port;
@Produce
private ProducerTemplate template;
@@ -64,7 +65,7 @@ public class UndertowHandlersSpringTest {
mockEndpoint.expectedBodiesReceived("Hello World");
// username:password is guest:secret
String auth = "Basic Z3Vlc3Q6c2VjcmV0";
- String out =
template.requestBodyAndHeader("undertow:http://localhost:" + port + "/spring",
"Hello World",
+ String out =
template.requestBodyAndHeader("undertow:http://localhost:" + port.getPort() +
"/spring", "Hello World",
"Authorization", auth, String.class);
assertEquals("Bye World", out);
@@ -77,19 +78,15 @@ public class UndertowHandlersSpringTest {
// username:password is guest:secret
String auth = "Basic Z3Vlc3Q6c2Vjc";
CamelExecutionException e =
assertThrows(CamelExecutionException.class, () -> {
- String out =
template.requestBodyAndHeader("undertow:http://localhost:" + port + "/spring",
"Hello World",
+ String out =
template.requestBodyAndHeader("undertow:http://localhost:" + port.getPort() +
"/spring", "Hello World",
"Authorization", auth, String.class);
});
HttpOperationFailedException cause = (HttpOperationFailedException)
e.getCause();
assertEquals(401, cause.getStatusCode());
}
- public Integer getPort() {
- return port;
- }
-
@Resource(name = "dynaPort")
- public void setPort(Integer port) {
+ public void setPort(AvailablePortFinder.Port port) {
this.port = port;
}
diff --git
a/components/camel-undertow/src/test/java/org/apache/camel/component/undertow/UndertowHttpsSpringTest.java
b/components/camel-undertow/src/test/java/org/apache/camel/component/undertow/UndertowHttpsSpringTest.java
index 47d4e876e8c6..81f0e05b9aed 100644
---
a/components/camel-undertow/src/test/java/org/apache/camel/component/undertow/UndertowHttpsSpringTest.java
+++
b/components/camel-undertow/src/test/java/org/apache/camel/component/undertow/UndertowHttpsSpringTest.java
@@ -24,6 +24,7 @@ import org.apache.camel.EndpointInject;
import org.apache.camel.Produce;
import org.apache.camel.ProducerTemplate;
import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.test.AvailablePortFinder;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
@@ -37,7 +38,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
@ContextConfiguration(locations = { "/SpringTest.xml" })
public class UndertowHttpsSpringTest {
- private Integer port;
+ private AvailablePortFinder.Port port;
@Produce
private ProducerTemplate template;
@@ -60,19 +61,16 @@ public class UndertowHttpsSpringTest {
public void testSSLConsumer() throws Exception {
mockEndpoint.expectedBodiesReceived("Hello World");
- String out = template.requestBody("undertow:https://localhost:" + port
+ "/spring?sslContextParameters=#sslClient",
+ String out = template.requestBody(
+ "undertow:https://localhost:" + port.getPort() +
"/spring?sslContextParameters=#sslClient",
"Hello World", String.class);
assertEquals("Bye World", out);
mockEndpoint.assertIsSatisfied();
}
- public Integer getPort() {
- return port;
- }
-
@Resource(name = "dynaPort")
- public void setPort(Integer port) {
+ public void setPort(AvailablePortFinder.Port port) {
this.port = port;
}
diff --git
a/components/camel-undertow/src/test/resources/HandlersSpringTest.xml
b/components/camel-undertow/src/test/resources/HandlersSpringTest.xml
index d44434ad4293..16e5aaa473fa 100644
--- a/components/camel-undertow/src/test/resources/HandlersSpringTest.xml
+++ b/components/camel-undertow/src/test/resources/HandlersSpringTest.xml
@@ -36,19 +36,12 @@
<camel:sslContextParameters id="sslClient" />
- <bean id="dynaPort"
class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
- <property name="targetClass">
- <value>org.apache.camel.test.AvailablePortFinder</value>
- </property>
- <property name="targetMethod">
- <value>getNextAvailable</value>
- </property>
- </bean>
+ <bean id="dynaPort" class="org.apache.camel.test.AvailablePortFinder"
factory-method="find" destroy-method="close"/>
<bean id="myHandler"
class="org.apache.camel.component.undertow.UndertowBasicAuthHandler"/>
<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
- <endpoint id="input"
uri="undertow:http://localhost:#{dynaPort}/spring?handlers=#myHandler"/>
+ <endpoint id="input"
uri="undertow:http://localhost:#{dynaPort.port}/spring?handlers=#myHandler"/>
<route>
<from uri="ref:input"/>
diff --git a/components/camel-undertow/src/test/resources/SpringTest.xml
b/components/camel-undertow/src/test/resources/SpringTest.xml
index 673045471688..c282eba41ff9 100644
--- a/components/camel-undertow/src/test/resources/SpringTest.xml
+++ b/components/camel-undertow/src/test/resources/SpringTest.xml
@@ -36,19 +36,12 @@
<camel:sslContextParameters id="sslClient" />
- <bean id="dynaPort"
class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
- <property name="targetClass">
- <value>org.apache.camel.test.AvailablePortFinder</value>
- </property>
- <property name="targetMethod">
- <value>getNextAvailable</value>
- </property>
- </bean>
+ <bean id="dynaPort" class="org.apache.camel.test.AvailablePortFinder"
factory-method="find" destroy-method="close"/>
<bean id="accessLogReceiver"
class="io.undertow.server.handlers.accesslog.JBossLoggingAccessLogReceiver"/>
<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
- <endpoint id="input"
uri="undertow:https://localhost:#{dynaPort}/spring?sslContextParameters=#sslContextParameters&accessLog=true&accessLogReceiver=#accessLogReceiver"/>
+ <endpoint id="input"
uri="undertow:https://localhost:#{dynaPort.port}/spring?sslContextParameters=#sslContextParameters&accessLog=true&accessLogReceiver=#accessLogReceiver"/>
<route>
<from uri="ref:input"/>
diff --git a/components/camel-undertow/src/test/resources/spring.properties
b/components/camel-undertow/src/test/resources/spring.properties
new file mode 100644
index 000000000000..01a190ff7407
--- /dev/null
+++ b/components/camel-undertow/src/test/resources/spring.properties
@@ -0,0 +1,21 @@
+## ---------------------------------------------------------------------------
+## Licensed to the Apache Software Foundation (ASF) under one or more
+## contributor license agreements. See the NOTICE file distributed with
+## this work for additional information regarding copyright ownership.
+## The ASF licenses this file to You under the Apache License, Version 2.0
+## (the "License"); you may not use this file except in compliance with
+## the License. You may obtain a copy of the License at
+##
+## http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+## ---------------------------------------------------------------------------
+
+# By default Spring refuses to reload an ApplicationContext after its first
load failure.
+# The Spring tests pick a free port when the context is created, which can
occasionally collide with
+# another process (BindException), so allow the context to be reloaded (with a
new port) on test reruns.
+spring.test.context.failure.threshold=3