geode-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From sai_boorlaga...@apache.org
Subject [geode] 01/01: GEODE-5212: fix failing StartLocator and StartServer command Dunit tests
Date Mon, 08 Oct 2018 20:26:07 GMT
This is an automated email from the ASF dual-hosted git repository.

sai_boorlagadda pushed a commit to branch feature/GEODE-5212-start-locator-server-tests
in repository https://gitbox.apache.org/repos/asf/geode.git

commit 27a524fb6d21e4188a156cce31bc23b1a4986a67
Author: Sai Boorlagadda <sboorlagadda@pivotal.io>
AuthorDate: Mon Oct 8 13:23:06 2018 -0700

    GEODE-5212: fix failing StartLocator and StartServer command Dunit tests
    
       * Added unit tests to cover different working directory cases
       * Removed acceptance tests related to working directory as they
         seem to be fragile as paths are environment specific
    
    Signed-off-by: Kirk Lund <klund@apache.org>
---
 .../cli/commands/StartLocatorCommandDUnitTest.java | 186 +++++----------------
 .../cli/commands/StartServerCommandDUnitTest.java  | 184 +++++++-------------
 .../cli/commands/StartLocatorCommandTest.java      |  55 ++----
 .../StartLocatorCommandWorkingDirectoryTest.java   | 152 +++++++++++++++++
 .../StartServerCommandWorkingDirectoryTest.java    | 146 ++++++++++++++++
 .../internal/cli/commands/StartLocatorCommand.java |  40 ++++-
 .../internal/cli/commands/StartMemberUtils.java    |   3 +-
 .../internal/cli/commands/StartServerCommand.java  |  40 ++++-
 8 files changed, 499 insertions(+), 307 deletions(-)

diff --git a/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/StartLocatorCommandDUnitTest.java b/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/StartLocatorCommandDUnitTest.java
index 364eaec..317ae88 100644
--- a/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/StartLocatorCommandDUnitTest.java
+++ b/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/StartLocatorCommandDUnitTest.java
@@ -27,42 +27,52 @@ import static org.assertj.core.api.Assertions.assertThat;
 import java.io.File;
 import java.io.FileWriter;
 import java.io.IOException;
-import java.lang.management.ManagementFactory;
 import java.net.InetSocketAddress;
 import java.net.Socket;
 import java.nio.file.Paths;
 import java.text.MessageFormat;
 
-import org.apache.commons.io.FileUtils;
 import org.junit.AfterClass;
+import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.ClassRule;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
+import org.junit.rules.TestName;
 
 import org.apache.geode.internal.AvailablePortHelper;
 import org.apache.geode.internal.process.ProcessType;
-import org.apache.geode.internal.util.IOUtils;
+import org.apache.geode.internal.process.ProcessUtils;
 import org.apache.geode.management.cli.Result;
 import org.apache.geode.management.internal.cli.result.CommandResult;
 import org.apache.geode.management.internal.cli.util.CommandStringBuilder;
 import org.apache.geode.test.dunit.rules.ClusterStartupRule;
 import org.apache.geode.test.dunit.rules.MemberVM;
 import org.apache.geode.test.junit.rules.GfshCommandRule;
