Make TestUtils.getFreePort() check both TCP and UDP
Motivation: We see occational failures in the datagram tests saying 'address already in use' when we attempt to bind on a port returned by TestUtils.getFreePort(). It turns out that TestUtils.getFreePort() only checks if TCP port is available. Modifications: Also check if UDP port is available, so that the datagram tests do not fail because of the 'address already in use' error during a bind attempt. Result: Less chance of datagram test failures
This commit is contained in:
parent
29a847587f
commit
582f2e82ec
@ -19,6 +19,7 @@ import io.netty.util.NetUtil;
|
||||
import org.junit.rules.TestName;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.DatagramSocket;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.ServerSocket;
|
||||
import java.nio.channels.Channel;
|
||||
@ -58,29 +59,66 @@ public final class TestUtils {
|
||||
*/
|
||||
public static int getFreePort() {
|
||||
for (int i = 0; i < NUM_CANDIDATES; i ++) {
|
||||
int port = nextCandidatePort();
|
||||
try {
|
||||
// Ensure it is possible to bind on both wildcard and loopback.
|
||||
ServerSocket ss;
|
||||
ss = new ServerSocket();
|
||||
ss.setReuseAddress(false);
|
||||
ss.bind(new InetSocketAddress(port));
|
||||
ss.close();
|
||||
|
||||
ss = new ServerSocket();
|
||||
ss.setReuseAddress(false);
|
||||
ss.bind(new InetSocketAddress(NetUtil.LOCALHOST, port));
|
||||
ss.close();
|
||||
final int port = nextCandidatePort();
|
||||
final InetSocketAddress wildcardAddr = new InetSocketAddress(port);
|
||||
final InetSocketAddress loopbackAddr = new InetSocketAddress(NetUtil.LOCALHOST4, port);
|
||||
|
||||
// Ensure it is possible to bind on wildcard/loopback and tcp/udp.
|
||||
if (isTcpPortAvailable(wildcardAddr) &&
|
||||
isTcpPortAvailable(loopbackAddr) &&
|
||||
isUdpPortAvailable(wildcardAddr) &&
|
||||
isUdpPortAvailable(loopbackAddr)) {
|
||||
return port;
|
||||
} catch (IOException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
throw new RuntimeException("unable to find a free port");
|
||||
}
|
||||
|
||||
private static boolean isTcpPortAvailable(InetSocketAddress localAddress) {
|
||||
ServerSocket ss = null;
|
||||
try {
|
||||
ss = new ServerSocket();
|
||||
ss.setReuseAddress(false);
|
||||
ss.bind(localAddress);
|
||||
ss.close();
|
||||
ss = null;
|
||||
return true;
|
||||
} catch (Exception ignore) {
|
||||
// Unavailable
|
||||
} finally {
|
||||
if (ss != null) {
|
||||
try {
|
||||
ss.close();
|
||||
} catch (IOException ignore) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isUdpPortAvailable(InetSocketAddress localAddress) {
|
||||
DatagramSocket ds = null;
|
||||
try {
|
||||
ds = new DatagramSocket(null);
|
||||
ds.setReuseAddress(false);
|
||||
ds.bind(localAddress);
|
||||
ds.close();
|
||||
ds = null;
|
||||
return true;
|
||||
} catch (Exception ignore) {
|
||||
// Unavailable
|
||||
} finally {
|
||||
if (ds != null) {
|
||||
ds.close();
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return {@code true} if SCTP is supported by the running os.
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user