You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by kl...@apache.org on 2017/08/11 17:12:03 UTC

[05/14] geode git commit: GEODE-3413: overhaul launcher and process classes and tests

http://git-wip-us.apache.org/repos/asf/geode/blob/894f3ee7/geode-core/src/test/java/org/apache/geode/distributed/ServerLauncherRemoteIntegrationTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/distributed/ServerLauncherRemoteIntegrationTest.java b/geode-core/src/test/java/org/apache/geode/distributed/ServerLauncherRemoteIntegrationTest.java
index d59cde1..733a108 100755
--- a/geode-core/src/test/java/org/apache/geode/distributed/ServerLauncherRemoteIntegrationTest.java
+++ b/geode-core/src/test/java/org/apache/geode/distributed/ServerLauncherRemoteIntegrationTest.java
@@ -14,1451 +14,304 @@
  */
 package org.apache.geode.distributed;
 
+import static org.apache.geode.distributed.AbstractLauncher.Status.NOT_RESPONDING;
+import static org.apache.geode.distributed.AbstractLauncher.Status.ONLINE;
+import static org.apache.geode.distributed.AbstractLauncher.Status.STOPPED;
 import static org.apache.geode.distributed.ConfigurationProperties.CACHE_XML_FILE;
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.CoreMatchers.notNullValue;
-import static org.hamcrest.CoreMatchers.nullValue;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
+import static org.apache.geode.distributed.internal.DistributionConfig.GEMFIRE_PREFIX;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
 import java.io.File;
-import java.io.FileOutputStream;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.io.PrintWriter;
-import java.lang.management.ManagementFactory;
+import java.net.BindException;
 import java.net.InetAddress;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicBoolean;
 
-import org.junit.Ignore;
+import org.junit.Before;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
-import org.apache.geode.cache.DataPolicy;
-import org.apache.geode.cache.Scope;
-import org.apache.geode.distributed.AbstractLauncher.Status;
 import org.apache.geode.distributed.ServerLauncher.Builder;
 import org.apache.geode.distributed.ServerLauncher.ServerState;
-import org.apache.geode.distributed.internal.DistributionConfig;
-import org.apache.geode.internal.AvailablePort;
-import org.apache.geode.internal.AvailablePortHelper;
-import org.apache.geode.internal.ExitCode;
 import org.apache.geode.internal.GemFireVersion;
-import org.apache.geode.internal.cache.AbstractCacheServer;
-import org.apache.geode.internal.cache.xmlcache.CacheCreation;
-import org.apache.geode.internal.cache.xmlcache.CacheXmlGenerator;
-import org.apache.geode.internal.cache.xmlcache.RegionAttributesCreation;
-import org.apache.geode.internal.logging.InternalLogWriter;
-import org.apache.geode.internal.logging.LocalLogWriter;
-import org.apache.geode.internal.net.SocketCreatorFactory;
-import org.apache.geode.internal.process.PidUnavailableException;
 import org.apache.geode.internal.process.ProcessControllerFactory;
-import org.apache.geode.internal.process.ProcessStreamReader;
-import org.apache.geode.internal.process.ProcessType;
-import org.apache.geode.internal.process.ProcessUtils;
-import org.apache.geode.test.junit.categories.FlakyTest;
 import org.apache.geode.test.junit.categories.IntegrationTest;
-import org.apache.geode.test.process.ProcessWrapper;
 
 /**
- * Integration tests for launching a Server in a forked process.
+ * Integration tests for using {@code ServerLauncher} as an application main in a forked JVM.
  *
- * @see org.apache.geode.distributed.AbstractLauncher
- * @see org.apache.geode.distributed.ServerLauncher
- * @see org.apache.geode.distributed.ServerLauncher.Builder
- * @see org.apache.geode.distributed.ServerLauncher.ServerState
- * @see org.apache.geode.internal.AvailablePortHelper
  * @since GemFire 8.0
  */
 @Category(IntegrationTest.class)
