From a18241e1d91b5212dc8e4fb9d41d9a2d6c0baa40 Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Wed, 04 May 2016 14:49:10 +0000
Subject: [PATCH] Fix unit test failures due to ports already in use

---
 opendj-server-legacy/src/test/java/org/opends/server/TestCaseUtils.java                   |   33 +++++++++++++++++++++++++--------
 opendj-server-legacy/src/test/java/org/opends/server/monitors/GenericMonitorTestCase.java |   27 ++++++++++-----------------
 2 files changed, 35 insertions(+), 25 deletions(-)

diff --git a/opendj-server-legacy/src/test/java/org/opends/server/TestCaseUtils.java b/opendj-server-legacy/src/test/java/org/opends/server/TestCaseUtils.java
index 8512a92..e87ad0d 100644
--- a/opendj-server-legacy/src/test/java/org/opends/server/TestCaseUtils.java
+++ b/opendj-server-legacy/src/test/java/org/opends/server/TestCaseUtils.java
@@ -34,6 +34,7 @@
 import java.lang.management.ManagementFactory;
 import java.lang.management.ThreadInfo;
 import java.lang.management.ThreadMXBean;
+import java.net.BindException;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.net.ServerSocket;
@@ -421,10 +422,11 @@
 
       // Find some free ports for the listeners and write them to the
       // config-chamges.ldif file.
-      serverLdapPort = getFreePort(PROPERTY_LDAP_PORT);
-      serverAdminPort = getFreePort(PROPERTY_ADMIN_PORT);
-      serverJmxPort = findFreePort();
-      serverLdapsPort = findFreePort();
+      final int[] ports = findFreePorts(4);
+      serverLdapPort = getFreePort(PROPERTY_LDAP_PORT, ports[0]);
+      serverAdminPort = getFreePort(PROPERTY_ADMIN_PORT, ports[1]);
+      serverJmxPort = ports[2];
+      serverLdapsPort = ports[3];
 
       String defaultConfigChangeFile = testResourceDir + File.separator
           + "config-changes.ldif";
@@ -497,12 +499,12 @@
     }
   }
 
-  private static int getFreePort(String portPropertyName) throws IOException
+  private static int getFreePort(String portPropertyName, int defaultPort) throws IOException
   {
     String port = System.getProperty(portPropertyName);
     if (port == null)
     {
-      return findFreePort();
+      return defaultPort;
     }
     int portNb = Integer.parseInt(port);
     // Check this port is free
@@ -657,14 +659,29 @@
   }
 
   /**
-   * Find and binds to a free server socket port on the local host.
+   * Find and binds to a free server socket port on the local host. Avoid allocating ephemeral ports since these may
+   * be used by client applications such as dsconfig. Instead scan through ports starting from a reasonably high number
+   * which avoids most reserved services (see /etc/services) and continues up to the beginning of the ephemeral port
+   * range. On most Linux OSes this is 32768, but may be higher.
+   *
    * @return the bounded Server socket.
    *
    * @throws IOException in case of underlying exception.
    */
   public static ServerSocket bindFreePort() throws IOException
   {
-    return bindPort(0);
+    for (int port = 10000; port < 32768; port++)
+    {
+      try
+      {
+        return bindPort(port);
+      }
+      catch (BindException e)
+      {
+        // Try next port.
+      }
+    }
+    throw new BindException("Unable to bind to a free port");
   }
 
   /**
diff --git a/opendj-server-legacy/src/test/java/org/opends/server/monitors/GenericMonitorTestCase.java b/opendj-server-legacy/src/test/java/org/opends/server/monitors/GenericMonitorTestCase.java
index 9aad391..1a91fc6 100644
--- a/opendj-server-legacy/src/test/java/org/opends/server/monitors/GenericMonitorTestCase.java
+++ b/opendj-server-legacy/src/test/java/org/opends/server/monitors/GenericMonitorTestCase.java
@@ -18,6 +18,7 @@
 
 
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 import org.testng.annotations.AfterClass;
 
@@ -38,33 +39,25 @@
 public abstract class GenericMonitorTestCase
        extends MonitorTestCase
 {
-  /** The configuration entry for this test case. */
+  private final String configEntryName;
   protected Entry configEntry;
 
+  GenericMonitorTestCase(String dnString)
+  {
+    configEntryName = dnString;
+  }
 
-
-  /**
-   * Creates a new instance of this monitor test case.
-   *
-   * @param  dnString  The DN of the configuration entry for this test case, or
-   *                   <CODE>null</CODE> if there is none.
-   *
-   * @throws  Exception  If an unexpected problem occurs.
-   */
-  protected GenericMonitorTestCase(String dnString)
-            throws Exception
+  @BeforeClass
+  public void beforeClass() throws Exception
   {
     TestCaseUtils.startServer();
-
-    if (dnString != null)
+    if (configEntryName != null)
     {
-      configEntry = DirectoryServer.getEntry(DN.valueOf(dnString));
+      configEntry = DirectoryServer.getEntry(DN.valueOf(configEntryName));
       assertNotNull(configEntry);
     }
   }
 
-
-
   /**
    * Retrieves an initialized instance of the associated monitor provider.
    *

--
Gitblit v1.10.0