You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by je...@apache.org on 2021/01/19 05:07:32 UTC

[geode] branch develop updated: GEODE-8838: Provide some ability to launch ChildVM with specific port for RemoteDUnitVM stub (#5909)

This is an automated email from the ASF dual-hosted git repository.

jensdeppe pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/geode.git


The following commit(s) were added to refs/heads/develop by this push:
     new c34d5c2  GEODE-8838: Provide some ability to launch ChildVM with specific port for RemoteDUnitVM stub (#5909)
c34d5c2 is described below

commit c34d5c2db23c17c196bd86502e281df820a3d9fa
Author: Jens Deppe <jd...@pivotal.io>
AuthorDate: Mon Jan 18 21:06:32 2021 -0800

    GEODE-8838: Provide some ability to launch ChildVM with specific port for RemoteDUnitVM stub (#5909)
    
    - This change is intended to address an issue with port bind conflicts
      specifically when VMs are restarted. Thus this change only specifies a
      specific port when bouncing a VM. In this case we use a RMI port
      outside the usual range of ephemeral ports for MacOS (49152–65535) and
      Linux (32768-60999).
    - We typically try and use ephemeral ports everywhere. However,
      sometimes an ephemeral port created during a prior start needs to be
      used as a fixed port on subsequent bounces. In this case, ephemeral
      ports that are allocated early may end up conflicting with these fixed
      ports.
    - Remove various unused methods related to bounce()ing VMs.
---
 .../java/org/apache/geode/test/dunit/DUnitEnv.java |  5 ----
 .../main/java/org/apache/geode/test/dunit/VM.java  | 10 ++++++-
 .../apache/geode/test/dunit/internal/ChildVM.java  |  3 ++-
 .../geode/test/dunit/internal/ChildVMLauncher.java |  2 +-
 .../geode/test/dunit/internal/DUnitHost.java       |  4 +--
 .../geode/test/dunit/internal/DUnitLauncher.java   |  1 +
 .../apache/geode/test/dunit/internal/Master.java   | 25 -----------------
 .../geode/test/dunit/internal/MasterRemote.java    |  3 ---
 .../geode/test/dunit/internal/ProcessManager.java  | 31 +++++-----------------
 .../geode/test/dunit/internal/RemoteDUnitVM.java   |  4 +--
 .../test/dunit/internal/StandAloneDUnitEnv.java    |  6 -----
 11 files changed, 23 insertions(+), 71 deletions(-)

diff --git a/geode-dunit/src/main/java/org/apache/geode/test/dunit/DUnitEnv.java b/geode-dunit/src/main/java/org/apache/geode/test/dunit/DUnitEnv.java
index cdb5c59..76c7852 100644
--- a/geode-dunit/src/main/java/org/apache/geode/test/dunit/DUnitEnv.java
+++ b/geode-dunit/src/main/java/org/apache/geode/test/dunit/DUnitEnv.java
@@ -15,10 +15,8 @@
 package org.apache.geode.test.dunit;
 
 import java.io.File;
-import java.rmi.RemoteException;
 import java.util.Properties;
 
-import org.apache.geode.test.dunit.internal.BounceResult;
 
 /**
  * This class provides an abstraction over the environment that is used to run dunit. This will
@@ -61,9 +59,6 @@ public abstract class DUnitEnv {
 
   public abstract int getId();
 
-  public abstract BounceResult bounce(String version, int pid, boolean force)
-      throws RemoteException;
-
   public abstract File getWorkingDirectory(int pid);
 
   public abstract File getWorkingDirectory(String version, int pid);
diff --git a/geode-dunit/src/main/java/org/apache/geode/test/dunit/VM.java b/geode-dunit/src/main/java/org/apache/geode/test/dunit/VM.java
index 5d99ddb..0c5baf5 100644
--- a/geode-dunit/src/main/java/org/apache/geode/test/dunit/VM.java
+++ b/geode-dunit/src/main/java/org/apache/geode/test/dunit/VM.java
@@ -33,6 +33,7 @@ import java.util.concurrent.Callable;
 import org.apache.commons.lang3.ArrayUtils;
 import org.apache.logging.log4j.Logger;
 
+import org.apache.geode.internal.AvailablePortHelper;
 import org.apache.geode.internal.process.ProcessUtils;
 import org.apache.geode.logging.internal.log4j.api.LogService;
 import org.apache.geode.test.dunit.internal.ChildVMLauncher;
@@ -584,7 +585,14 @@ public class VM implements Serializable {
         executeMethodOnObject(runnable, "run", new Object[0]);
       }
       processHolder.waitFor();
-      processHolder = childVMLauncher.launchVM(targetVersion, id, true);
+
+      // We typically try and use ephemeral ports everywhere. However, sometimes an ephemeral port
+      // created during a prior start needs to be used as a fixed port on subsequent bounces. In
+      // this case, ephemeral ports that are allocated early may end up conflicting with these
+      // fixed ports. So when we bounce a VM, use an RMI port outside the usual range of ephemeral
+      // ports for MacOS (49152–65535) and Linux (32768-60999).
+      int remoteStubPort = AvailablePortHelper.getRandomAvailableTCPPort();
+      processHolder = childVMLauncher.launchVM(targetVersion, id, true, remoteStubPort);
       version = targetVersion;
       client = childVMLauncher.getStub(id);
       available = true;
diff --git a/geode-dunit/src/main/java/org/apache/geode/test/dunit/internal/ChildVM.java b/geode-dunit/src/main/java/org/apache/geode/test/dunit/internal/ChildVM.java
index ddd9a8e..6c5297d 100644
--- a/geode-dunit/src/main/java/org/apache/geode/test/dunit/internal/ChildVM.java
+++ b/geode-dunit/src/main/java/org/apache/geode/test/dunit/internal/ChildVM.java
@@ -41,6 +41,7 @@ public class ChildVM {
     try {
       int namingPort = Integer.getInteger(DUnitLauncher.RMI_PORT_PARAM);
       int vmNum = Integer.getInteger(DUnitLauncher.VM_NUM_PARAM);
+      int remoteStubPort = Integer.getInteger(DUnitLauncher.REMOTE_STUB_PORT_PARAM, 0);
       String geodeVersion = System.getProperty(DUnitLauncher.VM_VERSION_PARAM);
       int pid = OSProcess.getId();
       logger.info("VM" + vmNum + " is launching" + (pid > 0 ? " with PID " + pid : ""));
@@ -52,7 +53,7 @@ public class ChildVM {
           .lookup("//localhost:" + namingPort + "/" + DUnitLauncher.MASTER_PARAM);
       DUnitLauncher.init(holder);
       DUnitLauncher.locatorPort = holder.getLocatorPort();
-      final RemoteDUnitVM dunitVM = new RemoteDUnitVM();
+      final RemoteDUnitVM dunitVM = new RemoteDUnitVM(remoteStubPort);
       final String name = "//localhost:" + namingPort + "/vm" + vmNum;
       Naming.rebind(name, dunitVM);
       JUnit4DistributedTestCase.initializeBlackboard();
diff --git a/geode-dunit/src/main/java/org/apache/geode/test/dunit/internal/ChildVMLauncher.java b/geode-dunit/src/main/java/org/apache/geode/test/dunit/internal/ChildVMLauncher.java
index a161bd5..e2d5c4a 100644
--- a/geode-dunit/src/main/java/org/apache/geode/test/dunit/internal/ChildVMLauncher.java
+++ b/geode-dunit/src/main/java/org/apache/geode/test/dunit/internal/ChildVMLauncher.java
@@ -20,7 +20,7 @@ import java.rmi.RemoteException;
 
 public interface ChildVMLauncher {
 
-  ProcessHolder launchVM(String version, int vmNum, boolean bouncedVM)
+  ProcessHolder launchVM(String version, int vmNum, boolean bouncedVM, int remoteStubPort)
       throws IOException;
 
   RemoteDUnitVMIF getStub(int i) throws RemoteException, NotBoundException, InterruptedException;
diff --git a/geode-dunit/src/main/java/org/apache/geode/test/dunit/internal/DUnitHost.java b/geode-dunit/src/main/java/org/apache/geode/test/dunit/internal/DUnitHost.java
index 4695358..02ef017 100644
--- a/geode-dunit/src/main/java/org/apache/geode/test/dunit/internal/DUnitHost.java
+++ b/geode-dunit/src/main/java/org/apache/geode/test/dunit/internal/DUnitHost.java
@@ -32,7 +32,7 @@ class DUnitHost extends Host {
   DUnitHost(String hostName, ProcessManager processManager, VMEventNotifier vmEventNotifier)
       throws RemoteException {
     super(hostName, vmEventNotifier);
-    this.debuggingVM = new VM(this, VersionManager.CURRENT_VERSION, -1, new RemoteDUnitVM(), null,
+    this.debuggingVM = new VM(this, VersionManager.CURRENT_VERSION, -1, new RemoteDUnitVM(0), null,
         null);
     this.processManager = processManager;
     this.vmEventNotifier = vmEventNotifier;
@@ -104,7 +104,7 @@ class DUnitHost extends Host {
         }
 
         // now create the one we really want
-        processManager.launchVM(version, n, false);
+        processManager.launchVM(version, n, false, 0);
         processManager.waitForVMs(DUnitLauncher.STARTUP_TIMEOUT);
         addVM(n, version, processManager.getStub(n), processManager.getProcessHolder(n),
             processManager);
diff --git a/geode-dunit/src/main/java/org/apache/geode/test/dunit/internal/DUnitLauncher.java b/geode-dunit/src/main/java/org/apache/geode/test/dunit/internal/DUnitLauncher.java
index 69cbd97..9a14733 100644
--- a/geode-dunit/src/main/java/org/apache/geode/test/dunit/internal/DUnitLauncher.java
+++ b/geode-dunit/src/main/java/org/apache/geode/test/dunit/internal/DUnitLauncher.java
@@ -118,6 +118,7 @@ public class DUnitLauncher {
 
   static final String MASTER_PARAM = "DUNIT_MASTER";
 
+  public static final String REMOTE_STUB_PORT_PARAM = "DUnitLauncher.REMOTE_STUB_PORT";
   public static final String RMI_PORT_PARAM = GEMFIRE_PREFIX + "DUnitLauncher.RMI_PORT";
   public static final String RMI_HOST_PARAM = GEMFIRE_PREFIX + "DUnitLauncher.RMI_HOST";
   public static final String VM_NUM_PARAM = GEMFIRE_PREFIX + "DUnitLauncher.VM_NUM";
diff --git a/geode-dunit/src/main/java/org/apache/geode/test/dunit/internal/Master.java b/geode-dunit/src/main/java/org/apache/geode/test/dunit/internal/Master.java
index fde4a90..a97c433 100644
--- a/geode-dunit/src/main/java/org/apache/geode/test/dunit/internal/Master.java
+++ b/geode-dunit/src/main/java/org/apache/geode/test/dunit/internal/Master.java
@@ -14,13 +14,10 @@
  */
 package org.apache.geode.test.dunit.internal;
 
-import java.rmi.NotBoundException;
 import java.rmi.RemoteException;
 import java.rmi.registry.Registry;
 import java.rmi.server.UnicastRemoteObject;
 
-import org.apache.geode.test.dunit.VM;
-import org.apache.geode.test.version.VersionManager;
 
 public class Master extends UnicastRemoteObject implements MasterRemote {
   private static final long serialVersionUID = 1178600200232603119L;
@@ -49,26 +46,4 @@ public class Master extends UnicastRemoteObject implements MasterRemote {
     // do nothing
   }
 
-  @Override
-  public BounceResult bounce(int pid) {
-    return bounce(VersionManager.CURRENT_VERSION, pid, false);
-  }
-
-  @Override
-  public BounceResult bounce(String version, int pid, boolean force) {
-    processManager.bounce(version, pid, force);
-
-    try {
-      if (!processManager.waitForVMs(DUnitLauncher.STARTUP_TIMEOUT)) {
-        throw new RuntimeException(DUnitLauncher.STARTUP_TIMEOUT_MESSAGE);
-      }
-      RemoteDUnitVMIF remote =
-          (RemoteDUnitVMIF) registry.lookup(VM.getVMName(VersionManager.CURRENT_VERSION, pid));
-      return new BounceResult(pid, remote);
-    } catch (RemoteException | NotBoundException e) {
-      throw new RuntimeException("could not lookup name", e);
-    } catch (InterruptedException e) {
-      throw new RuntimeException("Failed waiting for VM", e);
-    }
-  }
 }
diff --git a/geode-dunit/src/main/java/org/apache/geode/test/dunit/internal/MasterRemote.java b/geode-dunit/src/main/java/org/apache/geode/test/dunit/internal/MasterRemote.java
index f613f7e..38bc17a 100644
--- a/geode-dunit/src/main/java/org/apache/geode/test/dunit/internal/MasterRemote.java
+++ b/geode-dunit/src/main/java/org/apache/geode/test/dunit/internal/MasterRemote.java
@@ -25,7 +25,4 @@ public interface MasterRemote extends Remote {
 
   void ping() throws RemoteException;
 
-  BounceResult bounce(int pid) throws RemoteException;
-
-  BounceResult bounce(String version, int pid, boolean force) throws RemoteException;
 }
diff --git a/geode-dunit/src/main/java/org/apache/geode/test/dunit/internal/ProcessManager.java b/geode-dunit/src/main/java/org/apache/geode/test/dunit/internal/ProcessManager.java
index 209c822..c9c04e4 100755
--- a/geode-dunit/src/main/java/org/apache/geode/test/dunit/internal/ProcessManager.java
+++ b/geode-dunit/src/main/java/org/apache/geode/test/dunit/internal/ProcessManager.java
@@ -60,12 +60,12 @@ class ProcessManager implements ChildVMLauncher {
   }
 
   public synchronized void launchVM(int vmNum) throws IOException {
-    launchVM(VersionManager.CURRENT_VERSION, vmNum, false);
+    launchVM(VersionManager.CURRENT_VERSION, vmNum, false, 0);
   }
 
   @Override
-  public synchronized ProcessHolder launchVM(String version, int vmNum, boolean bouncedVM)
-      throws IOException {
+  public synchronized ProcessHolder launchVM(String version, int vmNum, boolean bouncedVM,
+      int remoteStubPort) throws IOException {
     if (bouncedVM) {
       processes.remove(vmNum);
     }
@@ -88,7 +88,7 @@ class ProcessManager implements ChildVMLauncher {
       workingDir.mkdirs();
     }
 
-    String[] cmd = buildJavaCommand(vmNum, namingPort, version);
+    String[] cmd = buildJavaCommand(vmNum, namingPort, version, remoteStubPort);
     System.out.println("Executing " + Arrays.toString(cmd));
 
     if (log4jConfig != null) {
@@ -141,26 +141,6 @@ class ProcessManager implements ChildVMLauncher {
     return false;
   }
 
-  @Deprecated
-  public synchronized void bounce(String version, int vmNum, boolean force) {
-    if (!processes.containsKey(vmNum)) {
-      throw new IllegalStateException("No such process " + vmNum);
-    }
-    try {
-      ProcessHolder holder = processes.remove(vmNum);
-      if (force) {
-        holder.killForcibly();
-      } else {
-        holder.kill();
-      }
-      holder.waitFor();
-      System.out.println("Old process for vm_" + vmNum + " has exited");
-      launchVM(version, vmNum, true);
-    } catch (InterruptedException | IOException e) {
-      throw new RuntimeException("Unable to restart VM " + vmNum, e);
-    }
-  }
-
   private void linkStreams(final String version, final int vmNum, final ProcessHolder holder,
       final InputStream in, final PrintStream out) {
     final String vmName = "[" + VM.getVMName(version, vmNum) + "] ";
@@ -246,7 +226,7 @@ class ProcessManager implements ChildVMLauncher {
     return classpath;
   }
 
-  private String[] buildJavaCommand(int vmNum, int namingPort, String version) {
+  private String[] buildJavaCommand(int vmNum, int namingPort, String version, int remoteStubPort) {
     String cmd = System.getProperty("java.home") + File.separator
         + "bin" + File.separator + "java";
     String dunitClasspath = System.getProperty("java.class.path");
@@ -280,6 +260,7 @@ class ProcessManager implements ChildVMLauncher {
     String jreLib = separator + "jre" + separator + "lib" + separator;
     classPath = removeFromPath(classPath, jreLib);
     cmds.add(classPath);
+    cmds.add("-D" + DUnitLauncher.REMOTE_STUB_PORT_PARAM + "=" + remoteStubPort);
     cmds.add("-D" + DUnitLauncher.RMI_PORT_PARAM + "=" + namingPort);
     cmds.add("-D" + DUnitLauncher.VM_NUM_PARAM + "=" + vmNum);
     cmds.add("-D" + DUnitLauncher.VM_VERSION_PARAM + "=" + version);
diff --git a/geode-dunit/src/main/java/org/apache/geode/test/dunit/internal/RemoteDUnitVM.java b/geode-dunit/src/main/java/org/apache/geode/test/dunit/internal/RemoteDUnitVM.java
index 49473cb..3033d15 100644
--- a/geode-dunit/src/main/java/org/apache/geode/test/dunit/internal/RemoteDUnitVM.java
+++ b/geode-dunit/src/main/java/org/apache/geode/test/dunit/internal/RemoteDUnitVM.java
@@ -26,8 +26,8 @@ import org.apache.geode.logging.internal.log4j.api.LogService;
 class RemoteDUnitVM extends UnicastRemoteObject implements RemoteDUnitVMIF {
   private static final Logger logger = LogService.getLogger();
 
-  RemoteDUnitVM() throws RemoteException {
-    // super
+  RemoteDUnitVM(int port) throws RemoteException {
+    super(port);
   }
 
   /**
diff --git a/geode-dunit/src/main/java/org/apache/geode/test/dunit/internal/StandAloneDUnitEnv.java b/geode-dunit/src/main/java/org/apache/geode/test/dunit/internal/StandAloneDUnitEnv.java
index ee6542b..0ebd2e7 100644
--- a/geode-dunit/src/main/java/org/apache/geode/test/dunit/internal/StandAloneDUnitEnv.java
+++ b/geode-dunit/src/main/java/org/apache/geode/test/dunit/internal/StandAloneDUnitEnv.java
@@ -15,7 +15,6 @@
 package org.apache.geode.test.dunit.internal;
 
 import java.io.File;
-import java.rmi.RemoteException;
 import java.util.Properties;
 
 import org.apache.geode.test.dunit.DUnitEnv;
@@ -55,11 +54,6 @@ public class StandAloneDUnitEnv extends DUnitEnv {
   }
 
   @Override
-  public BounceResult bounce(String version, int pid, boolean force) throws RemoteException {
-    return master.bounce(version, pid, force);
-  }
-
-  @Override
   public File getWorkingDirectory(int pid) {
     return getWorkingDirectory(VersionManager.CURRENT_VERSION, pid);
   }