From 7282c7f762540fe097290a2a82b72d23284968e3 Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Sat, 13 Oct 2012 08:33:45 +0000
Subject: [PATCH] OPENDJ-612: SDK: Race conditions installing client/server filter chains during connect/bind/accept

---
 opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/TestCaseUtils.java        |   19 +++++++++++++++++++
 opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/LDAPListenerTestCase.java |   37 +++++++++++++++----------------------
 2 files changed, 34 insertions(+), 22 deletions(-)

diff --git a/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/LDAPListenerTestCase.java b/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/LDAPListenerTestCase.java
index 4ce42c8..6af2e8c 100644
--- a/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/LDAPListenerTestCase.java
+++ b/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/LDAPListenerTestCase.java
@@ -29,7 +29,9 @@
 
 import static org.fest.assertions.Assertions.assertThat;
 import static org.fest.assertions.Fail.fail;
+import static org.forgerock.opendj.ldap.TestCaseUtils.findFreeSocketAddress;
 
+import java.net.InetSocketAddress;
 import java.util.Arrays;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
@@ -246,13 +248,11 @@
         final MockServerConnectionFactory serverConnectionFactory =
                 new MockServerConnectionFactory(serverConnection);
         final LDAPListener listener =
-                new LDAPListener("localhost", TestCaseUtils.findFreePort(),
-                        serverConnectionFactory);
+                new LDAPListener(new InetSocketAddress(0), serverConnectionFactory);
         try {
             // Connect and close.
             final Connection connection =
                     new LDAPConnectionFactory(listener.getSocketAddress()).getConnection();
-
             assertThat(serverConnection.context.get(10, TimeUnit.SECONDS)).isNotNull();
             assertThat(serverConnection.isClosed.getCount()).isEqualTo(1);
             connection.close();
@@ -349,24 +349,23 @@
     @Test
     public void testLDAPListenerLoadBalanceDuringHandleBind() throws Exception {
         // Online server listener.
-        final int onlineServerPort = TestCaseUtils.findFreePort();
         final MockServerConnection onlineServerConnection = new MockServerConnection();
         final MockServerConnectionFactory onlineServerConnectionFactory =
                 new MockServerConnectionFactory(onlineServerConnection);
         final LDAPListener onlineServerListener =
-                new LDAPListener("localhost", onlineServerPort, onlineServerConnectionFactory);
+                new LDAPListener(new InetSocketAddress(0), onlineServerConnectionFactory);
 
         try {
             // Connection pool and load balancing tests.
             final ConnectionFactory offlineServer1 =
-                    Connections.newNamedConnectionFactory(new LDAPConnectionFactory("localhost",
-                            TestCaseUtils.findFreePort()), "offline1");
+                    Connections.newNamedConnectionFactory(new LDAPConnectionFactory(
+                            findFreeSocketAddress()), "offline1");
             final ConnectionFactory offlineServer2 =
-                    Connections.newNamedConnectionFactory(new LDAPConnectionFactory("localhost",
-                            TestCaseUtils.findFreePort()), "offline2");
+                    Connections.newNamedConnectionFactory(new LDAPConnectionFactory(
+                            findFreeSocketAddress()), "offline2");
             final ConnectionFactory onlineServer =
-                    Connections.newNamedConnectionFactory(new LDAPConnectionFactory("localhost",
-                            onlineServerPort), "online");
+                    Connections.newNamedConnectionFactory(new LDAPConnectionFactory(
+                            onlineServerListener.getSocketAddress()), "online");
 
             // Round robin.
             final ConnectionFactory loadBalancer =
@@ -388,8 +387,7 @@
                         final ResultHandler<? super BindResult> resultHandler)
                         throws UnsupportedOperationException {
                     // Get connection from load balancer, this should fail over
-                    // twice
-                    // before getting connection to online server.
+                    // twice before getting connection to online server.
                     try {
                         loadBalancer.getConnection().close();
                         resultHandler.handleResult(Responses.newBindResult(ResultCode.SUCCESS));
@@ -406,8 +404,7 @@
                     new MockServerConnectionFactory(proxyServerConnection);
 
             final LDAPListener proxyListener =
-                    new LDAPListener("localhost", TestCaseUtils.findFreePort(),
-                            proxyServerConnectionFactory);
+                    new LDAPListener(new InetSocketAddress(0), proxyServerConnectionFactory);
             try {
                 // Connect, bind, and close.
                 final Connection connection =
@@ -531,12 +528,9 @@
         final MockServerConnectionFactory onlineServerConnectionFactory =
                 new MockServerConnectionFactory(onlineServerConnection);
         final LDAPListener onlineServerListener =
-                new LDAPListener("localhost", TestCaseUtils.findFreePort(),
-                        onlineServerConnectionFactory);
+                new LDAPListener(findFreeSocketAddress(), onlineServerConnectionFactory);
 
         try {
-            final int offlineServerPort = TestCaseUtils.findFreePort();
-
             final MockServerConnection proxyServerConnection = new MockServerConnection() {
 
                 /**
@@ -550,7 +544,7 @@
                         throws UnsupportedOperationException {
                     // First attempt offline server.
                     LDAPConnectionFactory lcf =
-                            new LDAPConnectionFactory("localhost", offlineServerPort);
+                            new LDAPConnectionFactory(findFreeSocketAddress());
                     try {
                         // This is expected to fail.
                         lcf.getConnection().close();
@@ -583,8 +577,7 @@
             final MockServerConnectionFactory proxyServerConnectionFactory =
                     new MockServerConnectionFactory(proxyServerConnection);
             final LDAPListener proxyListener =
-                    new LDAPListener("localhost", TestCaseUtils.findFreePort(),
-                            proxyServerConnectionFactory);
+                    new LDAPListener(findFreeSocketAddress(), proxyServerConnectionFactory);
             try {
                 // Connect, bind, and close.
                 final Connection connection =
diff --git a/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/TestCaseUtils.java b/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/TestCaseUtils.java
index 85bb408..b78acb4 100644
--- a/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/TestCaseUtils.java
+++ b/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/TestCaseUtils.java
@@ -31,6 +31,7 @@
 import java.io.IOException;
 import java.net.InetSocketAddress;
 import java.net.ServerSocket;
+import java.net.SocketAddress;
 
 /**
  * This class defines some utility functions which can be used by test cases.
@@ -101,6 +102,24 @@
     }
 
     /**
+     * Finds a free server socket port on the local host.
+     *
+     * @return The free port.
+     */
+    public static SocketAddress findFreeSocketAddress() {
+        try {
+            ServerSocket serverLdapSocket = new ServerSocket();
+            serverLdapSocket.setReuseAddress(true);
+            serverLdapSocket.bind(new InetSocketAddress("127.0.0.1", 0));
+            final SocketAddress address = serverLdapSocket.getLocalSocketAddress();
+            serverLdapSocket.close();
+            return address;
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
      * Returns an internal client connection to the running ldap server.
      *
      * @return The internal client connection.

--
Gitblit v1.10.0