From 2e94753c9570be0d5df2721b2b2ca3095a1896df Mon Sep 17 00:00:00 2001 From: jaymode Date: Tue, 19 May 2015 10:57:53 -0400 Subject: [PATCH] [Test] set socket reuse address when using unicast discovery When we use unicast discovery in tests, we test for available ports by binding to ports and if the bind was successful, we use that port. This has a timing issue on certain operating systems the socket can still be in a TIME_WAIT causing subsequent binds to fail before a certain timeout. Setting reuse address on the Java socket will instruct the underlying operating system to allow the socket to be bound to immediately, usually by specifying the SO_REUSEADDR socket option. --- .../test/discovery/ClusterDiscoveryConfiguration.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/test/java/org/elasticsearch/test/discovery/ClusterDiscoveryConfiguration.java b/src/test/java/org/elasticsearch/test/discovery/ClusterDiscoveryConfiguration.java index 1be28a9a8a1..b36bf8f95db 100644 --- a/src/test/java/org/elasticsearch/test/discovery/ClusterDiscoveryConfiguration.java +++ b/src/test/java/org/elasticsearch/test/discovery/ClusterDiscoveryConfiguration.java @@ -21,6 +21,7 @@ package org.elasticsearch.test.discovery; import com.carrotsearch.randomizedtesting.RandomizedTest; import com.google.common.primitives.Ints; import org.elasticsearch.ElasticsearchException; +import org.elasticsearch.common.network.NetworkUtils; import org.elasticsearch.common.settings.ImmutableSettings; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.test.InternalTestCluster; @@ -28,6 +29,7 @@ import org.elasticsearch.test.SettingsSource; import org.elasticsearch.transport.local.LocalTransport; import java.io.IOException; +import java.net.InetSocketAddress; import java.net.ServerSocket; import java.util.HashSet; import java.util.Set; @@ -146,7 +148,11 @@ public class ClusterDiscoveryConfiguration extends SettingsSource { for (int i = 0; i < unicastHostPorts.length; i++) { boolean foundPortInRange = false; while (tries < 1000 && !foundPortInRange) { - try (ServerSocket socket = new ServerSocket(nextPort)) { + try (ServerSocket serverSocket = new ServerSocket()) { + // Set SO_REUSEADDR as we may bind here and not be able to reuse the address immediately without it. + serverSocket.setReuseAddress(NetworkUtils.defaultReuseAddress()); + serverSocket.bind(new InetSocketAddress(nextPort)); + // bind was a success foundPortInRange = true; unicastHostPorts[i] = nextPort;