[TESTS] Set SO_LINGER and SO_REUSEADDR on the mock socket (#34211)
In SessionFactoryLoadBalancingTests#testRoundRobinWithFailures() we kill ldap servers randomly and immediately bind to that port connecting to mock server socket. This is done to avoid someone else listening to this port. As the creation of mock socket and binding to the port is immediate, sometimes the earlier socket would be in TIME_WAIT state thereby having problems with either bind or connect. This commit sets the SO_REUSEADDR explicitly to true and also sets the linger on time to 0(as we are not writing any data) so as to allow re-use of the port and close immediately. Note: I could not find other places where this might be problematic but looking at test runs and netstat output I do see lot of sockets in TIME_WAIT. If we find that this needs to be addressed we can wrap ServerSocketFactory to set these options and use that with in memory ldap server configuration during tests. Closes #32190
This commit is contained in:
parent
a21a99da18
commit
f79282e47d
|
@ -8,6 +8,7 @@ package org.elasticsearch.xpack.security.authc.ldap.support;
|
||||||
import com.unboundid.ldap.listener.InMemoryDirectoryServer;
|
import com.unboundid.ldap.listener.InMemoryDirectoryServer;
|
||||||
import com.unboundid.ldap.sdk.LDAPConnection;
|
import com.unboundid.ldap.sdk.LDAPConnection;
|
||||||
import org.elasticsearch.action.ActionListener;
|
import org.elasticsearch.action.ActionListener;
|
||||||
|
import org.elasticsearch.common.SuppressForbidden;
|
||||||
import org.elasticsearch.common.settings.SecureString;
|
import org.elasticsearch.common.settings.SecureString;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
||||||
|
@ -17,6 +18,7 @@ import org.elasticsearch.mocksocket.MockSocket;
|
||||||
import org.elasticsearch.test.junit.annotations.TestLogging;
|
import org.elasticsearch.test.junit.annotations.TestLogging;
|
||||||
import org.elasticsearch.threadpool.TestThreadPool;
|
import org.elasticsearch.threadpool.TestThreadPool;
|
||||||
import org.elasticsearch.threadpool.ThreadPool;
|
import org.elasticsearch.threadpool.ThreadPool;
|
||||||
|
import org.elasticsearch.xpack.core.common.socket.SocketAccess;
|
||||||
import org.elasticsearch.xpack.core.security.authc.RealmConfig;
|
import org.elasticsearch.xpack.core.security.authc.RealmConfig;
|
||||||
import org.elasticsearch.xpack.core.security.authc.ldap.support.LdapSearchScope;
|
import org.elasticsearch.xpack.core.security.authc.ldap.support.LdapSearchScope;
|
||||||
import org.elasticsearch.xpack.core.ssl.SSLService;
|
import org.elasticsearch.xpack.core.ssl.SSLService;
|
||||||
|
@ -25,6 +27,7 @@ import org.junit.Before;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
@ -112,7 +115,7 @@ public class SessionFactoryLoadBalancingTests extends LdapTestCase {
|
||||||
// of the ldap server and the opening of the socket
|
// of the ldap server and the opening of the socket
|
||||||
logger.debug("opening mock server socket listening on [{}]", port);
|
logger.debug("opening mock server socket listening on [{}]", port);
|
||||||
Runnable runnable = () -> {
|
Runnable runnable = () -> {
|
||||||
try (Socket socket = new MockSocket(InetAddress.getByName("localhost"), mockServerSocket.getLocalPort(), local, port)) {
|
try (Socket socket = openMockSocket(local, mockServerSocket.getLocalPort(), local, port)) {
|
||||||
logger.debug("opened socket [{}]", socket);
|
logger.debug("opened socket [{}]", socket);
|
||||||
latch.countDown();
|
latch.countDown();
|
||||||
closeLatch.await();
|
closeLatch.await();
|
||||||
|
@ -149,6 +152,17 @@ public class SessionFactoryLoadBalancingTests extends LdapTestCase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressForbidden(reason = "Allow opening socket for test")
|
||||||
|
private MockSocket openMockSocket(InetAddress remoteAddress, int remotePort, InetAddress localAddress, int localPort)
|
||||||
|
throws IOException {
|
||||||
|
final MockSocket socket = new MockSocket();
|
||||||
|
socket.setReuseAddress(true); // allow binding even if the previous socket is in timed wait state.
|
||||||
|
socket.setSoLinger(true, 0); // close immediately as we are not writing anything here.
|
||||||
|
socket.bind(new InetSocketAddress(localAddress, localPort));
|
||||||
|
SocketAccess.doPrivileged(() -> socket.connect(new InetSocketAddress(localAddress, remotePort)));
|
||||||
|
return socket;
|
||||||
|
}
|
||||||
|
|
||||||
public void testFailover() throws Exception {
|
public void testFailover() throws Exception {
|
||||||
assumeTrue("at least one ldap server should be present for this test", ldapServers.length > 1);
|
assumeTrue("at least one ldap server should be present for this test", ldapServers.length > 1);
|
||||||
logger.debug("using [{}] ldap servers, urls {}", ldapServers.length, ldapUrls());
|
logger.debug("using [{}] ldap servers, urls {}", ldapServers.length, ldapUrls());
|
||||||
|
|
Loading…
Reference in New Issue