-public class ServerLauncherRemoteIntegrationTest
-    extends AbstractServerLauncherRemoteIntegrationTestCase {
+public class ServerLauncherRemoteIntegrationTest extends ServerLauncherRemoteIntegrationTestCase {
 
-  @Test
-  public void testIsAttachAPIFound() throws Exception {
-    final ProcessControllerFactory factory = new ProcessControllerFactory();
-    assertTrue(factory.isAttachAPIFound());
+  @Before
+  public void setUpServerLauncherRemoteIntegrationTest() throws Exception {
+    assertThat(new ProcessControllerFactory().isAttachAPIFound()).isTrue();
   }
 
   @Test
-  @Ignore("TRAC bug #52304: test is broken and needs to be reworked")
-  public void testRunningServerOutlivesForkingProcess() throws Throwable {
-    // launch ServerLauncherForkingProcess which then launches server
-
-    // final List<String> command = new ArrayList<String>();
-    // command.add(new File(new File(System.getProperty("java.home"), "bin"),
-    // "java").getCanonicalPath());
-    // command.add("-cp");
-    // command.add(System.getProperty("java.class.path"));
-    // command.add(ServerLauncherDUnitTest.class.getName().concat("$").concat(ServerLauncherForkingProcess.class.getSimpleName()));
-    //
-    // process = new ProcessBuilder(command).directory(temporaryFolder.getRoot()).start();
-    // assertNotNull(process);
-    // processOutReader = new ProcessStreamReader(process.getInputStream(), createListener("sysout",
-    // getUniqueName() + "#sysout")).start();
-    // processErrReader = new ProcessStreamReader(process.getErrorStream(), createListener("syserr",
-    // getUniqueName() + "#syserr")).start();
-
-    @SuppressWarnings("unused")
-    File file = new File(this.temporaryFolder.getRoot(),
-        ServerLauncherForkingProcess.class.getSimpleName().concat(".log"));
-    // -logger.info("log file is " + file);
-
-    final ProcessWrapper pw =
-        new ProcessWrapper.Builder().mainClass(ServerLauncherForkingProcess.class).build();
-    pw.execute(null, this.temporaryFolder.getRoot()).waitFor(true);
-    // logger.info("[testRunningServerOutlivesForkingProcess] ServerLauncherForkingProcess output
-    // is:\n\n"+pw.getOutput());
-
-    // // create waiting thread since waitFor does not have a timeout
-    // Thread waiting = new Thread(new Runnable() {
-    // @Override
-    // public void run() {
-    // try {
-    // assertIndexDetailsEquals(0, process.waitFor());
-    // } catch (InterruptedException e) {
-    // logger.error("Interrupted while waiting for process", e);
-    // }
-    // }
-    // });
-
-    // // start waiting thread and join to it for timeout
-    // try {
-    // waiting.start();
-    // waiting.join(TIMEOUT_MILLISECONDS);
-    // assertFalse("ServerLauncherForkingProcess took too long and caused timeout",
-    // waiting.isAlive());
-    //
-    // } catch (Throwable e) {
-    // logger.error(e);
-    // if (failure == null) {
-    // failure = e;
-    // }
-    // } finally {
-    // if (waiting.isAlive()) {
-    // waiting.interrupt();
-    // }
-    // }
-
-    // wait for server to start
-    int pid = 0;
-    final String serverName = ServerLauncherForkingProcess.class.getSimpleName() + "_server";
-    final ServerLauncher dirLauncher = new ServerLauncher.Builder()
-        .setWorkingDirectory(this.temporaryFolder.getRoot().getCanonicalPath()).build();
-    try {
-      waitForServerToStart(dirLauncher);
-
-      // validate the pid file and its contents
-      this.pidFile = new File(this.temporaryFolder.getRoot(), ProcessType.SERVER.getPidFileName());
-      assertTrue(this.pidFile.exists());
-      pid = readPid(this.pidFile);
-      assertTrue(pid > 0);
-      assertTrue(ProcessUtils.isProcessAlive(pid));
-
-      // validate log file was created
-      final String logFileName = serverName + ".log";
-      assertTrue("Log file should exist: " + logFileName,
-          new File(this.temporaryFolder.getRoot(), logFileName).exists());
-
-      // validate the status
-      final ServerState actualStatus = dirLauncher.status();
-      assertNotNull(actualStatus);
-      assertEquals(Status.ONLINE, actualStatus.getStatus());
-      assertEquals(pid, actualStatus.getPid().intValue());
-      assertTrue(actualStatus.getUptime() > 0);
-      assertEquals(this.temporaryFolder.getRoot().getCanonicalPath(),
-          actualStatus.getWorkingDirectory());
-      assertEquals(getJvmArguments(), actualStatus.getJvmArguments());
-      assertEquals(ManagementFactory.getRuntimeMXBean().getClassPath(),
-          actualStatus.getClasspath());
-      assertEquals(GemFireVersion.getGemFireVersion(), actualStatus.getGemFireVersion());
-      assertEquals(System.getProperty("java.version"), actualStatus.getJavaVersion());
-      assertEquals(
-          this.temporaryFolder.getRoot().getCanonicalPath() + File.separator + serverName + ".log",
-          actualStatus.getLogFile());
-      assertEquals(InetAddress.getLocalHost().getCanonicalHostName(), actualStatus.getHost());
-      assertEquals(serverName, actualStatus.getMemberName());
-
-    } catch (Throwable e) {
-      this.errorCollector.addError(e);
-    }
-
-    // stop the server
-    try {
-      assertEquals(Status.STOPPED, dirLauncher.stop().getStatus());
-      waitForPidToStop(pid);
-    } catch (Throwable e) {
-      this.errorCollector.addError(e);
-    }
+  public void startCreatesPidFile() throws Exception {
+    startServer();
+
+    assertThat(getPidFile()).exists();
   }
 
   @Test
-  public void testStartCreatesPidFile() throws Throwable {
-    // build and start the server
-    final List<String> jvmArguments = getJvmArguments();
-
-    final List<String> command = new ArrayList<String>();
-    command
-        .add(new File(new File(System.getProperty("java.home"), "bin"), "java").getCanonicalPath());
-    for (String jvmArgument : jvmArguments) {
-      command.add(jvmArgument);
-    }
-    command.add("-cp");
-    command.add(System.getProperty("java.class.path"));
-    command.add(ServerLauncher.class.getName());
-    command.add(ServerLauncher.Command.START.getName());
-    command.add(getUniqueName());
-    command.add("--disable-default-server");
-    command.add("--redirect-output");
-
-    this.process = new ProcessBuilder(command).directory(this.temporaryFolder.getRoot()).start();
-    this.processOutReader = new ProcessStreamReader.Builder(this.process)
-        .inputStream(this.process.getInputStream()).build().start();
-    this.processErrReader = new ProcessStreamReader.Builder(this.process)
-        .inputStream(this.process.getErrorStream()).build().start();
-
-    int pid = 0;
-    this.launcher = new ServerLauncher.Builder()
-        .setWorkingDirectory(this.temporaryFolder.getRoot().getCanonicalPath()).build();
-    try {
-      waitForServerToStart();
-
-      // validate the pid file and its contents
-      this.pidFile = new File(this.temporaryFolder.getRoot(), ProcessType.SERVER.getPidFileName());
-      assertTrue(this.pidFile.exists());
-      pid = readPid(this.pidFile);
-      assertTrue(pid > 0);
-      assertTrue(ProcessUtils.isProcessAlive(pid));
-
-      final String logFileName = getUniqueName() + ".log";
-      assertTrue("Log file should exist: " + logFileName,
-          new File(this.temporaryFolder.getRoot(), logFileName).exists());
-
-      // check the status
-      final ServerState serverState = this.launcher.status();
-      assertNotNull(serverState);
-      assertEquals(Status.ONLINE, serverState.getStatus());
-
-    } catch (Throwable e) {
-      this.errorCollector.addError(e);
-    }
-
-    // stop the server
-    try {
-      assertEquals(Status.STOPPED, this.launcher.stop().getStatus());
-      waitForPidToStop(pid);
-    } catch (Throwable e) {
-      this.errorCollector.addError(e);
-    }
+  public void pidFileContainsServerPid() throws Exception {
+    startServer();
+
+    assertThatPidIsAlive(getServerPid());
   }
 
   @Test
-  public void testStartDeletesStaleControlFiles() throws Throwable {
-    // create existing control files
-    this.stopRequestFile =
-        new File(this.temporaryFolder.getRoot(), ProcessType.SERVER.getStopRequestFileName());
-    this.stopRequestFile.createNewFile();
-    assertTrue(this.stopRequestFile.exists());
-
-    this.statusRequestFile =
-        new File(this.temporaryFolder.getRoot(), ProcessType.SERVER.getStatusRequestFileName());
-    this.statusRequestFile.createNewFile();
-    assertTrue(this.statusRequestFile.exists());
-
-    this.statusFile =
-        new File(this.temporaryFolder.getRoot(), ProcessType.SERVER.getStatusFileName());
-    this.statusFile.createNewFile();
-    assertTrue(this.statusFile.exists());
-
-    // build and start the server
-    final List<String> jvmArguments = getJvmArguments();
-
-    final List<String> command = new ArrayList<String>();
-    command
-        .add(new File(new File(System.getProperty("java.home"), "bin"), "java").getCanonicalPath());
-    for (String jvmArgument : jvmArguments) {
-      command.add(jvmArgument);
-    }
-    command.add("-cp");
-    command.add(System.getProperty("java.class.path"));
-    command.add(ServerLauncher.class.getName());
-    command.add(ServerLauncher.Command.START.getName());
-    command.add(getUniqueName());
-    command.add("--disable-default-server");
-    command.add("--redirect-output");
-
-    this.process = new ProcessBuilder(command).directory(this.temporaryFolder.getRoot()).start();
-    this.processOutReader = new ProcessStreamReader.Builder(this.process)
-        .inputStream(this.process.getInputStream()).build().start();
-    this.processErrReader = new ProcessStreamReader.Builder(this.process)
-        .inputStream(this.process.getErrorStream()).build().start();
-
-    // wait for server to start
-    int pid = 0;
-    this.launcher = new ServerLauncher.Builder()
-        .setWorkingDirectory(this.temporaryFolder.getRoot().getCanonicalPath()).build();
-    try {
-      waitForServerToStart();
-
-      // validate the pid file and its contents
-      this.pidFile = new File(this.temporaryFolder.getRoot(), ProcessType.SERVER.getPidFileName());
-      assertTrue(this.pidFile.exists());
-      pid = readPid(this.pidFile);
-      assertTrue(pid > 0);
-      assertTrue(ProcessUtils.isProcessAlive(pid));
-
-      // validate stale control files were deleted
-      waitForFileToDelete(this.stopRequestFile);
-      waitForFileToDelete(this.statusRequestFile);
-      waitForFileToDelete(this.statusFile);
-
-      // validate log file was created
-      final String logFileName = getUniqueName() + ".log";
-      assertTrue("Log file should exist: " + logFileName,
-          new File(this.temporaryFolder.getRoot(), logFileName).exists());
-
-    } catch (Throwable e) {
-      this.errorCollector.addError(e);
-    }
-
-    // stop the server
-    try {
-      assertEquals(Status.STOPPED, this.launcher.stop().getStatus());
-      waitForPidToStop(pid);
-    } catch (Throwable e) {
-      this.errorCollector.addError(e);
-    }
+  public void startCreatesLogFile() throws Exception {
+    startServer();
+
+    assertThat(getLogFile()).exists();
   }
 
-  @Category(FlakyTest.class) // GEODE-721: random ports (setup overriding default port),
-                             // TemporaryFolder
   @Test
-  public void testStartOverwritesStalePidFile() throws Throwable {
-    // create existing pid file
-    this.pidFile = new File(this.temporaryFolder.getRoot(), ProcessType.SERVER.getPidFileName());
-    writePid(this.pidFile, Integer.MAX_VALUE);
-
-    // build and start the server
-    final List<String> jvmArguments = getJvmArguments();
-
-    final List<String> command = new ArrayList<String>();
-    command
-        .add(new File(new File(System.getProperty("java.home"), "bin"), "java").getCanonicalPath());
-    for (String jvmArgument : jvmArguments) {
-      command.add(jvmArgument);
-    }
-    command.add("-cp");
-    command.add(System.getProperty("java.class.path"));
-    command.add(ServerLauncher.class.getName());
-    command.add(ServerLauncher.Command.START.getName());
-    command.add(getUniqueName());
-    command.add("--disable-default-server");
-    command.add("--redirect-output");
-
-    this.process = new ProcessBuilder(command).directory(this.temporaryFolder.getRoot()).start();
-    this.processOutReader = new ProcessStreamReader.Builder(this.process)
-        .inputStream(this.process.getInputStream()).build().start();
-    this.processErrReader = new ProcessStreamReader.Builder(this.process)
-        .inputStream(this.process.getErrorStream()).build().start();
-
-    int pid = 0;
-    this.launcher = new ServerLauncher.Builder()
-        .setWorkingDirectory(this.temporaryFolder.getRoot().getCanonicalPath()).build();
-    try {
-      waitForServerToStart();
-
-      // validate the pid file and its contents
-      assertTrue(this.pidFile.exists());
-      pid = readPid(this.pidFile);
-      assertTrue(pid > 0);
-      assertTrue(ProcessUtils.isProcessAlive(pid));
-      assertFalse(pid == Integer.MAX_VALUE);
-
-      final String logFileName = getUniqueName() + ".log";
-      assertTrue("Log file should exist: " + logFileName,
-          new File(this.temporaryFolder.getRoot(), logFileName).exists());
-
-    } catch (Throwable e) {
-      this.errorCollector.addError(e);
-    }
-
-    // stop the server
-    try {
-      assertEquals(Status.STOPPED, this.launcher.stop().getStatus());
-      waitForPidToStop(pid);
-    } catch (Throwable e) {
-      this.errorCollector.addError(e);
-    }
+  public void startDeletesStaleControlFiles() throws Exception {
+    File stopRequestFile = givenControlFile(getStopRequestFileName());
+    File statusRequestFile = givenControlFile(getStatusRequestFileName());
+    File statusFile = givenControlFile(getStatusFileName());
+
+    startServer();
+
+    assertDeletionOf(stopRequestFile);
+    assertDeletionOf(statusRequestFile);
+    assertDeletionOf(statusFile);
   }
 
   /**
-   * Confirms fix for #47778.
+   * This test takes > 1 minute to run in {@link ServerLauncherRemoteFileIntegrationTest}.
    */
   @Test
-  public void testStartUsingDisableDefaultServerLeavesPortFree() throws Throwable {
-    assertTrue(AvailablePort.isPortAvailable(this.serverPort, AvailablePort.SOCKET));
-
-    // build and start the server
-    final List<String> jvmArguments = getJvmArguments();
-    jvmArguments.add(
-        "-D" + AbstractCacheServer.TEST_OVERRIDE_DEFAULT_PORT_PROPERTY + "=" + this.serverPort);
-
-    final List<String> command = new ArrayList<String>();
-    command
-        .add(new File(new File(System.getProperty("java.home"), "bin"), "java").getCanonicalPath());
-    for (String jvmArgument : jvmArguments) {
-      command.add(jvmArgument);
-    }
-    command.add("-cp");
-    command.add(System.getProperty("java.class.path"));
-    command.add(ServerLauncher.class.getName());
-    command.add(ServerLauncher.Command.START.getName());
-    command.add(getUniqueName());
-    command.add("--disable-default-server");
-    command.add("--redirect-output");
-
-    this.process = new ProcessBuilder(command).directory(this.temporaryFolder.getRoot()).start();
-    this.processOutReader = new ProcessStreamReader.Builder(this.process)
-        .inputStream(this.process.getInputStream()).build().start();
-    this.processErrReader = new ProcessStreamReader.Builder(this.process)
-        .inputStream(this.process.getErrorStream()).build().start();
-
-    // wait for server to start
-    int pid = 0;
-    this.launcher = new ServerLauncher.Builder()
-        .setWorkingDirectory(this.temporaryFolder.getRoot().getCanonicalPath()).build();
-    try {
-      waitForServerToStart();
-
-      // validate the pid file and its contents
-      this.pidFile = new File(this.temporaryFolder.getRoot(), ProcessType.SERVER.getPidFileName());
-      assertTrue(this.pidFile.exists());
-      pid = readPid(this.pidFile);
-      assertTrue(pid > 0);
-      assertTrue(ProcessUtils.isProcessAlive(pid));
-
-      // validate log file was created
-      final String logFileName = getUniqueName() + ".log";
-      assertTrue("Log file should exist: " + logFileName,
-          new File(this.temporaryFolder.getRoot(), logFileName).exists());
-
-      // verify server did not a port
-      assertTrue(AvailablePort.isPortAvailable(this.serverPort, AvailablePort.SOCKET));
-
-      final ServerState status = this.launcher.status();
-      final String portString = status.getPort();
-      assertEquals("Port should be \"\" instead of " + portString, "", portString);
-
-    } catch (Throwable e) {
-      this.errorCollector.addError(e);
-    }
-
-    // stop the server
-    try {
-      assertEquals(Status.STOPPED, this.launcher.stop().getStatus());
-      waitForPidToStop(pid);
-    } catch (Throwable e) {
-      this.errorCollector.addError(e);
-    }
+  public void startOverwritesStalePidFile() throws Exception {
+    givenPidFile(fakePid);
+
+    startServer();
+
+    assertThat(getServerPid()).isNotEqualTo(fakePid);
   }
 
   @Test
-  public void testStartUsingDisableDefaultServerSkipsPortCheck() throws Throwable {
-    // make serverPort in use
-    this.socket = SocketCreatorFactory
-        .createNonDefaultInstance(false, false, null, null, System.getProperties())
-        .createServerSocket(this.serverPort, 50, null, -1);
-    assertFalse(AvailablePort.isPortAvailable(this.serverPort, AvailablePort.SOCKET));
-
-    // build and start the server
-    final List<String> jvmArguments = getJvmArguments();
-    jvmArguments.add(
-        "-D" + AbstractCacheServer.TEST_OVERRIDE_DEFAULT_PORT_PROPERTY + "=" + this.serverPort);
-
-    final List<String> command = new ArrayList<String>();
-    command
-        .add(new File(new File(System.getProperty("java.home"), "bin"), "java").getCanonicalPath());
-    for (String jvmArgument : jvmArguments) {
-      command.add(jvmArgument);
-    }
-    command.add("-cp");
-    command.add(System.getProperty("java.class.path"));
-    command.add(ServerLauncher.class.getName());
-    command.add(ServerLauncher.Command.START.getName());
-    command.add(getUniqueName());
-    command.add("--disable-default-server");
-    command.add("--redirect-output");
-
-    this.process = new ProcessBuilder(command).directory(this.temporaryFolder.getRoot()).start();
-    this.processOutReader = new ProcessStreamReader.Builder(this.process)
-        .inputStream(this.process.getInputStream()).build().start();
-    this.processErrReader = new ProcessStreamReader.Builder(this.process)
-        .inputStream(this.process.getErrorStream()).build().start();
-
-    // wait for server to start
-    int pid = 0;
-    this.launcher = new ServerLauncher.Builder()
-        .setWorkingDirectory(this.temporaryFolder.getRoot().getCanonicalPath()).build();
-    try {
-      waitForServerToStart();
-
-      // validate log file was created
-      final String logFileName = getUniqueName() + ".log";
-      assertTrue("Log file should exist: " + logFileName,
-          new File(this.temporaryFolder.getRoot(), logFileName).exists());
-
-      final ServerState status = this.launcher.status();
-      final String portString = status.getPort();
-      assertEquals("Port should be \"\" instead of " + portString, "", portString);
-
-    } catch (Throwable e) {
-      this.errorCollector.addError(e);
-    }
-
-    // stop the server
-    try {
-      assertEquals(Status.STOPPED, this.launcher.stop().getStatus());
-      waitForPidToStop(pid);
-    } catch (Throwable e) {
-      this.errorCollector.addError(e);
-    }
-
-    // verify port is still in use
-    this.errorCollector.checkThat(
-        AvailablePort.isPortAvailable(this.serverPort, AvailablePort.SOCKET), is(equalTo(false)));
+  public void startWithDisableDefaultServerDoesNotUseDefaultPort() throws Exception {
+    givenServerPortIsFree(defaultServerPort);
+
+    startServer(withDisableDefaultServer());
+
+    assertThatServerPortIsFree(defaultServerPort);
   }
 
-  @Category(FlakyTest.class) // GEODE-764: random ports, BindException, forks JVM, uses
-                             // ErrorCollector
   @Test
-  public void testStartUsingForceOverwritesExistingPidFile() throws Throwable {
-    // create existing pid file
-    this.pidFile = new File(this.temporaryFolder.getRoot(), ProcessType.SERVER.getPidFileName());
-    final int otherPid = getPid();
-    assertTrue("Pid " + otherPid + " should be alive", ProcessUtils.isProcessAlive(otherPid));
-    writePid(this.pidFile, otherPid);
-
-    // build and start the server
-    final List<String> jvmArguments = getJvmArguments();
-
-    final List<String> command = new ArrayList<String>();
-    command
-        .add(new File(new File(System.getProperty("java.home"), "bin"), "java").getCanonicalPath());
-    for (String jvmArgument : jvmArguments) {
-      command.add(jvmArgument);
-    }
-    command.add("-cp");
-    command.add(System.getProperty("java.class.path"));
-    command.add(ServerLauncher.class.getName());
-    command.add(ServerLauncher.Command.START.getName());
-    command.add(getUniqueName());
-    command.add("--disable-default-server");
-    command.add("--redirect-output");
-    command.add("--force");
-
-    this.process = new ProcessBuilder(command).directory(this.temporaryFolder.getRoot()).start();
-    this.processOutReader = new ProcessStreamReader.Builder(this.process)
-        .inputStream(this.process.getInputStream()).build().start();
-    this.processErrReader = new ProcessStreamReader.Builder(this.process)
-        .inputStream(this.process.getErrorStream()).build().start();
-
-    // wait for server to start
-    int pid = 0;
-    this.launcher = new ServerLauncher.Builder()
-        .setWorkingDirectory(this.temporaryFolder.getRoot().getCanonicalPath()).build();
-    try {
-      waitForServerToStart();
-
-      // validate the pid file and its contents
-      assertTrue(this.pidFile.exists());
-      pid = readPid(this.pidFile);
-      assertTrue(pid > 0);
-      assertTrue(ProcessUtils.isProcessAlive(pid));
-      assertTrue(pid != otherPid);
-
-      // validate log file was created
-      final String logFileName = getUniqueName() + ".log";
-      assertTrue("Log file should exist: " + logFileName,
-          new File(this.temporaryFolder.getRoot(), logFileName).exists());
-
-    } catch (Throwable e) {
-      this.errorCollector.addError(e);
-    }
-
-    // stop the server
-    try {
-      assertEquals(Status.STOPPED, this.launcher.stop().getStatus());
-      waitForPidToStop(pid);
-    } catch (Throwable e) {
-      this.errorCollector.addError(e);
-    }
+  public void startWithDisableDefaultServerSucceedsWhenDefaultPortInUse() throws Exception {
+    givenServerPortInUse(defaultServerPort);
+
+    startServer(withDisableDefaultServer());
+
+    assertThatServerPortIsInUseBySocket(defaultServerPort);
   }
 
   /**
-   * Confirms fix for #47665.
+   * This test takes > 1 minute to run in {@link ServerLauncherRemoteFileIntegrationTest}.
    */
   @Test
-  public void testStartUsingServerPortInUseFails() throws Throwable {
-    // make serverPort in use
-    this.socket = SocketCreatorFactory
-        .createNonDefaultInstance(false, false, null, null, System.getProperties())
-        .createServerSocket(this.serverPort, 50, null, -1);
-    assertFalse(AvailablePort.isPortAvailable(this.serverPort, AvailablePort.SOCKET));
-
-    final List<String> jvmArguments = getJvmArguments();
-
-    final List<String> command = new ArrayList<String>();
-    command
-        .add(new File(new File(System.getProperty("java.home"), "bin"), "java").getCanonicalPath());
-    for (String jvmArgument : jvmArguments) {
-      command.add(jvmArgument);
-    }
-    command.add("-cp");
-    command.add(System.getProperty("java.class.path"));
-    command.add(ServerLauncher.class.getName());
-    command.add(ServerLauncher.Command.START.getName());
-    command.add(getUniqueName());
-    command.add("--redirect-output");
-    command.add("--server-port=" + this.serverPort);
-
-    String expectedString = "java.net.BindException";
-    AtomicBoolean outputContainedExpectedString = new AtomicBoolean();
-
-    this.process = new ProcessBuilder(command).directory(this.temporaryFolder.getRoot()).start();
-    this.processOutReader = new ProcessStreamReader.Builder(this.process)
-        .inputStream(this.process.getInputStream()).inputListener(createExpectedListener("sysout",
-            getUniqueName() + "#sysout", expectedString, outputContainedExpectedString))
-        .build().start();
-    this.processErrReader = new ProcessStreamReader.Builder(this.process)
-        .inputStream(this.process.getErrorStream()).inputListener(createExpectedListener("syserr",
-            getUniqueName() + "#syserr", expectedString, outputContainedExpectedString))
-        .build().start();
-
-    // wait for server to start and fail
-    final ServerLauncher dirLauncher = new ServerLauncher.Builder()
-        .setWorkingDirectory(this.temporaryFolder.getRoot().getCanonicalPath()).build();
-    try {
-      int code = this.process.waitFor();
-      assertEquals("Expected exit code 1 but was " + code, 1, code);
-    } catch (Throwable e) {
-      this.errorCollector.addError(e);
-    }
-
-    try {
-      // check the status
-      final ServerState serverState = dirLauncher.status();
-      assertNotNull(serverState);
-      assertEquals(Status.NOT_RESPONDING, serverState.getStatus());
-
-      final String logFileName = getUniqueName() + ".log";
-      assertFalse("Log file should exist: " + logFileName,
-          new File(this.temporaryFolder.getRoot(), logFileName).exists());
-
-    } catch (Throwable e) {
-      this.errorCollector.addError(e);
-    }
-
-    // if the following fails, then the SHORTER_TIMEOUT is too short for slow machines
-    // or this test needs to use MainLauncher in ProcessWrapper
-
-    // validate that output contained BindException
-    this.errorCollector.checkThat(outputContainedExpectedString.get(), is(equalTo(true)));
-
-    // just in case the launcher started...
-    ServerState status = null;
-    try {
-      status = dirLauncher.stop();
-    } catch (Throwable t) {
-      // ignore
-    }
-
-    try {
-      assertEquals(getExpectedStopStatusForNotRunning(), status.getStatus());
-    } catch (Throwable e) {
-      this.errorCollector.addError(e);
-    }
+  public void startWithForceOverwritesExistingPidFile() throws Exception {
+    givenPidFile(localPid);
+
+    startServer(withForce());
+
+    assertThatPidIsAlive(getServerPid());
+    assertThat(getServerPid()).isNotEqualTo(localPid);
   }
 
-  /**
-   * Confirms part of fix for #47664
-   */
   @Test
-  public void testStartUsingServerPortOverridesCacheXml() throws Throwable {
-    // generate two free ports
-    final int[] freeTCPPorts = AvailablePortHelper.getRandomAvailableTCPPorts(2);
-
-    // write out cache.xml with one port
-    final CacheCreation creation = new CacheCreation();
-    final RegionAttributesCreation attrs = new RegionAttributesCreation(creation);
-    attrs.setScope(Scope.DISTRIBUTED_ACK);
-    attrs.setDataPolicy(DataPolicy.REPLICATE);
-    creation.createRegion(getUniqueName(), attrs);
-    creation.addCacheServer().setPort(freeTCPPorts[0]);
-
-    File cacheXmlFile = new File(this.temporaryFolder.getRoot(), getUniqueName() + ".xml");
-    final PrintWriter pw = new PrintWriter(new FileWriter(cacheXmlFile), true);
-    CacheXmlGenerator.generate(creation, pw);
-    pw.close();
-
-    // launch server and specify a different port
-    final List<String> jvmArguments = getJvmArguments();
-    jvmArguments.add("-D" + DistributionConfig.GEMFIRE_PREFIX + "" + CACHE_XML_FILE + "="
-        + cacheXmlFile.getCanonicalPath());
-
-    final List<String> command = new ArrayList<String>();
-    command
-        .add(new File(new File(System.getProperty("java.home"), "bin"), "java").getCanonicalPath());
-    for (String jvmArgument : jvmArguments) {
-      command.add(jvmArgument);
-    }
-    command.add("-cp");
-    command.add(System.getProperty("java.class.path"));
-    command.add(ServerLauncher.class.getName());
-    command.add(ServerLauncher.Command.START.getName());
-    command.add(getUniqueName());
-    command.add("--redirect-output");
-    command.add("--server-port=" + freeTCPPorts[1]);
-
-    String expectedString = "java.net.BindException";
-    AtomicBoolean outputContainedExpectedString = new AtomicBoolean();
-
-    this.process = new ProcessBuilder(command).directory(this.temporaryFolder.getRoot()).start();
-    this.processOutReader = new ProcessStreamReader.Builder(this.process)
-        .inputStream(this.process.getInputStream()).inputListener(createExpectedListener("sysout",
-            getUniqueName() + "#sysout", expectedString, outputContainedExpectedString))
-        .build().start();
-    this.processErrReader = new ProcessStreamReader.Builder(this.process)
-        .inputStream(this.process.getErrorStream()).inputListener(createExpectedListener("syserr",
-            getUniqueName() + "#syserr", expectedString, outputContainedExpectedString))
-        .build().start();
-
-    // wait for server to start up
-    int pid = 0;
-    this.launcher = new ServerLauncher.Builder()
-        .setWorkingDirectory(this.temporaryFolder.getRoot().getCanonicalPath()).build();
-    try {
-      waitForServerToStart();
-
-      // validate the pid file and its contents
-      this.pidFile = new File(this.temporaryFolder.getRoot(), ProcessType.SERVER.getPidFileName());
-      assertTrue(this.pidFile.exists());
-      pid = readPid(this.pidFile);
-      assertTrue(pid > 0);
-      assertTrue(ProcessUtils.isProcessAlive(pid));
-
-      // validate log file was created
-      final String logFileName = getUniqueName() + ".log";
-      assertTrue("Log file should exist: " + logFileName,
-          new File(this.temporaryFolder.getRoot(), logFileName).exists());
-
-      // verify server used --server-port instead of default or port in cache.xml
-      assertTrue(AvailablePort.isPortAvailable(freeTCPPorts[0], AvailablePort.SOCKET));
-      assertFalse(AvailablePort.isPortAvailable(freeTCPPorts[1], AvailablePort.SOCKET));
-
-      ServerState status = this.launcher.status();
-      String portString = status.getPort();
-      int port = Integer.valueOf(portString);
-      assertEquals("Port should be " + freeTCPPorts[1] + " instead of " + port, freeTCPPorts[1],
-          port);
-
-    } catch (Throwable e) {
-      this.errorCollector.addError(e);
-    }
-
-    // stop the server
-    try {
-      assertEquals(Status.STOPPED, this.launcher.stop().getStatus());
-      waitForPidToStop(pid);
-      waitForFileToDelete(this.pidFile);
-
-    } catch (Throwable e) {
-      this.errorCollector.addError(e);
-    }
+  public void startWithServerPortInUseFailsWithBindException() throws Exception {
+    givenServerPortInUse(nonDefaultServerPort);
+
+    startServerShouldFail(withServerPort(nonDefaultServerPort));
+
+    assertThatServerThrew(BindException.class);
   }
 
-  /**
-   * Confirms part of fix for #47664
-   */
   @Test
-  public void testStartUsingServerPortUsedInsteadOfDefaultCacheXml() throws Throwable {
-    // write out cache.xml with one port
-    final CacheCreation creation = new CacheCreation();
-    final RegionAttributesCreation attrs = new RegionAttributesCreation(creation);
-    attrs.setScope(Scope.DISTRIBUTED_ACK);
-    attrs.setDataPolicy(DataPolicy.REPLICATE);
-    creation.createRegion(getUniqueName(), attrs);
-    creation.addCacheServer();
-
-    File cacheXmlFile = new File(this.temporaryFolder.getRoot(), getUniqueName() + ".xml");
-    final PrintWriter pw = new PrintWriter(new FileWriter(cacheXmlFile), true);
-    CacheXmlGenerator.generate(creation, pw);
-    pw.close();
-
-    // launch server and specify a different port
-    final List<String> jvmArguments = getJvmArguments();
-    jvmArguments.add("-D" + DistributionConfig.GEMFIRE_PREFIX + "" + CACHE_XML_FILE + "="
-        + cacheXmlFile.getCanonicalPath());
-
-    final List<String> command = new ArrayList<String>();
-    command
-        .add(new File(new File(System.getProperty("java.home"), "bin"), "java").getCanonicalPath());
-    for (String jvmArgument : jvmArguments) {
-      command.add(jvmArgument);
-    }
-    command.add("-cp");
-    command.add(System.getProperty("java.class.path"));
-    command.add(ServerLauncher.class.getName());
-    command.add(ServerLauncher.Command.START.getName());
-    command.add(getUniqueName());
-    command.add("--redirect-output");
-    command.add("--server-port=" + this.serverPort);
-
-    final String expectedString = "java.net.BindException";
-    final AtomicBoolean outputContainedExpectedString = new AtomicBoolean();
-
-    this.process = new ProcessBuilder(command).directory(this.temporaryFolder.getRoot()).start();
-    this.processOutReader = new ProcessStreamReader.Builder(this.process)
-        .inputStream(this.process.getInputStream()).inputListener(createExpectedListener("sysout",
-            getUniqueName() + "#sysout", expectedString, outputContainedExpectedString))
-        .build().start();
-    this.processErrReader = new ProcessStreamReader.Builder(this.process)
-        .inputStream(this.process.getErrorStream()).inputListener(createExpectedListener("syserr",
-            getUniqueName() + "#syserr", expectedString, outputContainedExpectedString))
-        .build().start();
-
-    // wait for server to start up
-    int pid = 0;
-    this.launcher = new ServerLauncher.Builder()
-        .setWorkingDirectory(this.temporaryFolder.getRoot().getCanonicalPath()).build();
-    try {
-      waitForServerToStart();
-
-      // validate the pid file and its contents
-      this.pidFile = new File(this.temporaryFolder.getRoot(), ProcessType.SERVER.getPidFileName());
-      assertTrue(this.pidFile.exists());
-      pid = readPid(this.pidFile);
-      assertTrue(pid > 0);
-      assertTrue(ProcessUtils.isProcessAlive(pid));
-
-      // validate log file was created
-      final String logFileName = getUniqueName() + ".log";
-      assertTrue("Log file should exist: " + logFileName,
-          new File(this.temporaryFolder.getRoot(), logFileName).exists());
-
-      // verify server used --server-port instead of default or port in cache.xml
-      assertFalse(AvailablePort.isPortAvailable(this.serverPort, AvailablePort.SOCKET));
-
-      final ServerState status = this.launcher.status();
-      final String portString = status.getPort();
-      int port = Integer.valueOf(portString);
-      assertEquals("Port should be " + this.serverPort + " instead of " + port, this.serverPort,
-          port);
-
-    } catch (Throwable e) {
-      this.errorCollector.addError(e);
-    }
-
-    // stop the server
-    try {
-      assertEquals(Status.STOPPED, this.launcher.stop().getStatus());
-      waitForPidToStop(pid);
-    } catch (Throwable e) {
-      this.errorCollector.addError(e);
-    }
+  public void startWithServerPortOverridesPortInCacheXml() throws Exception {
+    givenCacheXmlFileWithServerPort(unusedServerPort);
+
+    ServerLauncher launcher = startServer(
+        addJvmArgument("-D" + GEMFIRE_PREFIX + CACHE_XML_FILE + "=" + getCacheXmlFilePath())
+            .withServerPort(nonDefaultServerPort));
+
+    // server should use --server-port instead of port in cache.xml
+    assertThatServerPortIsInUse(nonDefaultServerPort);
+    assertThatServerPortIsFree(unusedServerPort);
+    assertThat(Integer.valueOf(launcher.status().getPort())).isEqualTo(nonDefaultServerPort);
   }
 
-  @Category(FlakyTest.class) // GEODE-1135: random ports, BindException, fork JVM
   @Test
-  public void testStartWithDefaultPortInUseFails() throws Throwable {
-    String expectedString = "java.net.BindException";
-    AtomicBoolean outputContainedExpectedString = new AtomicBoolean();
-
-    // make serverPort in use
-    this.socket = SocketCreatorFactory
-        .createNonDefaultInstance(false, false, null, null, System.getProperties())
-        .createServerSocket(this.serverPort, 50, null, -1);
-    assertFalse(AvailablePort.isPortAvailable(this.serverPort, AvailablePort.SOCKET));
-
-    // launch server
-    final List<String> jvmArguments = getJvmArguments();
-    jvmArguments.add(
-        "-D" + AbstractCacheServer.TEST_OVERRIDE_DEFAULT_PORT_PROPERTY + "=" + this.serverPort);
-
-    final List<String> command = new ArrayList<String>();
-    command
-        .add(new File(new File(System.getProperty("java.home"), "bin"), "java").getCanonicalPath());
-    for (String jvmArgument : jvmArguments) {
-      command.add(jvmArgument);
-    }
-    command.add("-cp");
-    command.add(System.getProperty("java.class.path"));
-    command.add(ServerLauncher.class.getName());
-    command.add(ServerLauncher.Command.START.getName());
-    command.add(getUniqueName());
-    command.add("--redirect-output");
-
-    this.process = new ProcessBuilder(command).directory(this.temporaryFolder.getRoot()).start();
-    this.processOutReader = new ProcessStreamReader.Builder(this.process)
-        .inputStream(this.process.getInputStream()).inputListener(createExpectedListener("sysout",
-            getUniqueName() + "#sysout", expectedString, outputContainedExpectedString))
-        .build().start();
-    this.processErrReader = new ProcessStreamReader.Builder(this.process)
-        .inputStream(this.process.getErrorStream()).inputListener(createExpectedListener("syserr",
-            getUniqueName() + "#syserr", expectedString, outputContainedExpectedString))
-        .build().start();
-
-    // wait for server to start up
-    final ServerLauncher dirLauncher = new ServerLauncher.Builder()
-        .setWorkingDirectory(this.temporaryFolder.getRoot().getCanonicalPath()).build();
-    try {
-      int code = this.process.waitFor();
-      assertEquals("Expected exit code 1 but was " + code, 1, code);
-    } catch (Throwable e) {
-      this.errorCollector.addError(e);
-    }
-
-    try {
-      // check the status
-      final ServerState serverState = dirLauncher.status();
-      assertNotNull(serverState);
-      assertEquals(Status.NOT_RESPONDING, serverState.getStatus());
-
-      // creation of log file seems to be random -- look into why sometime
-      final String logFileName = getUniqueName() + ".log";
-      assertFalse("Log file should exist: " + logFileName,
-          new File(this.temporaryFolder.getRoot(), logFileName).exists());
-
-    } catch (Throwable e) {
-      this.errorCollector.addError(e);
-    }
-
-    // if the following fails, then the SHORTER_TIMEOUT might be too short for slow machines
-    // or this test needs to use MainLauncher in ProcessWrapper
-
-    // validate that output contained BindException
-    this.errorCollector.checkThat(outputContainedExpectedString.get(), is(equalTo(true)));
-
-    // just in case the launcher started...
-    ServerState status = null;
-    try {
-      status = dirLauncher.stop();
-    } catch (Throwable t) {
-      // ignore
-    }
-
-    try {
-      assertEquals(getExpectedStopStatusForNotRunning(), status.getStatus());
-    } catch (Throwable e) {
-      this.errorCollector.addError(e);
-    }
+  public void startWithServerPortOverridesDefaultWithCacheXml() throws Exception {
+    givenCacheXmlFile();
+
+    ServerLauncher launcher = startServer(
+        addJvmArgument("-D" + GEMFIRE_PREFIX + CACHE_XML_FILE + "=" + getCacheXmlFilePath())
+            .withServerPort(nonDefaultServerPort));
+
+    // verify server used --server-port instead of default
+    assertThatServerPortIsInUse(nonDefaultServerPort);
+    assertThatServerPortIsFree(defaultServerPort);
+    assertThat(Integer.valueOf(launcher.status().getPort())).isEqualTo(nonDefaultServerPort);
   }
 
   @Test
-  @Ignore("Need to rewrite this without using dunit.Host")
-  public void testStartWithExistingPidFileFails()
-      throws Throwable {}/*
-                          * this.temporaryFolder.getRoot() = new File(getUniqueName());
-                          * this.temporaryFolder.getRoot().mkdir();
-                          * assertTrue(this.temporaryFolder.getRoot().isDirectory() &&
-                          * this.temporaryFolder.getRoot().canWrite());
-                          * 
-                          * // create existing pid file this.pidFile = new
-                          * File(this.temporaryFolder.getRoot(),
-                          * ProcessType.SERVER.getPidFileName()); final int realPid =
-                          * Host.getHost(0).getVM(3).invoke(() -> ProcessUtils.identifyPid());
-                          * assertFalse("Remote pid shouldn't be the same as local pid " + realPid,
-                          * realPid == ProcessUtils.identifyPid()); writePid(this.pidFile, realPid);
-                          * 
-                          * // build and start the server final List<String> jvmArguments =
-                          * getJvmArguments();
-                          * 
-                          * final List<String> command = new ArrayList<String>(); command.add(new
-                          * File(new File(System.getProperty("java.home"), "bin"),
-                          * "java").getCanonicalPath()); for (String jvmArgument : jvmArguments) {
-                          * command.add(jvmArgument); } command.add("-cp");
-                          * command.add(System.getProperty("java.class.path"));
-                          * command.add(ServerLauncher.class.getName());
-                          * command.add(ServerLauncher.Command.START.getName());
-                          * command.add(getUniqueName()); command.add("--disable-default-server");
-                          * command.add("--redirect-output");
-                          * 
-                          * this.process = new
-                          * ProcessBuilder(command).directory(this.temporaryFolder.getRoot()).start(
-                          * ); this.processOutReader = new
-                          * ProcessStreamReader.Builder(this.process).inputStream(this.process.
-                          * getInputStream()).build().start(); this.processErrReader = new
-                          * ProcessStreamReader.Builder(this.process).inputStream(this.process.
-                          * getErrorStream()).build().start();
-                          * 
-                          * // collect and throw the FIRST failure Throwable failure = null;
-                          * 
-                          * final ServerLauncher dirLauncher = new ServerLauncher.Builder()
-                          * .setWorkingDirectory(this.temporaryFolder.getRoot().getCanonicalPath())
-                          * .build(); try { waitForServerToStart(dirLauncher, 10*1000, false); }
-                          * catch (Throwable e) { logger.error(e); if (failure == null) { failure =
-                          * e; } }
-                          * 
-                          * try { // check the status final ServerState serverState =
-                          * dirLauncher.status(); assertNotNull(serverState);
-                          * assertIndexDetailsEquals(Status.NOT_RESPONDING,
-                          * serverState.getStatus());
-                          * 
-                          * final String logFileName = getUniqueName()+".log";
-                          * assertFalse("Log file should not exist: " + logFileName, new
-                          * File(this.temporaryFolder.getRoot(), logFileName).exists());
-                          * 
-                          * } catch (Throwable e) { logger.error(e); if (failure == null) { failure
-                          * = e; } }
-                          * 
-                          * // just in case the launcher started... ServerState status = null; try {
-                          * status = dirLauncher.stop(); } catch (Throwable t) { // ignore }
-                          * 
-                          * try { final Status theStatus = status.getStatus(); assertFalse(theStatus
-                          * == Status.STARTING); assertFalse(theStatus == Status.ONLINE); } catch
-                          * (Throwable e) { logger.error(e); if (failure == null) { failure = e; } }
-                          * 
-                          * if (failure != null) { throw failure; } } //
-                          * testStartWithExistingPidFileFails
-                          */
-
-  @Category(FlakyTest.class) // GEODE-957: random ports, BindException, fork JVM
+  public void startWithDefaultPortInUseFailsWithBindException() throws Exception {
+    givenServerPortInUse(defaultServerPort);
+
+    startServerShouldFail();
+
+    assertThatServerThrew(BindException.class);
+  }
+
   @Test
-  public void testStatusUsingPid() throws Throwable {
-    final List<String> jvmArguments = getJvmArguments();
-
-    final List<String> command = new ArrayList<String>();
-    command
-        .add(new File(new File(System.getProperty("java.home"), "bin"), "java").getCanonicalPath());
-    for (String jvmArgument : jvmArguments) {
-      command.add(jvmArgument);
-    }
-    command.add("-cp");
-    command.add(System.getProperty("java.class.path"));
-    command.add(ServerLauncher.class.getName());
-    command.add(ServerLauncher.Command.START.getName());
-    command.add(getUniqueName());
-    command.add("--disable-default-server");
-    command.add("--redirect-output");
-
-    this.process = new ProcessBuilder(command).directory(this.temporaryFolder.getRoot()).start();
-    this.processOutReader = new ProcessStreamReader.Builder(this.process)
-        .inputStream(this.process.getInputStream()).build().start();
-    this.processErrReader = new ProcessStreamReader.Builder(this.process)
-        .inputStream(this.process.getErrorStream()).build().start();
-
-    // wait for server to start
-    int pid = 0;
-    ServerLauncher pidLauncher = null;
-    this.launcher = new ServerLauncher.Builder()
-        .setWorkingDirectory(this.temporaryFolder.getRoot().getCanonicalPath()).build();
-    try {
-      waitForServerToStart();
-
-      // validate the pid file and its contents
-      this.pidFile = new File(this.temporaryFolder.getRoot(), ProcessType.SERVER.getPidFileName());
-      assertTrue(this.pidFile.exists());
-      pid = readPid(this.pidFile);
-      assertTrue(pid > 0);
-      assertTrue(ProcessUtils.isProcessAlive(pid));
-
-      // validate log file was created
-      final String logFileName = getUniqueName() + ".log";
-      assertTrue("Log file should exist: " + logFileName,
-          new File(this.temporaryFolder.getRoot(), logFileName).exists());
-
-      // use launcher with pid
-      pidLauncher = new Builder().setPid(pid).build();
-
-      assertNotNull(pidLauncher);
-      assertFalse(pidLauncher.isRunning());
-
-      // validate the status
-      final ServerState actualStatus = pidLauncher.status();
-      assertNotNull(actualStatus);
-      assertEquals(Status.ONLINE, actualStatus.getStatus());
-      assertEquals(pid, actualStatus.getPid().intValue());
-      assertTrue(actualStatus.getUptime() > 0);
-      assertEquals(this.temporaryFolder.getRoot().getCanonicalPath(),
-          actualStatus.getWorkingDirectory());
-      assertEquals(jvmArguments, actualStatus.getJvmArguments());
-      assertEquals(ManagementFactory.getRuntimeMXBean().getClassPath(),
-          actualStatus.getClasspath());
-      assertEquals(GemFireVersion.getGemFireVersion(), actualStatus.getGemFireVersion());
-      assertEquals(System.getProperty("java.version"), actualStatus.getJavaVersion());
-      assertEquals(this.temporaryFolder.getRoot().getCanonicalPath() + File.separator
-          + getUniqueName() + ".log", actualStatus.getLogFile());
-      assertEquals(InetAddress.getLocalHost().getCanonicalHostName(), actualStatus.getHost());
-      assertEquals(getUniqueName(), actualStatus.getMemberName());
-
-    } catch (Throwable e) {
-      this.errorCollector.addError(e);
-    }
-
-    // stop the server
-    try {
-      if (pidLauncher == null) {
-        assertEquals(Status.STOPPED, this.launcher.stop().getStatus());
-      } else {
-        assertEquals(Status.STOPPED, pidLauncher.stop().getStatus());
-      }
-      waitForPidToStop(pid);
-      waitForFileToDelete(this.pidFile);
-
-    } catch (Throwable e) {
-      this.errorCollector.addError(e);
-    }
+  public void statusForDisableDefaultServerHasEmptyPort() throws Exception {
+    givenRunningServer(withDisableDefaultServer());
+
+    ServerState serverState =
+        new Builder().setWorkingDirectory(getWorkingDirectoryPath()).build().status();
+
+    assertThat(serverState.getPort()).isEmpty();
   }
 
   @Test
-  public void testStatusUsingWorkingDirectory() throws Throwable {
-    final List<String> jvmArguments = getJvmArguments();
-
-    final List<String> command = new ArrayList<String>();
-    command
-        .add(new File(new File(System.getProperty("java.home"), "bin"), "java").getCanonicalPath());
-    for (String jvmArgument : jvmArguments) {
-      command.add(jvmArgument);
-    }
-    command.add("-cp");
-    command.add(System.getProperty("java.class.path"));
-    command.add(ServerLauncher.class.getName());
-    command.add(ServerLauncher.Command.START.getName());
-    command.add(getUniqueName());
-    command.add("--disable-default-server");
-    command.add("--redirect-output");
-
-    this.process = new ProcessBuilder(command).directory(this.temporaryFolder.getRoot()).start();
-    this.processOutReader = new ProcessStreamReader.Builder(this.process)
-        .inputStream(this.process.getInputStream()).build().start();
-    this.processErrReader = new ProcessStreamReader.Builder(this.process)
-        .inputStream(this.process.getErrorStream()).build().start();
-
-    // wait for server to start
-    int pid = 0;
-    this.launcher = new ServerLauncher.Builder()
-        .setWorkingDirectory(this.temporaryFolder.getRoot().getCanonicalPath()).build();
-    try {
-      waitForServerToStart();
-
-      // validate the pid file and its contents
-      this.pidFile = new File(this.temporaryFolder.getRoot(), ProcessType.SERVER.getPidFileName());
-      assertTrue(this.pidFile.exists());
-      pid = readPid(this.pidFile);
-      assertTrue(pid > 0);
-      assertTrue(ProcessUtils.isProcessAlive(pid));
-
-      // validate log file was created
-      final String logFileName = getUniqueName() + ".log";
-      assertTrue("Log file should exist: " + logFileName,
-          new File(this.temporaryFolder.getRoot(), logFileName).exists());
-
-      assertNotNull(this.launcher);
-      assertFalse(this.launcher.isRunning());
-
-      // validate the status
-      final ServerState actualStatus = this.launcher.status();
-      assertNotNull(actualStatus);
-      assertEquals(Status.ONLINE, actualStatus.getStatus());
-      assertEquals(pid, actualStatus.getPid().intValue());
-      assertTrue(actualStatus.getUptime() > 0);
-      assertEquals(this.temporaryFolder.getRoot().getCanonicalPath(),
-          actualStatus.getWorkingDirectory());
-      assertEquals(jvmArguments, actualStatus.getJvmArguments());
-      assertEquals(ManagementFactory.getRuntimeMXBean().getClassPath(),
-          actualStatus.getClasspath());
-      assertEquals(GemFireVersion.getGemFireVersion(), actualStatus.getGemFireVersion());
-      assertEquals(System.getProperty("java.version"), actualStatus.getJavaVersion());
-      assertEquals(this.temporaryFolder.getRoot().getCanonicalPath() + File.separator
-          + getUniqueName() + ".log", actualStatus.getLogFile());
-      assertEquals(InetAddress.getLocalHost().getCanonicalHostName(), actualStatus.getHost());
-      assertEquals(getUniqueName(), actualStatus.getMemberName());
-
-    } catch (Throwable e) {
-      this.errorCollector.addError(e);
-    }
-
-    // stop the server
-    try {
-      assertEquals(Status.STOPPED, this.launcher.stop().getStatus());
-      waitForPidToStop(pid);
-    } catch (Throwable e) {
-      this.errorCollector.addError(e);
-    }
+  public void statusWithPidReturnsOnlineWithDetails() throws Exception {
+    givenRunningServer();
+
+    ServerState serverState = new Builder().setPid(getServerPid()).build().status();
+
+    assertThat(serverState.getStatus()).isEqualTo(ONLINE);
+    assertThat(serverState.getPid().intValue()).isEqualTo(getServerPid());
+    assertThat(serverState.getUptime()).isGreaterThan(0);
+    assertThat(serverState.getWorkingDirectory()).isEqualTo(getWorkingDirectoryPath());
+    assertThat(serverState.getJvmArguments()).isEqualTo(getJvmArguments());
+    assertThat(serverState.getClasspath()).isEqualTo(getClassPath());
+    assertThat(serverState.getGemFireVersion()).isEqualTo(GemFireVersion.getGemFireVersion());
+    assertThat(serverState.getJavaVersion()).isEqualTo(System.getProperty("java.version"));
+    assertThat(serverState.getLogFile()).isEqualTo(getLogFile().getCanonicalPath());
+    assertThat(serverState.getHost()).isEqualTo(InetAddress.getLocalHost().getCanonicalHostName());
+    assertThat(serverState.getMemberName()).isEqualTo(getUniqueName());
   }
 
   @Test
-  public void testStatusWithEmptyPidFile() throws Exception {
-    this.pidFile = new File(this.temporaryFolder.getRoot(), ProcessType.SERVER.getPidFileName());
-    assertTrue(this.pidFile + " already exists", this.pidFile.createNewFile());
-
-    final ServerLauncher dirLauncher = new ServerLauncher.Builder()
-        .setWorkingDirectory(this.temporaryFolder.getRoot().getCanonicalPath()).build();
-    final ServerState actualStatus = dirLauncher.status();
-    assertThat(actualStatus, is(notNullValue()));
-    assertThat(actualStatus.getStatus(), is(equalTo(Status.NOT_RESPONDING)));
-    assertThat(actualStatus.getPid(), is(nullValue()));
-    assertThat(actualStatus.getUptime().intValue(), is(equalTo(0)));
-    assertThat(actualStatus.getWorkingDirectory(),
-        is(equalTo(this.temporaryFolder.getRoot().getCanonicalPath())));
-    assertThat(actualStatus.getClasspath(), is(nullValue()));
-    assertThat(actualStatus.getGemFireVersion(), is(equalTo(GemFireVersion.getGemFireVersion())));
-    assertThat(actualStatus.getJavaVersion(), is(nullValue()));
-    assertThat(actualStatus.getLogFile(), is(nullValue()));
-    assertThat(actualStatus.getHost(), is(nullValue()));
-    assertThat(actualStatus.getMemberName(), is(nullValue()));
+  public void statusWithWorkingDirectoryReturnsOnlineWithDetails() throws Exception {
+    givenRunningServer();
+
+    ServerState serverState =
+        new Builder().setWorkingDirectory(getWorkingDirectoryPath()).build().status();
+
+    assertThat(serverState.getStatus()).isEqualTo(ONLINE);
+    assertThat(serverState.getPid().intValue()).isEqualTo(readPidFile());
+    assertThat(serverState.getUptime()).isGreaterThan(0);
+    assertThat(serverState.getWorkingDirectory()).isEqualTo(getWorkingDirectoryPath());
+    assertThat(serverState.getJvmArguments()).isEqualTo(getJvmArguments());
+    assertThat(serverState.getClasspath()).isEqualTo(getClassPath());
+    assertThat(serverState.getGemFireVersion()).isEqualTo(GemFireVersion.getGemFireVersion());
+    assertThat(serverState.getJavaVersion()).isEqualTo(System.getProperty("java.version"));
+    assertThat(serverState.getLogFile()).isEqualTo(getLogFile().getCanonicalPath());
+    assertThat(serverState.getHost()).isEqualTo(InetAddress.getLocalHost().getCanonicalHostName());
+    assertThat(serverState.getMemberName()).isEqualTo(getUniqueName());
   }
 
   @Test
-  public void testStatusWithNoPidFile() throws Exception {
-    final ServerLauncher dirLauncher = new ServerLauncher.Builder()
-        .setWorkingDirectory(this.temporaryFolder.getRoot().getCanonicalPath()).build();
-    ServerState serverState = dirLauncher.status();
-    assertEquals(Status.NOT_RESPONDING, serverState.getStatus());
+  public void statusWithEmptyPidFileThrowsIllegalArgumentException() throws Exception {
+    givenEmptyPidFile();
+
+    ServerLauncher launcher = new Builder().setWorkingDirectory(getWorkingDirectoryPath()).build();
+
+    assertThatThrownBy(() -> launcher.status()).isInstanceOf(IllegalArgumentException.class)
+        .hasMessageContaining("Invalid pid 'null' found in");
   }
 
   @Test
-  public void testStatusWithStalePidFile() throws Exception {
-    this.pidFile = new File(this.temporaryFolder.getRoot(), ProcessType.SERVER.getPidFileName());
-    final int pid = 0;
-    assertFalse(ProcessUtils.isProcessAlive(pid));
-    writePid(this.pidFile, pid);
-
-    final ServerLauncher dirLauncher = new ServerLauncher.Builder()
-        .setWorkingDirectory(temporaryFolder.getRoot().getCanonicalPath()).build();
-    final ServerState actualStatus = dirLauncher.status();
-    assertThat(actualStatus, is(notNullValue()));
-    assertThat(actualStatus.getStatus(), is(equalTo(Status.NOT_RESPONDING)));
-    assertThat(actualStatus.getPid(), is(nullValue()));
-    assertThat(actualStatus.getUptime().intValue(), is(equalTo(0)));
-    assertThat(actualStatus.getWorkingDirectory(),
-        is(equalTo(this.temporaryFolder.getRoot().getCanonicalPath())));
-    assertThat(actualStatus.getClasspath(), is(nullValue()));
-    assertThat(actualStatus.getGemFireVersion(), is(equalTo(GemFireVersion.getGemFireVersion())));
-    assertThat(actualStatus.getJavaVersion(), is(nullValue()));
-    assertThat(actualStatus.getLogFile(), is(nullValue()));
-    assertThat(actualStatus.getHost(), is(nullValue()));
-    assertThat(actualStatus.getMemberName(), is(nullValue()));
+  public void statusWithEmptyWorkingDirectoryReturnsNotRespondingWithDetails() throws Exception {
+    givenEmptyWorkingDirectory();
+
+    ServerState serverState =
+        new Builder().setWorkingDirectory(getWorkingDirectoryPath()).build().status();
+
+    assertThat(serverState.getStatus()).isEqualTo(NOT_RESPONDING);
+    assertThat(serverState.getPid()).isNull();
+    assertThat(serverState.getUptime().intValue()).isEqualTo(0);
+    assertThat(serverState.getWorkingDirectory()).isEqualTo(getWorkingDirectoryPath());
+    assertThat(serverState.getClasspath()).isNull();
+    assertThat(serverState.getGemFireVersion()).isEqualTo(GemFireVersion.getGemFireVersion());
+    assertThat(serverState.getJavaVersion()).isNull();
+    assertThat(serverState.getLogFile()).isNull();
+    assertThat(serverState.getHost()).isNull();
+    assertThat(serverState.getMemberName()).isNull();
   }
 
   @Test
-  public void testStopUsingPid() throws Throwable {
-    final List<String> jvmArguments = getJvmArguments();
-
-    final List<String> command = new ArrayList<String>();
-    command
-        .add(new File(new File(System.getProperty("java.home"), "bin"), "java").getCanonicalPath());
-    for (String jvmArgument : jvmArguments) {
-      command.add(jvmArgument);
-    }
-    command.add("-cp");
-    command.add(System.getProperty("java.class.path"));
-    command.add(ServerLauncher.class.getName());
-    command.add(ServerLauncher.Command.START.getName());
-    command.add(getUniqueName());
-    command.add("--disable-default-server");
-    command.add("--redirect-output");
-
-    this.process = new ProcessBuilder(command).directory(this.temporaryFolder.getRoot()).start();
-    this.processOutReader =
-        new ProcessStreamReader.Builder(this.process).inputStream(this.process.getInputStream())
-            .inputListener(createLoggingListener("sysout", getUniqueName() + "#sysout")).build()
-            .start();
-    this.processErrReader =
-        new ProcessStreamReader.Builder(this.process).inputStream(this.process.getErrorStream())
-            .inputListener(createLoggingListener("syserr", getUniqueName() + "#syserr")).build()
-            .start();
-
-    // wait for server to start
-    int pid = 0;
-    ServerLauncher pidLauncher = null;
-    this.launcher = new ServerLauncher.Builder()
-        .setWorkingDirectory(this.temporaryFolder.getRoot().getCanonicalPath()).build();
-    try {
-      waitForServerToStart();
-
-      // validate the pid file and its contents
-      this.pidFile = new File(this.temporaryFolder.getRoot(), ProcessType.SERVER.getPidFileName());
-      assertTrue(this.pidFile.exists());
-      pid = readPid(this.pidFile);
-      assertTrue(pid > 0);
-      assertTrue(ProcessUtils.isProcessAlive(pid));
-
-      // validate log file was created
-      final String logFileName = getUniqueName() + ".log";
-      assertTrue("Log file should exist: " + logFileName,
-          new File(this.temporaryFolder.getRoot(), logFileName).exists());
-
-      // use launcher with pid
-      pidLauncher = new Builder().setPid(pid).build();
-
-      assertNotNull(pidLauncher);
-      assertFalse(pidLauncher.isRunning());
-
-      // validate the status
-      final ServerState status = pidLauncher.status();
-      assertNotNull(status);
-      assertEquals(Status.ONLINE, status.getStatus());
-      assertEquals(pid, status.getPid().intValue());
-
-    } catch (Throwable e) {
-      this.errorCollector.addError(e);
-    }
-
-    // stop the server
-    try {
-      if (pidLauncher == null) {
-        assertEquals(Status.STOPPED, this.launcher.stop().getStatus());
-      } else {
-        assertEquals(Status.STOPPED, pidLauncher.stop().getStatus());
-      }
-      waitForPidToStop(pid);
-      waitForFileToDelete(this.pidFile);
-
-    } catch (Throwable e) {
-      this.errorCollector.addError(e);
-    }
+  public void statusWithStalePidFileReturnsNotResponding() throws Exception {
+    givenPidFile(fakePid);
+
+    ServerState serverState =
+        new Builder().setWorkingDirectory(getWorkingDirectoryPath()).build().status();
+
+    assertThat(serverState.getStatus()).isEqualTo(NOT_RESPONDING);
   }
 
   @Test
-  public void testStopUsingWorkingDirectory() throws Throwable {
-    final List<String> jvmArguments = getJvmArguments();
-
-    final List<String> command = new ArrayList<String>();
-    command
-        .add(new File(new File(System.getProperty("java.home"), "bin"), "java").getCanonicalPath());
-    for (String jvmArgument : jvmArguments) {
-      command.add(jvmArgument);
-    }
-    command.add("-cp");
-    command.add(System.getProperty("java.class.path"));
-    command.add(ServerLauncher.class.getName());
-    command.add(ServerLauncher.Command.START.getName());
-    command.add(getUniqueName());
-    command.add("--disable-default-server");
-    command.add("--redirect-output");
-
-    this.process = new ProcessBuilder(command).directory(this.temporaryFolder.getRoot()).start();
-    this.processOutReader = new ProcessStreamReader.Builder(this.process)
-        .inputStream(this.process.getInputStream()).build().start();
-    this.processErrReader = new ProcessStreamReader.Builder(this.process)
-        .inputStream(this.process.getErrorStream()).build().start();
-
-    // wait for server to start
-    int pid = 0;
-    this.launcher = new ServerLauncher.Builder()
-        .setWorkingDirectory(this.temporaryFolder.getRoot().getCanonicalPath()).build();
-    try {
-      waitForServerToStart();
-
-      // validate the pid file and its contents
-      this.pidFile = new File(this.temporaryFolder.getRoot(), ProcessType.SERVER.getPidFileName());
-      assertTrue(this.pidFile.exists());
-      pid = readPid(this.pidFile);
-      assertTrue(pid > 0);
-      assertTrue(ProcessUtils.isProcessAlive(pid));
-
-      // validate log file was created
-      final String logFileName = getUniqueName() + ".log";
-      assertTrue("Log file should exist: " + logFileName,
-          new File(this.temporaryFolder.getRoot(), logFileName).exists());
-
-    } catch (Throwable e) {
-      this.errorCollector.addError(e);
-    }
-
-    try {
-      // stop the server
-      assertEquals(Status.STOPPED, this.launcher.stop().getStatus());
-      waitForPidToStop(pid);
-      assertFalse("PID file still exists!", this.pidFile.exists());
-
-    } catch (Throwable e) {
-      this.errorCollector.addError(e);
-    }
+  public void stopWithPidReturnsStopped() throws Exception {
+    givenRunningServer();
+
+    ServerState serverState = new Builder().setPid(getServerPid()).build().stop();
+
+    assertThat(serverState.getStatus()).isEqualTo(STOPPED);
   }
 
-  @Override
-  protected List<String> getJvmArguments() {
-    final List<String> jvmArguments = new ArrayList<String>();
-    jvmArguments.add(
-        "-D" + DistributionConfig.GEMFIRE_PREFIX + ConfigurationProperties.LOG_LEVEL + "=config");
-    jvmArguments
-        .add("-D" + DistributionConfig.GEMFIRE_PREFIX + ConfigurationProperties.MCAST_PORT + "=0");
-    return jvmArguments;
+  @Test
+  public void stopWithPidStopsServerProcess() throws Exception {
+    givenRunningServer();
+
+    new Builder().setPid(getServerPid()).build().stop();
+
+    assertStopOf(getServerProcess());
   }
 
-  /**
-   * Used only by
-   * {@link ServerLauncherRemoteIntegrationTest#testRunningServerOutlivesForkingProcess}
-   */
-  public static class ServerLauncherForkingProcess {
-
-    public static void main(final String... args) throws IOException, PidUnavailableException {
-      // -System.out.println("inside main");
-      File file = new File(System.getProperty("user.dir"),
-          ServerLauncherForkingProcess.class.getSimpleName().concat(".log"));
-      file.createNewFile();
-      LocalLogWriter logWriter = new LocalLogWriter(InternalLogWriter.ALL_LEVEL,
-          new PrintStream(new FileOutputStream(file, true)));
-      // LogWriter logWriter = new PureLogWriter(LogWriterImpl.ALL_LEVEL);
-      logWriter
-          .info(ServerLauncherForkingProcess.class.getSimpleName() + "#main PID is " + getPid());
-
-      try {
-        // launch ServerLauncher
-        final List<String> jvmArguments = null;// getJvmArguments();
-        assertTrue(jvmArguments.size() == 2);
-        final List<String> command = new ArrayList<String>();
-        command.add(
-            new File(new File(System.getProperty("java.home"), "bin"), "java").getCanonicalPath());
-        for (String jvmArgument : jvmArguments) {
-          command.add(jvmArgument);
-        }
-        command.add("-cp");
-        command.add(System.getProperty("java.class.path"));
-        command.add(ServerLauncher.class.getName());
-        command.add(ServerLauncher.Command.START.getName());
-        command.add(ServerLauncherForkingProcess.class.getSimpleName() + "_server");
-        command.add("--disable-default-server");
-        command.add("--redirect-output");
-
-        logWriter
-            .info(ServerLauncherForkingProcess.class.getSimpleName() + "#main command: " + command);
-        logWriter.info(ServerLauncherForkingProcess.class.getSimpleName() + "#main starting...");
-
-        // -System.out.println("launching " + command);
-
-        @SuppressWarnings("unused")
-        Process forkedProcess = new ProcessBuilder(command).start();
-
-        // processOutReader = new ProcessStreamReader(forkedProcess.getInputStream()).start();
-        // processErrReader = new ProcessStreamReader(forkedProcess.getErrorStream()).start();
-
-        // logWriter.info(ServerLauncherForkingProcess.class.getSimpleName() + "#main waiting for
-        // Server to start...");
-        //
-        // File workingDir = new File(System.getProperty("user.dir"));
-        // System.out.println("waiting for server to start in " + workingDir);
-        // final ServerLauncher dirLauncher = new ServerLauncher.Builder()
-        // .setWorkingDirectory(workingDir.getCanonicalPath())
-        // .build();
-        // waitForServerToStart(dirLauncher, true);
-
-        logWriter.info(ServerLauncherForkingProcess.class.getSimpleName() + "#main exiting...");
-
-        // -System.out.println("exiting");
-        ExitCode.NORMAL.doSystemExit();
-      } catch (Throwable t) {
-        logWriter.info(ServerLauncherForkingProcess.class.getSimpleName() + "#main error: " + t, t);
-        System.exit(-1);
-      }
-    }
+  @Test
+  public void stopWithPidDeletesPidFile() throws Exception {
+    givenRunningServer();
+
+    new Builder().setPid(getServerPid()).build().stop();
+
+    assertDeletionOf(getPidFile());
+  }
+
+  @Test
+  public void stopWithWorkingDirectoryReturnsStopped() throws Exception {
+    givenRunningServer();
+
+    ServerState serverState =
+        new Builder().setWorkingDirectory(getWorkingDirectoryPath()).build().stop();
+
+    assertThat(serverState.getStatus()).isEqualTo(STOPPED);
+  }
+
+  @Test
+  public void stopWithWorkingDirectoryStopsServerProcess() throws Exception {
+    givenRunningServer();
+
+    new Builder().setWorkingDirectory(getWorkingDirectoryPath()).build().stop();
+
+    assertStopOf(getServerProcess());
+  }
+
+  @Test
+  public void stopWithWorkingDirectoryDeletesPidFile() throws Exception {
+    givenRunningServer();
+
+    new Builder().setWorkingDirectory(getWorkingDirectoryPath()).build().stop();
+
+    assertDeletionOf(getPidFile());
   }
 }

http://git-wip-us.apache.org/repos/asf/geode/blob/894f3ee7/geode-core/src/test/java/org/apache/geode/distributed/ServerLauncherRemoteIntegrationTestCase.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/distributed/ServerLauncherRemoteIntegrationTestCase.java b/geode-core/src/test/java/org/apache/geode/distributed/ServerLauncherRemoteIntegrationTestCase.java
new file mode 100644
index 0000000..a66b772
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/distributed/ServerLauncherRemoteIntegrationTestCase.java
@@ -0,0 +1,236 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.geode.distributed;
+
+import static java.util.concurrent.TimeUnit.MINUTES;
+import static org.apache.geode.distributed.ConfigurationProperties.LOG_LEVEL;
+import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT;
+import static org.apache.geode.distributed.internal.DistributionConfig.GEMFIRE_PREFIX;
+import static org.apache.geode.internal.cache.AbstractCacheServer.TEST_OVERRIDE_DEFAULT_PORT_PROPERTY;
+import static org.apache.geode.internal.process.ProcessUtils.isProcessAlive;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.net.BindException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.junit.After;
+import org.junit.Before;
+
+import org.apache.geode.distributed.AbstractLauncher.Status;
+import org.apache.geode.internal.process.ProcessStreamReader;
+import org.apache.geode.internal.process.ProcessStreamReader.InputListener;
+
+/**
+ * Abstract base class for integration tests of {@link ServerLauncher} as an application main in a
+ * forked JVM.
+ *
+ * @since GemFire 8.0
+ */
+public abstract class ServerLauncherRemoteIntegrationTestCase
+    extends ServerLauncherIntegrationTestCase implements UsesServerCommand {
+
+  private final AtomicBoolean threwBindException = new AtomicBoolean();
+
+  private volatile Process process;
+  private volatile ProcessStreamReader processOutReader;
+  private volatile ProcessStreamReader processErrReader;
+
+  private ServerCommand serverCommand;
+
+  @Before
+  public void setUpServerLauncherRemoteIntegrationTestCase() throws Exception {
+    serverCommand = new ServerCommand(this);
+  }
+
+  @After
+  public void tearDownServerLauncherRemoteIntegrationTestCase() throws Exception {
+    if (process != null) {
+      process.destroy();
+      process = null;
+    }
+    if (processOutReader != null && processOutReader.isRunning()) {
+      processOutReader.stop();
+    }
+    if (processErrReader != null && processErrReader.isRunning()) {
+      processErrReader.stop();
+    }
+  }
+
+  @Override
+  public boolean getDisableDefaultServer() {
+    return false;
+  }
+
+  @Override
+  public List<String> getJvmArguments() {
+    List<String> jvmArguments = new ArrayList<>();
+    jvmArguments.add("-D" + GEMFIRE_PREFIX + LOG_LEVEL + "=config");
+    jvmArguments.add("-D" + GEMFIRE_PREFIX + MCAST_PORT + "=0");
+    jvmArguments
+        .add("-D" + TEST_OVERRIDE_DEFAULT_PORT_PROPERTY + "=" + String.valueOf(defaultServerPort));
+    return jvmArguments;
+  }
+
+  @Override
+  public String getName() {
+    return getUniqueName();
+  }
+
+  protected void assertThatServerThrew(final Class<? extends Throwable> throwableClass) {
+    assertThat(threwBindException.get()).isTrue();
+  }
+
+  protected void assertStopOf(final Process process) {
+    await().until(() -> assertThat(process.isAlive()).isFalse());
+  }
+
+  protected void assertThatPidIsAlive(final int pid) {
+    assertThat(pid).isGreaterThan(0);
+    assertThat(isProcessAlive(pid)).isTrue();
+  }
+
+  protected ServerLauncher givenRunningServer() {
+    return givenRunningServer(serverCommand);
+  }
+
+  protected ServerLauncher givenRunningServer(final ServerCommand command) {
+    return awaitStart(command);
+  }
+
+  protected Process getServerProcess() {
+    return process;
+  }
+
+  @Override
+  protected ServerLauncher startServer() {
+    return startServer(serverCommand);
+  }
+
+  protected ServerLauncher startServer(final ServerCommand command) {
+    return awaitStart(command);
+  }
+
+  protected ServerLauncher startServer(final ServerCommand command,
+      final ProcessStreamReader.InputListener outListener,
+      final ProcessStreamReader.InputListener errListener) throws Exception {
+    executeCommandWithReaders(command.create(), outListener, errListener);
+    ServerLauncher launcher = awaitStart(getWorkingDirectory());
+    assertThat(process.isAlive()).isTrue();
+    return launcher;
+  }
+
+  protected void startServerShouldFail() throws IOException, InterruptedException {
+    startServerShouldFail(serverCommand);
+  }
+
+  protected void startServerShouldFail(final ServerCommand command)
+      throws IOException, InterruptedException {
+    startServerShouldFail(command, createBindExceptionListener("sysout", threwBindException),
+        createBindExceptionListener("syserr", threwBindException));
+  }
+
+  protected ServerCommand addJvmArgument(final String arg) {
+    return serverCommand.addJvmArgument(arg);
+  }
+
+  protected ServerCommand withDisableDefaultServer() {
+    return withDisableDefaultServer(true);
+  }
+
+  protected ServerCommand withDisableDefaultServer(final boolean value) {
+    return serverCommand.disableDefaultServer(value);
+  }
+
+  protected ServerCommand withForce() {
+    return withForce(true);
+  }
+
+  protected ServerCommand withForce(final boolean value) {
+    return serverCommand.force(value);
+  }
+
+  protected ServerCommand withServerPort(final int port) {
+    return serverCommand.withServerPort(port);
+  }
+
+  private ServerLauncher awaitStart(final File workingDirectory) {
+    try {
+      launcher = new ServerLauncher.Builder()
+          .setWorkingDirectory(workingDirectory.getCanonicalPath()).build();
+      awaitStart(launcher);
+      assertThat(process.isAlive()).isTrue();
+      return launcher;
+    } catch (IOException e) {
+      throw new UncheckedIOException(e);
+    }
+  }
+
+  private ServerLauncher awaitStart(final ServerCommand command) {
+    try {
+      executeCommandWithReaders(command);
+      ServerLauncher launcher = awaitStart(getWorkingDirectory());
+      assertThat(process.isAlive()).isTrue();
+      return launcher;
+    } catch (IOException e) {
+      throw new UncheckedIOException(e);
+    }
+  }
+
+  @Override
+  protected ServerLauncher awaitStart(final ServerLauncher launcher) {
+    await().until(() -> assertThat(launcher.status().getStatus()).isEqualTo(Status.ONLINE));
+    assertThat(process.isAlive()).isTrue();
+    return launcher;
+  }
+
+  private InputListener createBindExceptionListener(final String name,
+      final AtomicBoolean threwBindException) {
+    return createExpectedListener(name, BindException.class.getName(), threwBindException);
+  }
+
+  private void executeCommandWithReaders(final List<String> command) throws IOException {
+    process = new ProcessBuilder(command).directory(getWorkingDirectory()).start();
+    processOutReader = new ProcessStreamReader.Builder(process)
+        .inputStream(process.getInputStream()).build().start();
+    processErrReader = new ProcessStreamReader.Builder(process)
+        .inputStream(process.getErrorStream()).build().start();
+  }
+
+  private void executeCommandWithReaders(final List<String> command,
+      final InputListener outListener, final InputListener errListener) throws IOException {
+    process = new ProcessBuilder(command).directory(getWorkingDirectory()).start();
+    processOutReader = new ProcessStreamReader.Builder(process)
+        .inputStream(process.getInputStream()).inputListener(outListener).build().start();
+    processErrReader = new ProcessStreamReader.Builder(process)
+        .inputStream(process.getErrorStream()).inputListener(errListener).build().start();
+  }
+
+  private void executeCommandWithReaders(final ServerCommand command) throws IOException {
+    executeCommandWithReaders(command.create());
+  }
+
+  private void startServerShouldFail(final ServerCommand command, final InputListener outListener,
+      final InputListener errListener) throws IOException, InterruptedException {
+    executeCommandWithReaders(command.create(), outListener, errListener);
+    process.waitFor(2, MINUTES);
+    assertThat(process.isAlive()).isFalse();
+    assertThat(process.exitValue()).isEqualTo(1);
+  }
+}

http://git-wip-us.apache.org/repos/asf/geode/blob/894f3ee7/geode-core/src/test/java/org/apache/geode/distributed/ServerLauncherRemoteWithCustomLoggingIntegrationTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/distributed/ServerLauncherRemoteWithCustomLoggingIntegrationTest.java b/geode-core/src/test/java/org/apache/geode/distributed/ServerLauncherRemoteWithCustomLoggingIntegrationTest.java
index fa3564b..99112db 100755
--- a/geode-core/src/test/java/org/apache/geode/distributed/ServerLauncherRemoteWithCustomLoggingIntegrationTest.java
+++ b/geode-core/src/test/java/org/apache/geode/distributed/ServerLauncherRemoteWithCustomLoggingIntegrationTest.java
@@ -14,24 +14,23 @@
  */
 package org.apache.geode.distributed;
 
-import static org.apache.geode.internal.logging.log4j.custom.CustomConfiguration.*;
-import static org.assertj.core.api.Assertions.*;
-import static org.junit.Assert.*;
+import static org.apache.geode.internal.logging.log4j.custom.CustomConfiguration.CONFIG_LAYOUT_PREFIX;
+import static org.apache.geode.internal.logging.log4j.custom.CustomConfiguration.createConfigFileIn;
+import static org.apache.logging.log4j.core.config.ConfigurationFactory.CONFIGURATION_FILE_PROPERTY;
+import static org.assertj.core.api.Assertions.assertThat;
 
 import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
+import java.io.IOException;
+import java.io.UncheckedIOException;
 
-import org.apache.logging.log4j.core.config.ConfigurationFactory;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.contrib.java.lang.system.SystemOutRule;
 import org.junit.experimental.categories.Category;
 
-import org.apache.geode.internal.process.ProcessStreamReader;
-import org.apache.geode.internal.process.ProcessType;
-import org.apache.geode.internal.process.ProcessUtils;
+import org.apache.geode.distributed.ServerLauncher.Command;
+import org.apache.geode.internal.process.ProcessStreamReader.InputListener;
 import org.apache.geode.test.junit.categories.IntegrationTest;
 
 /**
@@ -39,89 +38,45 @@ import org.apache.geode.test.junit.categories.IntegrationTest;
  */
 @Category(IntegrationTest.class)
 public class ServerLauncherRemoteWithCustomLoggingIntegrationTest
-    extends AbstractServerLauncherRemoteIntegrationTestCase {
+    extends ServerLauncherRemoteIntegrationTestCase {
 
-  private File customConfigFile;
+  private File customLoggingConfigFile;
 
   @Rule
   public SystemOutRule systemOutRule = new SystemOutRule().enableLog();
 
   @Before
-  public void setUpLocatorLauncherRemoteWithCustomLoggingIntegrationTest() throws Exception {
-    this.customConfigFile = createConfigFileIn(this.temporaryFolder.getRoot());
+  public void setUpServerLauncherRemoteWithCustomLoggingIntegrationTest() throws Exception {
+    this.customLoggingConfigFile = createConfigFileIn(getWorkingDirectory());
   }
 
   @Test
-  public void testStartUsesCustomLoggingConfiguration() throws Throwable {
-    // build and start the server
-    final List<String> jvmArguments = getJvmArguments();
-
-    final List<String> command = new ArrayList<String>();
-    command
-        .add(new File(new File(System.getProperty("java.home"), "bin"), "java").getCanonicalPath());
-    for (String jvmArgument : jvmArguments) {
-      command.add(jvmArgument);
-    }
-    command.add("-D" + ConfigurationFactory.CONFIGURATION_FILE_PROPERTY + "="
-        + this.customConfigFile.getCanonicalPath());
-    command.add("-cp");
-    command.add(System.getProperty("java.class.path"));
-    command.add(ServerLauncher.class.getName());
-    command.add(ServerLauncher.Command.START.getName());
-    command.add(getUniqueName());
-    command.add("--disable-default-server");
-    command.add("--redirect-output");
-
-    this.process = new ProcessBuilder(command).directory(new File(this.workingDirectory)).start();
-    this.processOutReader =
-        new ProcessStreamReader.Builder(this.process).inputStream(this.process.getInputStream())
-            .inputListener(new ToSystemOut()).build().start();
-    this.processErrReader =
-        new ProcessStreamReader.Builder(this.process).inputStream(this.process.getErrorStream())
-            .inputListener(new ToSystemOut()).build().start();
-
-    int pid = 0;
-    this.launcher = new ServerLauncher.Builder()
-        .setWorkingDirectory(this.temporaryFolder.getRoot().getCanonicalPath()).build();
-    try {
-      waitForServerToStart();
-
-      // validate the pid file and its contents
-      this.pidFile = new File(this.temporaryFolder.getRoot(), ProcessType.SERVER.getPidFileName());
-      assertTrue(this.pidFile.exists());
-      pid = readPid(this.pidFile);
-      assertTrue(pid > 0);
-      assertTrue(ProcessUtils.isProcessAlive(pid));
-
-      final String logFileName = getUniqueName() + ".log";
-      assertTrue("Log file should exist: " + logFileName,
-          new File(this.temporaryFolder.getRoot(), logFileName).exists());
-
-      // check the status
-      final ServerLauncher.ServerState serverState = this.launcher.status();
-      assertNotNull(serverState);
-      assertEquals(AbstractLauncher.Status.ONLINE, serverState.getStatus());
-
-      assertThat(systemOutRule.getLog())
-          .contains("log4j.configurationFile = " + this.customConfigFile.getCanonicalPath());
-      assertThat(systemOutRule.getLog()).contains(CONFIG_LAYOUT_PREFIX);
+  public void startWithCustomLoggingConfiguration() throws Exception {
+    startServer(
+        new ServerCommand(this).addJvmArgument(customLoggingConfigArgument())
+            .disableDefaultServer(true).withCommand(Command.START),
+        new ToSystemOut(), new ToSystemOut());
+
+    assertThat(systemOutRule.getLog())
+        .contains("log4j.configurationFile = " + getCustomLoggingConfigFilePath());
+    assertThat(systemOutRule.getLog()).contains(CONFIG_LAYOUT_PREFIX);
+  }
 
-    } catch (Throwable e) {
-      this.errorCollector.addError(e);
-    }
+  private String customLoggingConfigArgument() {
+    return "-D" + CONFIGURATION_FILE_PROPERTY + "=" + getCustomLoggingConfigFilePath();
+  }
 
-    // stop the server
+  private String getCustomLoggingConfigFilePath() {
     try {
-      assertEquals(AbstractLauncher.Status.STOPPED, this.launcher.stop().getStatus());
-      waitForPidToStop(pid);
-    } catch (Throwable e) {
-      this.errorCollector.addError(e);
+      return customLoggingConfigFile.getCanonicalPath();
+    } catch (IOException e) {
+      throw new UncheckedIOException(e);
     }
   }
 
-  private static class ToSystemOut implements ProcessStreamReader.InputListener {
+  private static class ToSystemOut implements InputListener {
     @Override
-    public void notifyInputLine(String line) {
+    public void notifyInputLine(final String line) {
       System.out.println(line);
     }
   }