+import org.apache.geode.test.junit.rules.RequiresGeodeHome;
 
 public class StartLocatorCommandDUnitTest {
+
   private static MemberVM locator;
   private static String locatorConnectionString;
 
+  private String memberName;
+
+  @ClassRule
+  public static RequiresGeodeHome requiresGeodeHome = new RequiresGeodeHome();
+
   @ClassRule
   public static GfshCommandRule gfsh = new GfshCommandRule();
 
   @ClassRule
-  public static final ClusterStartupRule cluster = new ClusterStartupRule();
+  public static ClusterStartupRule cluster = new ClusterStartupRule();
 
   @Rule
-  public TemporaryFolder tempFolder = new TemporaryFolder();
+  public TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+  @Rule
+  public TestName testName = new TestName();
 
   @BeforeClass
   public static void before() {
@@ -72,6 +82,11 @@ public class StartLocatorCommandDUnitTest {
     locatorConnectionString = "localhost[" + locator.getPort() + "]";
   }
 
+  @Before
+  public void setUp() {
+    memberName = testName.getMethodName();
+  }
+
   @AfterClass
   public static void after() throws Exception {
     gfsh.connectAndVerify(locator);
@@ -80,11 +95,10 @@ public class StartLocatorCommandDUnitTest {
 
   @Test
   public void testWithConflictingPIDFile() throws Exception {
-    final String fileName = ProcessType.LOCATOR.getPidFileName();
-    final String memberName = "testWithConflictingPIDFile-locator";
+    String fileName = ProcessType.LOCATOR.getPidFileName();
 
     // create dir for pid file
-    File dir = tempFolder.newFolder();
+    File dir = temporaryFolder.newFolder();
 
     // create pid file
     File pidFile = new File(dir.getAbsolutePath(), fileName);
@@ -92,7 +106,7 @@ public class StartLocatorCommandDUnitTest {
 
     // write pid to pid file
     try (FileWriter fileWriter = new FileWriter(pidFile, false)) {
-      fileWriter.write(getPidOrOne().toString() + "\n");
+      fileWriter.write(ProcessUtils.identifyPid() + "\n");
       fileWriter.flush();
     }
 
@@ -106,9 +120,9 @@ public class StartLocatorCommandDUnitTest {
 
     CommandResult result = gfsh.executeCommand(command.getCommandString());
 
-    final String expectedError = "A PID file already exists and a Locator may be running in "
+    String expectedError = "A PID file already exists and a Locator may be running in "
         + pidFile.getParentFile().getCanonicalPath();
-    final String expectedCause = "Caused by: "
+    String expectedCause = "Caused by: "
         + "org.apache.geode.internal.process.FileAlreadyExistsException: Pid file already exists: "
         + pidFile.getCanonicalPath();
 
@@ -119,13 +133,12 @@ public class StartLocatorCommandDUnitTest {
 
   @Test
   public void testWithMissingGemFirePropertiesFile() throws IOException {
-    final String missingPropertiesPath =
+    String missingPropertiesPath =
         Paths.get("missing", "gemfire.properties").toAbsolutePath().toString();
-    final String memberName = "testWithMissingGemFirePropertiesFile-locator";
-    final String expectedError =
+    String expectedError =
         MessageFormat.format(GEODE_0_PROPERTIES_1_NOT_FOUND_MESSAGE, "", missingPropertiesPath);
 
-    File workingDir = tempFolder.newFolder();
+    File workingDir = temporaryFolder.newFolder();
 
     CommandStringBuilder command = new CommandStringBuilder(START_LOCATOR)
         .addOption(START_LOCATOR__MEMBER_NAME, memberName)
@@ -140,13 +153,12 @@ public class StartLocatorCommandDUnitTest {
 
   @Test
   public void testWithMissingGemFireSecurityPropertiesFile() throws IOException {
-    final String missingSecurityPropertiesPath = Paths
+    String missingSecurityPropertiesPath = Paths
         .get("missing", "gemfire-security.properties").toAbsolutePath().toString();
-    final String memberName = "testWithMissingGemFireSecurityPropertiesFile-locator";
-    final String expectedError = MessageFormat.format(GEODE_0_PROPERTIES_1_NOT_FOUND_MESSAGE,
+    String expectedError = MessageFormat.format(GEODE_0_PROPERTIES_1_NOT_FOUND_MESSAGE,
         "Security ", missingSecurityPropertiesPath);
 
-    File workingDir = tempFolder.newFolder();
+    File workingDir = temporaryFolder.newFolder();
 
     CommandStringBuilder command = new CommandStringBuilder(START_LOCATOR)
         .addOption(START_LOCATOR__MEMBER_NAME, memberName)
@@ -162,22 +174,21 @@ public class StartLocatorCommandDUnitTest {
 
   @Test
   public void testWithUnavailablePort() throws IOException {
-    final Integer locatorPort = AvailablePortHelper.getRandomAvailableTCPPort();
-    final String memberName = "testWithUnavailablePort-locator";
-    final String unexpectedMessage = "[" + locatorPort + "] as locator is currently online.";
-    final String expectedMessage = "java.net.BindException: Network is unreachable; port ("
+    int locatorPort = AvailablePortHelper.getRandomAvailableTCPPort();
+    String unexpectedMessage = "[" + locatorPort + "] as locator is currently online.";
+    String expectedMessage = "java.net.BindException: Network is unreachable; port ("
         + locatorPort + ") is not available on localhost.";
 
     try (Socket interferingProcess = new Socket()) {
       interferingProcess.bind(new InetSocketAddress(locatorPort));
 
-      File workingDir = tempFolder.newFolder();
+      File workingDir = temporaryFolder.newFolder();
 
       CommandStringBuilder command = new CommandStringBuilder(START_LOCATOR)
           .addOption(START_LOCATOR__MEMBER_NAME, memberName)
           .addOption(START_LOCATOR__LOCATORS, locatorConnectionString)
           .addOption(START_LOCATOR__DIR, workingDir.getAbsolutePath())
-          .addOption(START_LOCATOR__PORT, locatorPort.toString());
+          .addOption(START_LOCATOR__PORT, Integer.toString(locatorPort));
 
       CommandResult result = gfsh.executeCommand(command.getCommandString());
 
@@ -189,18 +200,17 @@ public class StartLocatorCommandDUnitTest {
 
   @Test
   public void testWithAvailablePort() throws IOException {
-    final Integer locatorPort = AvailablePortHelper.getRandomAvailableTCPPort();
-    final String memberName = "testWithAvailablePort-locator";
-    final String expectedMessage =
+    int locatorPort = AvailablePortHelper.getRandomAvailableTCPPort();
+    String expectedMessage =
         "[" + locatorPort + "] as " + memberName + " is currently online.";
 
-    File workingDir = tempFolder.newFolder();
+    File workingDir = temporaryFolder.newFolder();
 
     CommandStringBuilder command = new CommandStringBuilder(START_LOCATOR)
         .addOption(START_LOCATOR__MEMBER_NAME, memberName)
         .addOption(START_LOCATOR__LOCATORS, locatorConnectionString)
         .addOption(START_LOCATOR__DIR, workingDir.getAbsolutePath())
-        .addOption(START_LOCATOR__PORT, locatorPort.toString());
+        .addOption(START_LOCATOR__PORT, String.valueOf(locatorPort));
 
     CommandResult result = gfsh.executeCommand(command.getCommandString());
 
@@ -210,11 +220,10 @@ public class StartLocatorCommandDUnitTest {
 
   @Test
   public void testWithDefaultLocatorPort() throws IOException {
-    final String memberName = "testWithDefaultLocatorPort-locator";
-    final String unexpectedMessage = "[0] as " + memberName + " is currently online.";
-    final String expectedMessage = "\\[\\d+\\] as " + memberName + " is currently online.";
+    String unexpectedMessage = "[0] as " + memberName + " is currently online.";
+    String expectedMessage = "\\[\\d+\\] as " + memberName + " is currently online.";
 
-    File workingDir = tempFolder.newFolder();
+    File workingDir = temporaryFolder.newFolder();
 
     CommandStringBuilder command = new CommandStringBuilder(START_LOCATOR)
         .addOption(START_LOCATOR__MEMBER_NAME, memberName)
@@ -228,113 +237,4 @@ public class StartLocatorCommandDUnitTest {
     assertThat(result.getMessageFromContent()).doesNotContain(unexpectedMessage);
     assertThat(result.getMessageFromContent()).containsPattern(expectedMessage);
   }
-
-  @Test
-  public void testInMissingRelativeDirectoryThatCanBeCreated() {
-    final Integer locatorPort = AvailablePortHelper.getRandomAvailableTCPPort();
-
-    // path to a missing dir that can be created
-    String readWritePathname = "readWriteDir";
-    File readWriteDir = new File(readWritePathname);
-    final String missingDirPath =
-        Paths.get(readWritePathname, "missing", "path", "to", "start", "in").toString();
-
-    final String memberName = "testInMissingRelativeDirectoryThatCanBeCreated-locator";
-    final String expectedMessage = "Locator in .*" + missingDirPath;
-
-    CommandStringBuilder command = new CommandStringBuilder(START_LOCATOR)
-        .addOption(START_LOCATOR__MEMBER_NAME, memberName)
-        .addOption(START_LOCATOR__LOCATORS, locatorConnectionString)
-        .addOption(START_LOCATOR__DIR, missingDirPath)
-        .addOption(START_LOCATOR__PORT, locatorPort.toString());
-
-    try {
-      CommandResult result = gfsh.executeCommand(command.getCommandString());
-
-      assertThat(result.getStatus()).isEqualTo(Result.Status.OK);
-      assertThat(result.getMessageFromContent()).containsPattern(expectedMessage);
-    } finally {
-      FileUtils.deleteQuietly(readWriteDir);
-    }
-  }
-
-  @Test
-  public void testWithRelativeDirectory() throws IOException {
-    final Integer locatorPort = AvailablePortHelper.getRandomAvailableTCPPort();
-    final File dir = tempFolder.newFolder();
-    final String memberName = "testWithRelativeDirectory-locator";
-    final String expectedMessage =
-        "Locator in " + IOUtils.tryGetCanonicalFileElseGetAbsoluteFile(dir);
-
-    CommandStringBuilder command = new CommandStringBuilder(START_LOCATOR)
-        .addOption(START_LOCATOR__MEMBER_NAME, memberName)
-        .addOption(START_LOCATOR__LOCATORS, locatorConnectionString)
-        .addOption(START_LOCATOR__DIR, dir.getAbsolutePath())
-        .addOption(START_LOCATOR__PORT, locatorPort.toString());
-
-    CommandResult result = gfsh.executeCommand(command.getCommandString());
-
-    assertThat(result.getStatus()).isEqualTo(Result.Status.OK);
-    assertThat(result.getMessageFromContent()).contains(expectedMessage);
-  }
-
-  @Test
-  public void testWithCurrentDirectory() {
-    final Integer locatorPort = AvailablePortHelper.getRandomAvailableTCPPort();
-    final String expectedMessage = "Locator in " + System.getProperty("user.dir");
-    final String expectedVersionPattern = "Geode Version: \\d+\\.\\d+\\.\\d+";
-    final String memberName = "testWithCurrentDirectory-locator";
-
-    CommandStringBuilder command = new CommandStringBuilder(START_LOCATOR)
-        .addOption(START_LOCATOR__MEMBER_NAME, memberName)
-        .addOption(START_LOCATOR__LOCATORS, locatorConnectionString)
-        .addOption(START_LOCATOR__PORT, locatorPort.toString());
-
-    try {
-      CommandResult result = gfsh.executeCommand(command.getCommandString());
-
-      assertThat(result.getStatus()).isEqualTo(Result.Status.OK);
-      assertThat(result.getMessageFromContent()).contains(expectedMessage);
-
-      // Verify GEODE-2138 (Geode commands do not contain GemFire in output)
-      assertThat(result.getMessageFromContent()).doesNotContainPattern("Gem[Ff]ire Version");
-      assertThat(result.getMessageFromContent()).containsPattern(expectedVersionPattern);
-    } finally {
-      String pathToFile = Paths.get(System.getProperty("user.dir"), memberName).toString();
-      File toDelete = new File(pathToFile);
-      deleteLocatorFiles(toDelete);
-    }
-  }
-
-  private void deleteLocatorFiles(File toDelete) {
-    File[] nestedToDelete = toDelete.listFiles();
-
-    if (nestedToDelete != null && nestedToDelete.length > 0) {
-      for (File file : nestedToDelete) {
-        deleteLocatorFiles(file);
-      }
-    }
-
-    toDelete.delete();
-  }
-
-  /**
-   * Attempts to determine the PID of the running process from the ManagementFactory's runtime MBean
-   *
-   * @return 1 if unable to determine the pid
-   * @return the PID if possible
-   */
-  private Integer getPidOrOne() {
-    Integer pid = 1;
-    String[] name = ManagementFactory.getRuntimeMXBean().getName().split("@");
-    if (name.length > 1) {
-      try {
-        pid = Integer.parseInt(name[0]);
-      } catch (NumberFormatException nex) {
-        // Ignored
-      }
-    }
-
-    return pid;
-  }
 }
diff --git a/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/StartServerCommandDUnitTest.java b/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/StartServerCommandDUnitTest.java
index 6e5b7cc..eb75315 100644
--- a/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/StartServerCommandDUnitTest.java
+++ b/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/StartServerCommandDUnitTest.java
@@ -37,12 +37,10 @@ import static org.assertj.core.api.Assertions.assertThat;
 import java.io.File;
 import java.io.FileWriter;
 import java.io.IOException;
-import java.lang.management.ManagementFactory;
 import java.net.InetSocketAddress;
 import java.net.Socket;
 import java.nio.file.Paths;
 
-import org.apache.commons.io.FileUtils;
 import org.junit.AfterClass;
 import org.junit.Before;
 import org.junit.BeforeClass;
@@ -50,6 +48,7 @@ import org.junit.ClassRule;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
+import org.junit.rules.TestName;
 
 import org.apache.geode.cache.execute.FunctionException;
 import org.apache.geode.cache.execute.FunctionService;
@@ -65,26 +64,36 @@ import org.apache.geode.management.internal.cli.util.CommandStringBuilder;
 import org.apache.geode.test.compiler.ClassBuilder;
 import org.apache.geode.test.dunit.rules.ClusterStartupRule;
 import org.apache.geode.test.dunit.rules.MemberVM;
+import org.apache.geode.test.dunit.rules.SharedErrorCollector;
 import org.apache.geode.test.junit.rules.GfshCommandRule;
+import org.apache.geode.test.junit.rules.RequiresGeodeHome;
 
 public class StartServerCommandDUnitTest {
+
   private static MemberVM locator;
   private static String locatorConnectionString;
+
   private File workingDir;
+  private String memberName;
+  private int serverPort;
 
   @ClassRule
-  public static final ClusterStartupRule cluster = new ClusterStartupRule();
+  public static RequiresGeodeHome requiresGeodeHome = new RequiresGeodeHome();
 
   @ClassRule
-  public static final GfshCommandRule gfsh = new GfshCommandRule();
+  public static ClusterStartupRule cluster = new ClusterStartupRule();
+
+  @ClassRule
+  public static GfshCommandRule gfsh = new GfshCommandRule();
 
   @Rule
-  public final TemporaryFolder temporaryFolder = new TemporaryFolder();
+  public SharedErrorCollector errorCollector = new SharedErrorCollector();
 
-  @Before
-  public void before() throws IOException {
-    workingDir = temporaryFolder.newFolder();
-  }
+  @Rule
+  public TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+  @Rule
+  public TestName testName = new TestName();
 
   @BeforeClass
   public static void beforeClass() throws Exception {
@@ -96,6 +105,13 @@ public class StartServerCommandDUnitTest {
     gfsh.connectAndVerify(locator);
   }
 
+  @Before
+  public void before() throws IOException {
+    workingDir = temporaryFolder.newFolder();
+    memberName = testName.getMethodName();
+    serverPort = AvailablePortHelper.getRandomAvailableTCPPort();
+  }
+
   @AfterClass
   public static void afterClass() throws Exception {
     gfsh.connectAndVerify(locator);
@@ -104,17 +120,15 @@ public class StartServerCommandDUnitTest {
 
   @Test
   public void testWithMissingCacheXml() throws IOException {
-    final Integer serverPort = AvailablePortHelper.getRandomAvailableTCPPort();
-    final String missingCacheXmlPath =
+    String missingCacheXmlPath =
         Paths.get("missing", "cache.xml").toAbsolutePath().toString();
-    final String memberName = "testWithMissingCacheXml-server";
-    final String expectedError =
+    String expectedError =
         CliStrings.format(CACHE_XML_NOT_FOUND_MESSAGE, missingCacheXmlPath);
 
     String command = new CommandStringBuilder(START_SERVER)
         .addOption(START_SERVER__NAME, memberName)
         .addOption(START_SERVER__LOCATORS, locatorConnectionString)
-        .addOption(START_SERVER__SERVER_PORT, serverPort.toString())
+        .addOption(START_SERVER__SERVER_PORT, String.valueOf(serverPort))
         .addOption(START_SERVER__CACHE_XML_FILE, missingCacheXmlPath)
         .addOption(START_SERVER__DIR, workingDir.getCanonicalPath())
         .getCommandString();
@@ -127,17 +141,15 @@ public class StartServerCommandDUnitTest {
 
   @Test
   public void testWithMissingGemFirePropertiesFile() throws IOException {
-    final Integer serverPort = AvailablePortHelper.getRandomAvailableTCPPort();
-    final String missingGemfirePropertiesPath =
+    String missingGemfirePropertiesPath =
         Paths.get("missing", "gemfire.properties").toAbsolutePath().toString();
-    final String memberName = "testWithMissingGemFirePropertiesFile-server";
-    final String expectedError =
+    String expectedError =
         CliStrings.format(GEODE_0_PROPERTIES_1_NOT_FOUND_MESSAGE, "", missingGemfirePropertiesPath);
 
     String command = new CommandStringBuilder(START_SERVER)
         .addOption(START_SERVER__NAME, memberName)
         .addOption(START_SERVER__LOCATORS, locatorConnectionString)
-        .addOption(START_SERVER__SERVER_PORT, serverPort.toString())
+        .addOption(START_SERVER__SERVER_PORT, String.valueOf(serverPort))
         .addOption(START_SERVER__PROPERTIES, missingGemfirePropertiesPath)
         .addOption(START_SERVER__DIR, workingDir.getCanonicalPath())
         .getCommandString();
@@ -150,14 +162,12 @@ public class StartServerCommandDUnitTest {
 
   @Test
   public void testWithMissingPassword() throws IOException {
-    final Integer serverPort = AvailablePortHelper.getRandomAvailableTCPPort();
-    final String memberName = "testWithMissingPassword-server";
-    final String expectedError = "password must be specified.";
+    String expectedError = "password must be specified.";
 
     String command = new CommandStringBuilder(START_SERVER)
         .addOption(START_SERVER__NAME, memberName)
         .addOption(START_SERVER__LOCATORS, locatorConnectionString)
-        .addOption(START_SERVER__SERVER_PORT, serverPort.toString())
+        .addOption(START_SERVER__SERVER_PORT, String.valueOf(serverPort))
         .addOption(START_SERVER__USERNAME, "usernameValue")
         .addOption(START_SERVER__DIR, workingDir.getCanonicalPath())
         .getCommandString();
@@ -170,17 +180,15 @@ public class StartServerCommandDUnitTest {
 
   @Test
   public void testWithMissingSecurityPropertiesFile() throws IOException {
-    final Integer serverPort = AvailablePortHelper.getRandomAvailableTCPPort();
-    final String missingSecurityPropertiesPath =
+    String missingSecurityPropertiesPath =
         Paths.get("missing", "security.properties").toAbsolutePath().toString();
-    final String memberName = "testWithMissingSecurityPropertiesFile-server";
-    final String expectedError = CliStrings.format(GEODE_0_PROPERTIES_1_NOT_FOUND_MESSAGE,
+    String expectedError = CliStrings.format(GEODE_0_PROPERTIES_1_NOT_FOUND_MESSAGE,
         "Security ", missingSecurityPropertiesPath);
 
     String command = new CommandStringBuilder(START_SERVER)
         .addOption(START_SERVER__NAME, memberName)
         .addOption(START_SERVER__LOCATORS, locatorConnectionString)
-        .addOption(START_SERVER__SERVER_PORT, serverPort.toString())
+        .addOption(START_SERVER__SERVER_PORT, String.valueOf(serverPort))
         .addOption(START_SERVER__DIR, workingDir.getCanonicalPath())
         .addOption(START_SERVER__SECURITY_PROPERTIES, missingSecurityPropertiesPath)
         .getCommandString();
@@ -193,21 +201,19 @@ public class StartServerCommandDUnitTest {
 
   @Test
   public void testWithUnavailablePort() throws IOException {
-    final Integer serverPort = AvailablePortHelper.getRandomAvailableTCPPort();
-    final String memberName = "testWithUnavailablePort-server";
-    final String expectedError =
+    String expectedError =
         "java.lang.RuntimeException: An IO error occurred while starting a Server";
-    final String expectedCause = "Caused by: java.net.BindException: "
+    String expectedCause = "Caused by: java.net.BindException: "
         + "Network is unreachable; port (" + serverPort + ") is not available on localhost.";
 
     try (Socket interferingProcess = new Socket()) {
-      interferingProcess.bind(new InetSocketAddress(serverPort)); // make the target port
-                                                                  // unavailable
+      // make the target port unavailable
+      interferingProcess.bind(new InetSocketAddress(serverPort));
 
       String command = new CommandStringBuilder(START_SERVER)
           .addOption(START_SERVER__NAME, memberName)
           .addOption(START_SERVER__LOCATORS, locatorConnectionString)
-          .addOption(START_SERVER__SERVER_PORT, serverPort.toString())
+          .addOption(START_SERVER__SERVER_PORT, String.valueOf(serverPort))
           .addOption(START_SERVER__DIR, workingDir.getCanonicalPath())
           .getCommandString();
 
@@ -220,15 +226,13 @@ public class StartServerCommandDUnitTest {
 
   @Test
   public void testWithAvailablePort() throws IOException {
-    final Integer serverPort = AvailablePortHelper.getRandomAvailableTCPPort();
-    final String memberName = "testWithAvailablePort-server";
-    final String expectedMessage = "Server in " + workingDir.getCanonicalPath();
-    final String expectedMessage2 = "as " + memberName + " is currently online.";
+    String expectedMessage = "Server in " + workingDir.getCanonicalPath();
+    String expectedMessage2 = "as " + memberName + " is currently online.";
 
     String command = new CommandStringBuilder(START_SERVER)
         .addOption(START_SERVER__NAME, memberName)
         .addOption(START_SERVER__LOCATORS, locatorConnectionString)
-        .addOption(START_SERVER__SERVER_PORT, serverPort.toString())
+        .addOption(START_SERVER__SERVER_PORT, String.valueOf(serverPort))
         .addOption(START_SERVER__DIR, workingDir.getCanonicalPath())
         .getCommandString();
 
@@ -239,40 +243,8 @@ public class StartServerCommandDUnitTest {
   }
 
   @Test
-  public void testWithMissingStartDirectoryThatCanBeCreated() throws IOException {
-    final Integer serverPort = AvailablePortHelper.getRandomAvailableTCPPort();
-
-    // path to a missing dir that can be created
-    String readWritePathname = "readWriteDir";
-    File readWriteDir = new File(readWritePathname);
-    final String missingDirPath =
-        Paths.get(readWritePathname, "missing", "dir", "to", "start", "in").toString();
-
-    final String memberName = "testWithMissingStartDirectoryThatCanBeCreated-server";
-    final String expectedMessage = "Server in .*" + missingDirPath;
-
-    String command = new CommandStringBuilder(START_SERVER)
-        .addOption(START_SERVER__NAME, memberName)
-        .addOption(START_SERVER__LOCATORS, locatorConnectionString)
-        .addOption(START_SERVER__SERVER_PORT, serverPort.toString())
-        .addOption(START_SERVER__DIR, missingDirPath)
-        .getCommandString();
-
-    try {
-      CommandResult result = gfsh.executeCommand(command);
-
-      assertThat(result.getStatus()).isEqualTo(Result.Status.OK);
-      assertThat(result.getMessageFromContent()).containsPattern(expectedMessage);
-    } finally {
-      FileUtils.deleteQuietly(readWriteDir);
-    }
-  }
-
-  @Test
-  public void testWithConflictingPIDFile() throws IOException {
-    final String fileName = ProcessType.SERVER.getPidFileName();
-    final Integer serverPort = AvailablePortHelper.getRandomAvailableTCPPort();
-    final String memberName = "testWithConflictingPIDFile-server";
+  public void testWithConflictingPIDFile() throws Exception {
+    String fileName = ProcessType.SERVER.getPidFileName();
 
     // create PID file
     File pidFile = new File(workingDir.getAbsolutePath(), fileName);
@@ -280,7 +252,7 @@ public class StartServerCommandDUnitTest {
 
     // write PID to PID file
     try (FileWriter fileWriter = new FileWriter(pidFile, false)) {
-      fileWriter.write(getPidOrOne().toString() + "\n");
+      fileWriter.write(ProcessUtils.identifyPid() + "\n");
       fileWriter.flush();
     }
     assertThat(pidFile.isFile()).isTrue();
@@ -288,28 +260,25 @@ public class StartServerCommandDUnitTest {
     String command = new CommandStringBuilder(START_SERVER)
         .addOption(START_SERVER__NAME, memberName)
         .addOption(START_SERVER__LOCATORS, locatorConnectionString)
-        .addOption(START_SERVER__SERVER_PORT, serverPort.toString())
+        .addOption(START_SERVER__SERVER_PORT, String.valueOf(serverPort))
         .addOption(START_SERVER__DIR, pidFile.getParentFile().getCanonicalPath())
         .getCommandString();
 
     CommandResult result = gfsh.executeCommand(command);
 
-    final String expectedError = "A PID file already exists and a Server may be running in "
+    String expectedError = "A PID file already exists and a Server may be running in "
         + pidFile.getParentFile().getCanonicalPath();
-    final String expectedCause = "Caused by: "
+    String expectedCause = "Caused by: "
         + "org.apache.geode.internal.process.FileAlreadyExistsException: Pid file already exists: "
         + pidFile.getCanonicalPath();
 
     assertThat(result.getStatus()).isEqualTo(Result.Status.ERROR);
     assertThat(result.getMessageFromContent()).contains(expectedError).contains(expectedCause);
-
   }
 
   @Test
-  public void testWithForceOverwriteConflictingPIDFile() throws IOException {
-    final Integer serverPort = AvailablePortHelper.getRandomAvailableTCPPort();
-    final String memberName = "testWithForceOverwriteConflictingPIDFile-server";
-    final String fileName = ProcessType.SERVER.getPidFileName();
+  public void testWithForceOverwriteConflictingPIDFile() throws Exception {
+    String fileName = ProcessType.SERVER.getPidFileName();
 
     // create PID file
     File pidFile = new File(workingDir.getAbsolutePath(), fileName);
@@ -317,7 +286,7 @@ public class StartServerCommandDUnitTest {
 
     // write PID to PID file
     try (FileWriter fileWriter = new FileWriter(pidFile, false)) {
-      fileWriter.write(getPidOrOne().toString() + "\n");
+      fileWriter.write(ProcessUtils.identifyPid() + "\n");
       fileWriter.flush();
     }
     assertThat(pidFile.isFile()).isTrue();
@@ -325,14 +294,14 @@ public class StartServerCommandDUnitTest {
     String command = new CommandStringBuilder(START_SERVER)
         .addOption(START_SERVER__NAME, memberName)
         .addOption(START_SERVER__LOCATORS, locatorConnectionString)
-        .addOption(START_SERVER__SERVER_PORT, serverPort.toString())
+        .addOption(START_SERVER__SERVER_PORT, String.valueOf(serverPort))
         .addOption(START_SERVER__DIR, pidFile.getParentFile().getCanonicalPath())
         .addOption(START_SERVER__FORCE, "true")
         .getCommandString();
 
     CommandResult result = gfsh.executeCommand(command);
 
-    final String expectedMessage = "Server in " + pidFile.getParentFile().getCanonicalPath();
+    String expectedMessage = "Server in " + pidFile.getParentFile().getCanonicalPath();
 
     assertThat(result.getStatus()).isEqualTo(Result.Status.OK);
     assertThat(result.getMessageFromContent()).contains(expectedMessage);
@@ -340,16 +309,14 @@ public class StartServerCommandDUnitTest {
 
   @Test
   public void testWithConnectionToLocator() throws IOException {
-    final Integer serverPort = AvailablePortHelper.getRandomAvailableTCPPort();
-    final String memberName = "testWithConnectionToLocator-server";
-    final String expectedVersionPattern = "Geode Version: \\d+\\.\\d+\\.\\d+";
-    final String expectedMessage = "Server in " + workingDir.getCanonicalPath();
+    String expectedVersionPattern = "Geode Version: \\d+\\.\\d+\\.\\d+";
+    String expectedMessage = "Server in " + workingDir.getCanonicalPath();
 
     String command = new CommandStringBuilder(START_SERVER)
         .addOption(START_SERVER__NAME, memberName)
         .addOption(START_SERVER__LOCATORS, locatorConnectionString)
         .addOption(START_SERVER__DIR, workingDir.getCanonicalPath())
-        .addOption(START_SERVER__SERVER_PORT, serverPort.toString())
+        .addOption(START_SERVER__SERVER_PORT, String.valueOf(serverPort))
         .getCommandString();
 
     CommandResult result = gfsh.executeCommand(command);
@@ -364,10 +331,8 @@ public class StartServerCommandDUnitTest {
 
   @Test
   public void testServerJVMTerminatesOnOutOfMemoryError() throws IOException {
-    final Integer serverPort = AvailablePortHelper.getRandomAvailableTCPPort();
-    final String memberName = "testServerJVMTerminatesOnOutOfMemoryError-server";
-    final String groupName = "serverGroup";
-    final String regionName = "testRegion";
+    String groupName = "serverGroup";
+    String regionName = "testRegion";
 
     MemberVM server = cluster.startServerVM(1, locator.getPort());
 
@@ -377,7 +342,7 @@ public class StartServerCommandDUnitTest {
         .addOption(START_SERVER__LOCATORS, locatorConnectionString)
         .addOption(START_SERVER__OFF_HEAP_MEMORY_SIZE, "0M")
         .addOption(START_SERVER__MAXHEAP, "300M")
-        .addOption(START_SERVER__SERVER_PORT, serverPort.toString())
+        .addOption(START_SERVER__SERVER_PORT, String.valueOf(serverPort))
         .addOption(START_SERVER__DIR, workingDir.getCanonicalPath())
         .getCommandString();
 
@@ -405,16 +370,16 @@ public class StartServerCommandDUnitTest {
     Integer serverPid = serverState.getPid();
     assertThat(ProcessUtils.isProcessAlive(serverPid)).isTrue();
 
-    final String jarName = "RunOutOfMemory.jar";
+    String jarName = "RunOutOfMemory.jar";
     File jar = temporaryFolder.newFile(jarName);
-    new ClassBuilder().writeJarFromClass(new RunOutOfMemoryFunction().getClass(), jar);
+    new ClassBuilder().writeJarFromClass(RunOutOfMemoryFunction.class, jar);
     gfsh.executeAndAssertThat("deploy --groups=" + groupName + " --jar=" + jar).statusIsSuccess();
 
     locator.invoke((() -> {
       try {
         FunctionService.onMember(groupName).execute(new RunOutOfMemoryFunction()).getResult();
       } catch (FunctionException e) {
-        e.printStackTrace();
+        errorCollector.addError(e);
       }
     }));
 
@@ -425,25 +390,4 @@ public class StartServerCommandDUnitTest {
 
     assertThat(ProcessUtils.isProcessAlive(serverPid)).isFalse();
   }
-
-  /**
-   * Attempts to determine the PID of the running process from the ManagementFactory's runtime MBean
-   *
-   * @return 1 if unable to determine the pid
-   * @return the PID if possible
-   */
-  private Integer getPidOrOne() {
-    Integer pid = 1;
-    String[] name = ManagementFactory.getRuntimeMXBean().getName().split("@");
-    if (name.length > 1) {
-      try {
-        pid = Integer.parseInt(name[0]);
-      } catch (NumberFormatException nex) {
-        // Ignored
-      }
-    }
-
-    return pid;
-  }
-
 }
diff --git a/geode-assembly/src/test/java/org/apache/geode/management/internal/cli/commands/StartLocatorCommandTest.java b/geode-assembly/src/test/java/org/apache/geode/management/internal/cli/commands/StartLocatorCommandTest.java
index e520374..291f0f2 100644
--- a/geode-assembly/src/test/java/org/apache/geode/management/internal/cli/commands/StartLocatorCommandTest.java
+++ b/geode-assembly/src/test/java/org/apache/geode/management/internal/cli/commands/StartLocatorCommandTest.java
@@ -12,11 +12,11 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-
 package org.apache.geode.management.internal.cli.commands;
 
 import static org.apache.geode.distributed.ConfigurationProperties.HTTP_SERVICE_BIND_ADDRESS;
 import static org.apache.geode.distributed.ConfigurationProperties.HTTP_SERVICE_PORT;
+import static org.apache.geode.management.internal.cli.commands.StartServerCommand.addJvmOptionsForOutOfMemoryErrors;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
@@ -43,16 +43,17 @@ import org.apache.geode.distributed.internal.DistributionConfig;
 import org.apache.geode.internal.lang.SystemUtils;
 
 public class StartLocatorCommandTest {
-  private StartLocatorCommand locatorCommands;
+
+  private StartLocatorCommand startLocatorCommand;
 
   @Before
-  public void setup() {
-    locatorCommands = new StartLocatorCommand();
+  public void setUp() {
+    startLocatorCommand = new StartLocatorCommand();
   }
 
   @After
   public void tearDown() {
-    locatorCommands = null;
+    startLocatorCommand = null;
   }
 
   @Test
@@ -62,7 +63,7 @@ public class StartLocatorCommandTest {
         StartMemberUtils.getGemFireJarPath().concat(File.pathSeparator).concat(userClasspath)
             .concat(File.pathSeparator).concat(System.getProperty("java.class.path"))
             .concat(File.pathSeparator).concat(StartMemberUtils.CORE_DEPENDENCIES_JAR_PATHNAME);
-    String actualClasspath = locatorCommands.getLocatorClasspath(true, userClasspath);
+    String actualClasspath = startLocatorCommand.getLocatorClasspath(true, userClasspath);
     assertEquals(expectedClasspath, actualClasspath);
   }
 
@@ -77,8 +78,9 @@ public class StartLocatorCommandTest {
     gemfireProperties.setProperty(HTTP_SERVICE_PORT, "8089");
     gemfireProperties.setProperty(HTTP_SERVICE_BIND_ADDRESS, "localhost");
 
-    String[] commandLineElements = locatorCommands.createStartLocatorCommandLine(locatorLauncher,
-        null, null, gemfireProperties, null, false, new String[0], null, null);
+    String[] commandLineElements =
+        startLocatorCommand.createStartLocatorCommandLine(locatorLauncher,
+            null, null, gemfireProperties, null, false, new String[0], null, null);
 
     assertNotNull(commandLineElements);
     assertTrue(commandLineElements.length > 0);
@@ -124,37 +126,14 @@ public class StartLocatorCommandTest {
     }
   }
 
-  private void addJvmOptionsForOutOfMemoryErrors(final List<String> commandLine) {
-    if (SystemUtils.isHotSpotVM()) {
-      if (SystemUtils.isWindows()) {
-        // ProcessBuilder "on Windows" needs every word (space separated) to be
-        // a different element in the array/list. See #47312. Need to study why!
-        commandLine.add("-XX:OnOutOfMemoryError=taskkill /F /PID %p");
-      } else { // All other platforms (Linux, Mac OS X, UNIX, etc)
-        commandLine.add("-XX:OnOutOfMemoryError=kill -KILL %p");
-      }
-    } else if (SystemUtils.isJ9VM()) {
-      // NOTE IBM states the following IBM J9 JVM command-line option/switch has side-effects on
-      // "performance",
-      // as noted in the reference documentation...
-      // http://publib.boulder.ibm.com/infocenter/javasdk/v6r0/index.jsp?topic=/com.ibm.java.doc.diagnostics.60/diag/appendixes/cmdline/commands_jvm.html
-      commandLine.add("-Xcheck:memory");
-    } else if (SystemUtils.isJRockitVM()) {
-      // NOTE the following Oracle JRockit JVM documentation was referenced to identify the
-      // appropriate JVM option to
-      // set when handling OutOfMemoryErrors.
-      // http://docs.oracle.com/cd/E13150_01/jrockit_jvm/jrockit/jrdocs/refman/optionXX.html
-      commandLine.add("-XXexitOnOutOfMemory");
-    }
-  }
-
   @Test
   public void testCreateStartLocatorCommandLine() throws Exception {
     LocatorLauncher locatorLauncher = new LocatorLauncher.Builder().setMemberName("defaultLocator")
         .setCommand(LocatorLauncher.Command.START).build();
 
-    String[] commandLineElements = locatorCommands.createStartLocatorCommandLine(locatorLauncher,
-        null, null, new Properties(), null, false, null, null, null);
+    String[] commandLineElements =
+        startLocatorCommand.createStartLocatorCommandLine(locatorLauncher,
+            null, null, new Properties(), null, false, null, null, null);
 
     Set<String> expectedCommandLineElements = new HashSet<>();
     expectedCommandLineElements.add(StartMemberUtils.getJavaPath());
@@ -206,9 +185,11 @@ public class StartLocatorCommandTest {
     String[] jvmArguments = new String[] {"-verbose:gc", "-Xloggc:member-gc.log",
         "-XX:+PrintGCDateStamps", "-XX:+PrintGCDetails"};
 
-    String[] commandLineElements = locatorCommands.createStartLocatorCommandLine(locatorLauncher,
-        gemfirePropertiesFile, gemfireSecurityPropertiesFile, gemfireProperties, customClasspath,
-        Boolean.FALSE, jvmArguments, heapSize, heapSize);
+    String[] commandLineElements =
+        startLocatorCommand.createStartLocatorCommandLine(locatorLauncher,
+            gemfirePropertiesFile, gemfireSecurityPropertiesFile, gemfireProperties,
+            customClasspath,
+            Boolean.FALSE, jvmArguments, heapSize, heapSize);
 
     Set<String> expectedCommandLineElements = new HashSet<>();
     expectedCommandLineElements.add(StartMemberUtils.getJavaPath());
diff --git a/geode-assembly/src/test/java/org/apache/geode/management/internal/cli/commands/StartLocatorCommandWorkingDirectoryTest.java b/geode-assembly/src/test/java/org/apache/geode/management/internal/cli/commands/StartLocatorCommandWorkingDirectoryTest.java
new file mode 100644
index 0000000..5e0b75f
--- /dev/null
+++ b/geode-assembly/src/test/java/org/apache/geode/management/internal/cli/commands/StartLocatorCommandWorkingDirectoryTest.java
@@ -0,0 +1,152 @@
+/*
+ * 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.management.internal.cli.commands;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.isNull;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+import java.io.File;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+
+public class StartLocatorCommandWorkingDirectoryTest {
+
+  private String memberName;
+  private String workingDirectory;
+  private StartLocatorCommand startLocatorCommand;
+  private ArgumentCaptor<String> workingDirectoryCaptor;
+
+  @Before
+  public void setUp() throws Exception {
+    memberName = "locator1";
+    startLocatorCommand = spy(new StartLocatorCommand());
+
+    doReturn(null).when(startLocatorCommand).doStartLocator(
+        anyString(), isNull(), isNull(), anyBoolean(),
+        isNull(), isNull(), isNull(), anyBoolean(),
+        isNull(), isNull(), isNull(), anyInt(),
+        anyInt(), anyString(), isNull(), isNull(),
+        isNull(), isNull(), isNull(), anyBoolean(),
+        anyBoolean(), anyBoolean(), isNull(), anyInt(),
+        isNull(), anyBoolean());
+
+    workingDirectoryCaptor = ArgumentCaptor.forClass(String.class);
+  }
+
+  @Test
+  public void startLocatorWithRelativeWorkingDirectory() throws Exception {
+    workingDirectory = "locator1Directory";
+
+    startLocatorCommand.startLocator(memberName, null, null, false,
+        null, null, null, false,
+        null, null, null, 0,
+        0, workingDirectory, null, null,
+        null, null, null, false,
+        false, false, null, 0,
+        null, false);
+
+    verifyDoStartLocatorInvoked();
+
+    assertThat(workingDirectoryCaptor.getValue())
+        .isEqualTo(new File(workingDirectory).getAbsolutePath());
+  }
+
+  @Test
+  public void startLocatorWithNullWorkingDirectory() throws Exception {
+    workingDirectory = null;
+
+    startLocatorCommand.startLocator(memberName, null, null, false,
+        null, null, null, false,
+        null, null, null, 0,
+        0, workingDirectory, null, null,
+        null, null, null, false,
+        false, false, null, 0,
+        null, false);
+
+    verifyDoStartLocatorInvoked();
+
+    assertThat(workingDirectoryCaptor.getValue()).isEqualTo(new File(memberName).getAbsolutePath());
+  }
+
+  @Test
+  public void startLocatorWithEmptyWorkingDirectory() throws Exception {
+    workingDirectory = "";
+
+    startLocatorCommand.startLocator(memberName, null, null, false,
+        null, null, null, false,
+        null, null, null, 0,
+        0, workingDirectory, null, null,
+        null, null, null, false,
+        false, false, null, 0,
+        null, false);
+
+    verifyDoStartLocatorInvoked();
+
+    assertThat(workingDirectoryCaptor.getValue()).isEqualTo(new File(memberName).getAbsolutePath());
+  }
+
+  @Test
+  public void startLocatorWithDotWorkingDirectory() throws Exception {
+    workingDirectory = ".";
+
+    startLocatorCommand.startLocator(memberName, null, null, false,
+        null, null, null, false,
+        null, null, null, 0,
+        0, workingDirectory, null, null,
+        null, null, null, false,
+        false, false, null, 0,
+        null, false);
+
+    verifyDoStartLocatorInvoked();
+
+    assertThat(workingDirectoryCaptor.getValue())
+        .isEqualTo(StartMemberUtils.resolveWorkingDir(new File("."), new File(memberName)));
+  }
+
+  @Test
+  public void startLocatorWithAbsoluteWorkingDirectory() throws Exception {
+    workingDirectory = new File(System.getProperty("user.dir")).getAbsolutePath();
+
+    startLocatorCommand.startLocator(memberName, null, null, false,
+        null, null, null, false,
+        null, null, null, 0,
+        0, workingDirectory, null, null,
+        null, null, null, false,
+        false, false, null, 0,
+        null, false);
+
+    verifyDoStartLocatorInvoked();
+
+    assertThat(workingDirectoryCaptor.getValue()).isEqualTo(workingDirectory);
+  }
+
+  private void verifyDoStartLocatorInvoked()
+      throws Exception {
+    verify(startLocatorCommand).doStartLocator(anyString(), isNull(), isNull(), anyBoolean(),
+        isNull(), isNull(), isNull(), anyBoolean(), isNull(),
+        isNull(), isNull(), anyInt(), anyInt(), workingDirectoryCaptor.capture(),
+        isNull(), isNull(), isNull(), isNull(), isNull(),
+        anyBoolean(), anyBoolean(), anyBoolean(), isNull(), anyInt(), isNull(),
+        anyBoolean());
+  }
+}
diff --git a/geode-assembly/src/test/java/org/apache/geode/management/internal/cli/commands/StartServerCommandWorkingDirectoryTest.java b/geode-assembly/src/test/java/org/apache/geode/management/internal/cli/commands/StartServerCommandWorkingDirectoryTest.java
new file mode 100644
index 0000000..e756865
--- /dev/null
+++ b/geode-assembly/src/test/java/org/apache/geode/management/internal/cli/commands/StartServerCommandWorkingDirectoryTest.java
@@ -0,0 +1,146 @@
+/*
+ * 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.management.internal.cli.commands;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyFloat;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.isNull;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+import java.io.File;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+
+public class StartServerCommandWorkingDirectoryTest {
+
+  private String memberName;
+  private String workingDirectory;
+  private StartServerCommand startServerCommand;
+  private ArgumentCaptor<String> workingDirectoryCaptor;
+
+  @Before
+  public void setUp() throws Exception {
+    memberName = "server1";
+    startServerCommand = spy(new StartServerCommand());
+
+    doReturn(null).when(startServerCommand)
+        .doStartServer(anyString(), anyBoolean(), isNull(), isNull(), isNull(), anyFloat(),
+            anyFloat(), anyString(), anyBoolean(), anyBoolean(), anyBoolean(), anyFloat(),
+            anyFloat(), anyBoolean(), isNull(), isNull(), isNull(), anyBoolean(), isNull(),
+            isNull(), isNull(), anyInt(), anyBoolean(), isNull(), anyInt(), isNull(), anyInt(),
+            anyInt(), isNull(), anyInt(), anyInt(), isNull(), isNull(), anyInt(), isNull(),
+            isNull(), anyInt(), isNull(), isNull(), anyBoolean(), isNull(), isNull(), anyInt(),
+            anyInt(), isNull(), isNull(), anyBoolean(), anyBoolean(), isNull(), isNull(), isNull(),
+            isNull(), anyBoolean());
+
+    workingDirectoryCaptor = ArgumentCaptor.forClass(String.class);
+  }
+
+  @Test
+  public void startLocatorWithRelativeWorkingDirectory() throws Exception {
+    workingDirectory = "server1Directory";
+
+    startServerCommand
+        .startServer(memberName, false, null, null, null, 0.0f, 0.0f, workingDirectory, false,
+            false, false, 0.0f, 0.0f, false, null, null, null, false, null, null, null, 0, false,
+            null, 0, null, 0, 0, null, 0, 0, null, null, 0, null, null, 0, null, null, false, null,
+            null, 0, 0, null, null, false, false, null, null, null, null, false);
+
+    verifyDoStartServerInvoked();
+
+    assertThat(workingDirectoryCaptor.getValue())
+        .isEqualTo(new File(workingDirectory).getAbsolutePath());
+  }
+
+  @Test
+  public void startServerWithNullWorkingDirectory() throws Exception {
+    workingDirectory = null;
+
+    startServerCommand
+        .startServer(memberName, false, null, null, null, 0.0f, 0.0f, workingDirectory, false,
+            false, false, 0.0f, 0.0f, false, null, null, null, false, null, null, null, 0, false,
+            null, 0, null, 0, 0, null, 0, 0, null, null, 0, null, null, 0, null, null, false, null,
+            null, 0, 0, null, null, false, false, null, null, null, null, false);
+
+    verifyDoStartServerInvoked();
+
+    assertThat(workingDirectoryCaptor.getValue()).isEqualTo(new File(memberName).getAbsolutePath());
+  }
+
+  @Test
+  public void startServerWithEmptyWorkingDirectory() throws Exception {
+    workingDirectory = "";
+
+    startServerCommand
+        .startServer(memberName, false, null, null, null, 0.0f, 0.0f, workingDirectory, false,
+            false, false, 0.0f, 0.0f, false, null, null, null, false, null, null, null, 0, false,
+            null, 0, null, 0, 0, null, 0, 0, null, null, 0, null, null, 0, null, null, false, null,
+            null, 0, 0, null, null, false, false, null, null, null, null, false);
+
+    verifyDoStartServerInvoked();
+
+    assertThat(workingDirectoryCaptor.getValue()).isEqualTo(new File(memberName).getAbsolutePath());
+  }
+
+  @Test
+  public void startServerWithDotWorkingDirectory() throws Exception {
+    workingDirectory = ".";
+
+    startServerCommand
+        .startServer(memberName, false, null, null, null, 0.0f, 0.0f, workingDirectory, false,
+            false, false, 0.0f, 0.0f, false, null, null, null, false, null, null, null, 0, false,
+            null, 0, null, 0, 0, null, 0, 0, null, null, 0, null, null, 0, null, null, false, null,
+            null, 0, 0, null, null, false, false, null, null, null, null, false);
+
+    verifyDoStartServerInvoked();
+
+    assertThat(workingDirectoryCaptor.getValue())
+        .isEqualTo(StartMemberUtils.resolveWorkingDir(new File("."), new File(memberName)));
+  }
+
+  @Test
+  public void startServerWithAbsoluteWorkingDirectory() throws Exception {
+    workingDirectory = new File(System.getProperty("user.dir")).getAbsolutePath();
+
+    startServerCommand
+        .startServer(memberName, false, null, null, null, 0.0f, 0.0f, workingDirectory, false,
+            false, false, 0.0f, 0.0f, false, null, null, null, false, null, null, null, 0, false,
+            null, 0, null, 0, 0, null, 0, 0, null, null, 0, null, null, 0, null, null, false, null,
+            null, 0, 0, null, null, false, false, null, null, null, null, false);
+
+    verifyDoStartServerInvoked();
+
+    assertThat(workingDirectoryCaptor.getValue()).isEqualTo(workingDirectory);
+  }
+
+  private void verifyDoStartServerInvoked() throws Exception {
+    verify(startServerCommand)
+        .doStartServer(anyString(), anyBoolean(), isNull(), isNull(), isNull(), anyFloat(),
+            anyFloat(), workingDirectoryCaptor.capture(), anyBoolean(), anyBoolean(), anyBoolean(),
+            anyFloat(), anyFloat(), anyBoolean(), isNull(), isNull(), isNull(), anyBoolean(),
+            isNull(), isNull(), isNull(), anyInt(), anyBoolean(), isNull(), anyInt(), isNull(),
+            anyInt(), anyInt(), isNull(), anyInt(), anyInt(), isNull(), isNull(), anyInt(),
+            isNull(), isNull(), anyInt(), isNull(), isNull(), anyBoolean(), isNull(), isNull(),
+            anyInt(), anyInt(), isNull(), isNull(), anyBoolean(), anyBoolean(), isNull(), isNull(),
+            isNull(), isNull(), anyBoolean());
+  }
+}
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/StartLocatorCommand.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/StartLocatorCommand.java
index b2e87f2..6f29ace 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/StartLocatorCommand.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/StartLocatorCommand.java
@@ -16,6 +16,7 @@
 package org.apache.geode.management.internal.cli.commands;
 
 import java.io.File;
+import java.io.IOException;
 import java.net.InetAddress;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -132,6 +133,44 @@ public class StartLocatorCommand extends InternalGfshCommand {
     workingDirectory = StartMemberUtils.resolveWorkingDir(
         workingDirectory == null ? null : new File(workingDirectory), new File(memberName));
 
+    return doStartLocator(memberName, bindAddress, classpath, force, group, hostnameForClients,
+        jmxManagerHostnameForClients, includeSystemClasspath, locators, logLevel, mcastBindAddress,
+        mcastPort, port, workingDirectory, gemfirePropertiesFile, gemfireSecurityPropertiesFile,
+        initialHeap, maxHeap, jvmArgsOpts, connect, enableSharedConfiguration,
+        loadSharedConfigurationFromDirectory, clusterConfigDir, httpServicePort,
+        httpServiceBindAddress, redirectOutput);
+
+  }
+
+  Result doStartLocator(
+      String memberName,
+      String bindAddress,
+      String classpath,
+      Boolean force,
+      String group,
+      String hostnameForClients,
+      String jmxManagerHostnameForClients,
+      Boolean includeSystemClasspath,
+      String locators,
+      String logLevel,
+      String mcastBindAddress,
+      Integer mcastPort,
+      Integer port,
+      String workingDirectory,
+      File gemfirePropertiesFile,
+      File gemfireSecurityPropertiesFile,
+      String initialHeap,
+      String maxHeap,
+      String[] jvmArgsOpts,
+      boolean connect,
+      boolean enableSharedConfiguration,
+      boolean loadSharedConfigurationFromDirectory,
+      String clusterConfigDir,
+      Integer httpServicePort,
+      String httpServiceBindAddress,
+      Boolean redirectOutput)
+      throws MalformedObjectNameException, IOException, InterruptedException,
+      ClassNotFoundException {
     if (gemfirePropertiesFile != null && !gemfirePropertiesFile.exists()) {
       return ResultBuilder.createUserErrorResult(
           CliStrings.format(CliStrings.GEODE_0_PROPERTIES_1_NOT_FOUND_MESSAGE, StringUtils.EMPTY,
@@ -313,7 +352,6 @@ public class StartLocatorCommand extends InternalGfshCommand {
     }
 
     return ResultBuilder.buildResult(infoResultData);
-
   }
 
   // TODO should we connect implicitly when in non-interactive, headless mode (e.g. gfsh -e "start
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/StartMemberUtils.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/StartMemberUtils.java
index 05abf00..4f1b7fa 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/StartMemberUtils.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/StartMemberUtils.java
@@ -72,7 +72,8 @@ public class StartMemberUtils {
 
   static String resolveWorkingDir(File userSpecifiedDir, File memberNameDir) {
     File workingDir =
-        (userSpecifiedDir == null) ? memberNameDir : userSpecifiedDir;
+        (userSpecifiedDir == null || userSpecifiedDir.equals(new File(""))) ? memberNameDir
+            : userSpecifiedDir;
     String workingDirPath = IOUtils.tryGetCanonicalPathElseGetAbsolutePath(workingDir);
     if (!workingDir.exists()) {
       if (!workingDir.mkdirs()) {
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/StartServerCommand.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/StartServerCommand.java
index 61d2539..e5c5e4f 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/StartServerCommand.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/StartServerCommand.java
@@ -16,6 +16,7 @@
 package org.apache.geode.management.internal.cli.commands;
 
 import java.io.File;
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
@@ -201,6 +202,37 @@ public class StartServerCommand extends InternalGfshCommand {
     workingDirectory = StartMemberUtils.resolveWorkingDir(
         workingDirectory == null ? null : new File(workingDirectory), new File(memberName));
 
+    return doStartServer(memberName, assignBuckets, bindAddress, cacheXmlPathname, classpath,
+        criticalHeapPercentage, criticalOffHeapPercentage, workingDirectory, disableDefaultServer,
+        disableExitWhenOutOfMemory, enableTimeStatistics, evictionHeapPercentage,
+        evictionOffHeapPercentage, force, group, hostNameForClients, jmxManagerHostnameForClients,
+        includeSystemClasspath, initialHeap, jvmArgsOpts, locators, locatorWaitTime, lockMemory,
+        logLevel, maxConnections, maxHeap, maxMessageCount, maxThreads, mcastBindAddress, mcastPort,
+        memcachedPort, memcachedProtocol, memcachedBindAddress, redisPort, redisBindAddress,
+        redisPassword, messageTimeToLive, offHeapMemorySize, gemfirePropertiesFile, rebalance,
+        gemfireSecurityPropertiesFile, serverBindAddress, serverPort, socketBufferSize,
+        springXmlLocation, statisticsArchivePathname, requestSharedConfiguration, startRestApi,
+        httpServicePort, httpServiceBindAddress, userName, passwordToUse, redirectOutput);
+  }
+
+  Result doStartServer(String memberName, Boolean assignBuckets, String bindAddress,
+      String cacheXmlPathname, String classpath, Float criticalHeapPercentage,
+      Float criticalOffHeapPercentage, String workingDirectory, Boolean disableDefaultServer,
+      Boolean disableExitWhenOutOfMemory, Boolean enableTimeStatistics,
+      Float evictionHeapPercentage, Float evictionOffHeapPercentage, Boolean force, String group,
+      String hostNameForClients, String jmxManagerHostnameForClients,
+      Boolean includeSystemClasspath, String initialHeap, String[] jvmArgsOpts, String locators,
+      Integer locatorWaitTime, Boolean lockMemory, String logLevel, Integer maxConnections,
+      String maxHeap, Integer maxMessageCount, Integer maxThreads, String mcastBindAddress,
+      Integer mcastPort, Integer memcachedPort, String memcachedProtocol,
+      String memcachedBindAddress, Integer redisPort, String redisBindAddress, String redisPassword,
+      Integer messageTimeToLive, String offHeapMemorySize, File gemfirePropertiesFile,
+      Boolean rebalance, File gemfireSecurityPropertiesFile, String serverBindAddress,
+      Integer serverPort, Integer socketBufferSize, String springXmlLocation,
+      String statisticsArchivePathname, Boolean requestSharedConfiguration, Boolean startRestApi,
+      String httpServicePort, String httpServiceBindAddress, String userName, String passwordToUse,
+      Boolean redirectOutput)
+      throws MalformedObjectNameException, IOException, InterruptedException {
     cacheXmlPathname = CliUtil.resolvePathname(cacheXmlPathname);
 
     if (StringUtils.isNotBlank(cacheXmlPathname)) {
@@ -378,10 +410,8 @@ public class StartServerCommand extends InternalGfshCommand {
       } while (!(registeredServerSignalListener && serverSignalListener.isSignaled())
           && serverState.isStartingOrNotResponding());
     } finally {
-      stderrReader.stopAsync(StartMemberUtils.PROCESS_STREAM_READER_ASYNC_STOP_TIMEOUT_MILLIS); // stop
-                                                                                                // will
-                                                                                                // close
-      // ErrorStream
+      stderrReader.stopAsync(StartMemberUtils.PROCESS_STREAM_READER_ASYNC_STOP_TIMEOUT_MILLIS);
+      // stop will close ErrorStream
       getGfsh().getSignalHandler().unregisterListener(serverSignalListener);
     }
 
@@ -562,7 +592,7 @@ public class StartServerCommand extends InternalGfshCommand {
     }
   }
 
-  private void addJvmOptionsForOutOfMemoryErrors(final List<String> commandLine) {
+  static void addJvmOptionsForOutOfMemoryErrors(final List<String> commandLine) {
     if (SystemUtils.isHotSpotVM()) {
       if (SystemUtils.isWindows()) {
         // ProcessBuilder "on Windows" needs every word (space separated) to be


Mime
View raw message