You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by zh...@apache.org on 2024/11/12 01:46:05 UTC
(camel-quarkus) 01/04: Avoid UDP port clashes in tests
This is an automated email from the ASF dual-hosted git repository.
zhfeng pushed a commit to branch 3.8.x
in repository https://gitbox.apache.org/repos/asf/camel-quarkus.git
commit 532ebde6edfd4705247a2532b8ec8d3e87236878
Author: James Netherton <ja...@gmail.com>
AuthorDate: Thu Sep 19 12:58:42 2024 +0100
Avoid UDP port clashes in tests
Fixes #6489
---
.../camel/quarkus/test/AvailablePortFinder.java | 64 ++++++++++++++++++----
.../component/netty/udp/NettyUdpTestResource.java | 2 +
.../component/syslog/it/SyslogTestResource.java | 3 +-
3 files changed, 57 insertions(+), 12 deletions(-)
diff --git a/integration-tests-support/test-support/src/main/java/org/apache/camel/quarkus/test/AvailablePortFinder.java b/integration-tests-support/test-support/src/main/java/org/apache/camel/quarkus/test/AvailablePortFinder.java
index 4fce970396..c125c45d20 100644
--- a/integration-tests-support/test-support/src/main/java/org/apache/camel/quarkus/test/AvailablePortFinder.java
+++ b/integration-tests-support/test-support/src/main/java/org/apache/camel/quarkus/test/AvailablePortFinder.java
@@ -17,8 +17,7 @@
package org.apache.camel.quarkus.test;
import java.io.IOException;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
+import java.net.DatagramSocket;
import java.net.ServerSocket;
import java.util.HashMap;
import java.util.Map;
@@ -51,22 +50,30 @@ public final class AvailablePortFinder {
}
/**
- * Gets the next available port.
+ * Gets the next available TCP port.
*
* @throws IllegalStateException if there are no ports available
* @return the available port
*/
public static int getNextAvailable() {
+ return getNextAvailable(Protocol.TCP);
+ }
+
+ /**
+ * Gets the next available port for the given protocol.
+ *
+ * @param protocol the network protocol to reserve the port for. Either TCP or UDP
+ * @throws IllegalStateException if there are no ports available
+ * @return the available port
+ */
+ public static int getNextAvailable(Protocol protocol) {
// Using AvailablePortFinder in native applications can be problematic
// E.g The reserved port may be allocated at build time and preserved indefinitely at runtime. I.e it never changes on each execution of the native application
logWarningIfNativeApplication();
while (true) {
- try (ServerSocket ss = new ServerSocket()) {
- ss.setReuseAddress(true);
- ss.bind(new InetSocketAddress((InetAddress) null, 0), 1);
-
- int port = ss.getLocalPort();
+ try {
+ int port = protocol.getPort();
if (!isQuarkusReservedPort(port)) {
String callerClassName = getCallerClassName();
String value = RESERVED_PORTS.putIfAbsent(port, callerClassName);
@@ -82,20 +89,34 @@ public final class AvailablePortFinder {
}
/**
- * Reserve a list of random and not in use network ports and place them in Map.
+ * Reserve a list of random and not in use TCP network ports and places them in Map.
*/
public static Map<String, Integer> reserveNetworkPorts(String... names) {
return reserveNetworkPorts(Function.identity(), names);
}
/**
- * Reserve a list of random and not in use network ports and place them in Map.
+ * Reserve a list of random and not in use network ports for the given protocol and places them in Map.
+ */
+ public static Map<String, Integer> reserveNetworkPorts(Protocol protocol, String... names) {
+ return reserveNetworkPorts(protocol, Function.identity(), names);
+ }
+
+ /**
+ * Reserve a list of random and not in use TCP network ports and places them in Map.
*/
public static <T> Map<String, T> reserveNetworkPorts(Function<Integer, T> converter, String... names) {
+ return reserveNetworkPorts(Protocol.TCP, converter, names);
+ }
+
+ /**
+ * Reserve a list of random and not in use network ports for the given protocol and places them in Map.
+ */
+ public static <T> Map<String, T> reserveNetworkPorts(Protocol protocol, Function<Integer, T> converter, String... names) {
Map<String, T> reservedPorts = new HashMap<>();
for (String name : names) {
- reservedPorts.put(name, converter.apply(getNextAvailable()));
+ reservedPorts.put(name, converter.apply(getNextAvailable(protocol)));
}
return reservedPorts;
@@ -139,4 +160,25 @@ public final class AvailablePortFinder {
+ "Pass the reserved port to the native application under test with QuarkusTestResource or via an HTTP request");
}
}
+
+ public enum Protocol {
+ TCP,
+ UDP;
+
+ int getPort() throws IOException {
+ if (this.equals(TCP)) {
+ try (ServerSocket socket = new ServerSocket()) {
+ socket.setReuseAddress(true);
+ socket.bind(null);
+ return socket.getLocalPort();
+ }
+ }
+
+ try (DatagramSocket socket = new DatagramSocket()) {
+ // NOTE: There's no need for socket.bind as it happens during DatagramSocket instantiation
+ socket.setReuseAddress(true);
+ return socket.getLocalPort();
+ }
+ }
+ }
}
diff --git a/integration-tests/netty/src/test/java/org/apache/camel/quarkus/component/netty/udp/NettyUdpTestResource.java b/integration-tests/netty/src/test/java/org/apache/camel/quarkus/component/netty/udp/NettyUdpTestResource.java
index 776c7af0b7..f05caea245 100644
--- a/integration-tests/netty/src/test/java/org/apache/camel/quarkus/component/netty/udp/NettyUdpTestResource.java
+++ b/integration-tests/netty/src/test/java/org/apache/camel/quarkus/component/netty/udp/NettyUdpTestResource.java
@@ -21,11 +21,13 @@ import java.util.Objects;
import io.quarkus.test.common.QuarkusTestResourceLifecycleManager;
import org.apache.camel.quarkus.test.AvailablePortFinder;
+import org.apache.camel.quarkus.test.AvailablePortFinder.Protocol;
public class NettyUdpTestResource implements QuarkusTestResourceLifecycleManager {
@Override
public Map<String, String> start() {
return AvailablePortFinder.reserveNetworkPorts(
+ Protocol.UDP,
Objects::toString,
"camel.netty.test-udp-port",
"camel.netty.test-codec-udp-port",
diff --git a/integration-tests/syslog/src/test/java/org/apache/camel/quarkus/component/syslog/it/SyslogTestResource.java b/integration-tests/syslog/src/test/java/org/apache/camel/quarkus/component/syslog/it/SyslogTestResource.java
index d875db16dc..e42d4ff501 100644
--- a/integration-tests/syslog/src/test/java/org/apache/camel/quarkus/component/syslog/it/SyslogTestResource.java
+++ b/integration-tests/syslog/src/test/java/org/apache/camel/quarkus/component/syslog/it/SyslogTestResource.java
@@ -21,12 +21,13 @@ import java.util.Objects;
import io.quarkus.test.common.QuarkusTestResourceLifecycleManager;
import org.apache.camel.quarkus.test.AvailablePortFinder;
+import org.apache.camel.quarkus.test.AvailablePortFinder.Protocol;
public class SyslogTestResource implements QuarkusTestResourceLifecycleManager {
@Override
public Map<String, String> start() {
- return AvailablePortFinder.reserveNetworkPorts(Objects::toString, "camel.netty.rfc5425.port",
+ return AvailablePortFinder.reserveNetworkPorts(Protocol.UDP, Objects::toString, "camel.netty.rfc5425.port",
"camel.netty.rfc3164.port");
}