[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.
This commit is contained in:
jaymode 2015-05-19 10:57:53 -04:00
parent 52899c87ef
commit 2e94753c95
1 changed files with 7 additions and 1 deletions

View File

@ -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;