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

commit 32314c185ee651f102dc10327426198b269a7da5
Author: Urmila Unni <[email protected]>
AuthorDate: Mon Oct 5 11:41:33 2026 +0530

    CAMEL-24762: camel-coap - Fix flaky CoAPComponentTLSTest
    
    Pick test ports that are free for UDP as well as TCP, as the CoAP servers 
bind UDP sockets.
    
    Co-authored-by: Claude <[email protected]>
---
 .../camel/coap/CoAPComponentTLSTestBase.java       | 16 +++++-----
 .../camel/coap/CoAPRestComponentTestBase.java      |  2 +-
 .../org/apache/camel/coap/CoAPTestSupport.java     | 36 +++++++++++++++++++++-
 3 files changed, 44 insertions(+), 10 deletions(-)

diff --git 
a/components/camel-coap/src/test/java/org/apache/camel/coap/CoAPComponentTLSTestBase.java
 
b/components/camel-coap/src/test/java/org/apache/camel/coap/CoAPComponentTLSTestBase.java
index 17de5e952920..64fa7d3e3fb9 100644
--- 
a/components/camel-coap/src/test/java/org/apache/camel/coap/CoAPComponentTLSTestBase.java
+++ 
b/components/camel-coap/src/test/java/org/apache/camel/coap/CoAPComponentTLSTestBase.java
@@ -52,21 +52,21 @@ import org.junit.jupiter.params.provider.ValueSource;
 abstract class CoAPComponentTLSTestBase extends CamelTestSupport {
 
     @RegisterExtension
-    static AvailablePortFinder.Port PORT = AvailablePortFinder.find();
+    static AvailablePortFinder.Port PORT = CoAPTestSupport.findUdpPort();
     @RegisterExtension
-    static AvailablePortFinder.Port PORT2 = AvailablePortFinder.find();
+    static AvailablePortFinder.Port PORT2 = CoAPTestSupport.findUdpPort();
     @RegisterExtension
-    static AvailablePortFinder.Port PORT3 = AvailablePortFinder.find();
+    static AvailablePortFinder.Port PORT3 = CoAPTestSupport.findUdpPort();
     @RegisterExtension
-    static AvailablePortFinder.Port PORT4 = AvailablePortFinder.find();
+    static AvailablePortFinder.Port PORT4 = CoAPTestSupport.findUdpPort();
     @RegisterExtension
-    static AvailablePortFinder.Port PORT5 = AvailablePortFinder.find();
+    static AvailablePortFinder.Port PORT5 = CoAPTestSupport.findUdpPort();
     @RegisterExtension
-    static AvailablePortFinder.Port PORT6 = AvailablePortFinder.find();
+    static AvailablePortFinder.Port PORT6 = CoAPTestSupport.findUdpPort();
     @RegisterExtension
-    static AvailablePortFinder.Port PORT7 = AvailablePortFinder.find();
+    static AvailablePortFinder.Port PORT7 = CoAPTestSupport.findUdpPort();
     @RegisterExtension
-    static AvailablePortFinder.Port PORT8 = AvailablePortFinder.find();
+    static AvailablePortFinder.Port PORT8 = CoAPTestSupport.findUdpPort();
 
     @ParameterizedTest
     @ValueSource(strings = { "direct:start", "direct:selfsigned", 
/*"direct:clientauth",*/ "direct:ciphersuites" })
diff --git 
a/components/camel-coap/src/test/java/org/apache/camel/coap/CoAPRestComponentTestBase.java
 
b/components/camel-coap/src/test/java/org/apache/camel/coap/CoAPRestComponentTestBase.java
index 8e2b22c3b968..47565e487de5 100644
--- 
a/components/camel-coap/src/test/java/org/apache/camel/coap/CoAPRestComponentTestBase.java
+++ 
b/components/camel-coap/src/test/java/org/apache/camel/coap/CoAPRestComponentTestBase.java
@@ -39,7 +39,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
 
 abstract class CoAPRestComponentTestBase extends CamelTestSupport {
     @RegisterExtension
-    static AvailablePortFinder.Port coapport = AvailablePortFinder.find();
+    static AvailablePortFinder.Port coapport = CoAPTestSupport.findUdpPort();
 
     @Produce("direct:start")
     protected ProducerTemplate sender;
diff --git 
a/components/camel-coap/src/test/java/org/apache/camel/coap/CoAPTestSupport.java
 
b/components/camel-coap/src/test/java/org/apache/camel/coap/CoAPTestSupport.java
index 3862c91976c6..8808f5bc1de3 100644
--- 
a/components/camel-coap/src/test/java/org/apache/camel/coap/CoAPTestSupport.java
+++ 
b/components/camel-coap/src/test/java/org/apache/camel/coap/CoAPTestSupport.java
@@ -16,6 +16,11 @@
  */
 package org.apache.camel.coap;
 
+import java.net.DatagramSocket;
+import java.net.SocketException;
+import java.util.ArrayList;
+import java.util.List;
+
 import org.apache.camel.test.AvailablePortFinder;
 import org.apache.camel.test.junit6.CamelTestSupport;
 import org.apache.camel.util.FileUtil;
@@ -26,7 +31,36 @@ import org.junit.jupiter.api.extension.RegisterExtension;
 public class CoAPTestSupport extends CamelTestSupport {
 
     @RegisterExtension
-    static AvailablePortFinder.Port PORT = AvailablePortFinder.find();
+    static AvailablePortFinder.Port PORT = findUdpPort();
+
+    /**
+     * Finds a port that is free for UDP as well as TCP. {@link 
AvailablePortFinder} only probes TCP, but CoAP over UDP
+     * and DTLS binds a UDP socket on all interfaces, so a port that is free 
for TCP can still be taken for UDP.
+     */
+    static AvailablePortFinder.Port findUdpPort() {
+        List<AvailablePortFinder.Port> rejected = new ArrayList<>();
+        try {
+            for (int i = 0; i < 100; i++) {
+                AvailablePortFinder.Port port = AvailablePortFinder.find();
+                if (isUdpPortFree(port.getPort())) {
+                    return port;
+                }
+                // keep the rejected port reserved until we are done, so 
find() does not return it again
+                rejected.add(port);
+            }
+            throw new IllegalStateException("Could not find a port that is 
free for both TCP and UDP");
+        } finally {
+            rejected.forEach(AvailablePortFinder.Port::release);
+        }
+    }
+
+    private static boolean isUdpPortFree(int port) {
+        try (DatagramSocket socket = new DatagramSocket(port)) {
+            return true;
+        } catch (SocketException e) {
+            return false;
+        }
+    }
 
     @Override
     public void doPostSetup() {

Reply via email to