This is an automated email from the ASF dual-hosted git repository.
markt-asf pushed a commit to branch 11.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/11.0.x by this push:
new 78b99c78d8 Make test more robust
78b99c78d8 is described below
commit 78b99c78d841ee61fc87be587f17f2c0b2850491
Author: Mark Thomas <[email protected]>
AuthorDate: Sat Nov 7 17:40:44 2026 +0000
Make test more robust
Co-authored by: Claude / Sonnet 5.5
---
test/org/apache/catalina/tribes/TesterUtil.java | 6 +--
.../tribes/membership/TestMcastService.java | 50 ++++++++++++++--------
2 files changed, 35 insertions(+), 21 deletions(-)
diff --git a/test/org/apache/catalina/tribes/TesterUtil.java
b/test/org/apache/catalina/tribes/TesterUtil.java
index 6b7dc256ff..b76e48f914 100644
--- a/test/org/apache/catalina/tribes/TesterUtil.java
+++ b/test/org/apache/catalina/tribes/TesterUtil.java
@@ -18,7 +18,6 @@ package org.apache.catalina.tribes;
import java.io.IOException;
import java.net.DatagramPacket;
-import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.MulticastSocket;
@@ -40,12 +39,13 @@ public class TesterUtil {
/*
- * Returns a UDP port that was free on the loopback interface when it was
checked. Only for ports, such as a
+ * Returns a UDP port that was free on the wildcard address (the address
McastService binds to) when it was
+ * checked. Only for ports, such as a
* multicast group port, that cannot be left to the operating system
because every member needs to know it in
* advance. There is a small window in which another process may take the
port before the caller binds it.
*/
public static int getFreeUdpPort() throws IOException {
- try (DatagramSocket socket = new DatagramSocket(0,
InetAddress.getLoopbackAddress())) {
+ try (MulticastSocket socket = new MulticastSocket(0)) {
return socket.getLocalPort();
}
}
diff --git a/test/org/apache/catalina/tribes/membership/TestMcastService.java
b/test/org/apache/catalina/tribes/membership/TestMcastService.java
index 1aada231b6..5074812086 100644
--- a/test/org/apache/catalina/tribes/membership/TestMcastService.java
+++ b/test/org/apache/catalina/tribes/membership/TestMcastService.java
@@ -17,6 +17,7 @@
package org.apache.catalina.tribes.membership;
import java.io.ByteArrayInputStream;
+import java.net.BindException;
import java.util.Properties;
import org.junit.Assert;
@@ -31,6 +32,35 @@ import org.apache.catalina.tribes.io.XByteBuffer;
public class TestMcastService {
+ private static final int MAX_START_ATTEMPTS = 5;
+
+ /*
+ * The multicast port has to be known in advance so it cannot be left to
the operating system. That leaves a window
+ * between finding a free port and the service binding it in which
something else may take it. If that happens,
+ * pick another port and try again.
+ */
+ private static McastService startService(Properties props) throws
Exception {
+ BindException lastFailure = null;
+ for (int attempt = 0; attempt < MAX_START_ATTEMPTS; attempt++) {
+ props.setProperty("mcastPort",
String.valueOf(TesterUtil.getFreeUdpPort()));
+
+ GroupChannel channel = new GroupChannel();
+ channel.setName("TestMcastService-" + System.nanoTime());
+
+ McastService service = new McastService();
+ service.setChannel(channel);
+ service.setProperties(props);
+ try {
+ service.start(Channel.MBR_TX_SEQ);
+ return service;
+ } catch (BindException e) {
+ lastFailure = e;
+ }
+ }
+ throw lastFailure;
+ }
+
+
/*
* The shutdown message that stop() broadcasts routinely fails when the
network device is down or the socket is
* already broken. That must not skip leaving the multicast group and
closing the socket, nor prevent the service
@@ -38,10 +68,8 @@ public class TestMcastService {
*/
@Test(timeout = 60000)
public void testStopWithFailingShutdownSendCompletes() throws Exception {
- int mcastPort = TesterUtil.getFreeUdpPort();
StringBuilder properties = new StringBuilder();
properties.append("mcastAddress=228.0.0.4\n");
- properties.append("mcastPort=").append(mcastPort).append("\n");
properties.append("tcpListenHost=127.0.0.1\n");
properties.append("tcpListenPort=").append(0).append("\n");
properties.append("tcpSecurePort=0\n");
@@ -52,15 +80,9 @@ public class TestMcastService {
properties.append("recoveryCounter=10\n");
properties.append("recoverySleepTime=3000\n");
- GroupChannel channel = new GroupChannel();
- channel.setName("TestMcastService-" + System.nanoTime());
-
- McastService service = new McastService();
- service.setChannel(channel);
Properties props = new Properties();
props.load(new
ByteArrayInputStream(properties.toString().getBytes("UTF-8")));
- service.setProperties(props);
- service.start(Channel.MBR_TX_SEQ);
+ McastService service = startService(props);
McastServiceImpl impl = service.impl;
Assert.assertNotNull(impl);
@@ -168,10 +190,8 @@ public class TestMcastService {
*/
@Test(timeout = 60000)
public void testBroadcastRejectsPacketsTheSocketCannotCarry() throws
Exception {
- int mcastPort = TesterUtil.getFreeUdpPort();
Properties props = new Properties();
props.setProperty("mcastAddress", "228.0.0.4");
- props.setProperty("mcastPort", String.valueOf(mcastPort));
props.setProperty("tcpListenHost", "127.0.0.1");
props.setProperty("tcpListenPort", "0");
props.setProperty("tcpSecurePort", "0");
@@ -182,13 +202,7 @@ public class TestMcastService {
props.setProperty("recoveryCounter", "10");
props.setProperty("recoverySleepTime", "3000");
- GroupChannel channel = new GroupChannel();
- channel.setName("TestMcastService-" + System.nanoTime());
-
- McastService service = new McastService();
- service.setChannel(channel);
- service.setProperties(props);
- service.start(Channel.MBR_TX_SEQ);
+ McastService service = startService(props);
try {
// Build a packet just above the sendable size but still within
the 65535 byte packet
// limit the old check used, and small enough for this platform to
actually send
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]