You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by up...@apache.org on 2018/08/01 20:20:51 UTC
[geode] branch develop updated: GEODE-3530: Refactor
LauncherLifecycleCommandsDUnitTest
This is an automated email from the ASF dual-hosted git repository.
upthewaterspout pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/geode.git
The following commit(s) were added to refs/heads/develop by this push:
new eafd116 GEODE-3530: Refactor LauncherLifecycleCommandsDUnitTest
eafd116 is described below
commit eafd116838324ac16bd81375bb06105b30b6c89b
Author: Helena Bales <hb...@pivotal.io>
AuthorDate: Wed Aug 1 13:20:47 2018 -0700
GEODE-3530: Refactor LauncherLifecycleCommandsDUnitTest
* extract start locator command tests
* extract status locator tests
* use the GfshCommandRule so that the test is not an acceptance test
* use the ClusterStarterRule to start a locator to help with clean-up
* connect all started locators to the locator
* shutdown the cluster using the locator to clean up all JVMs
* wrap resource creations in try-finally block
* add test for creating dir and cleanup temp files
* ignore the test that requires fewer permissions
---
.../LauncherLifecycleCommandsDUnitTest.java | 275 ----------------
.../cli/commands/StartLocatorCommandDUnitTest.java | 352 +++++++++++++++++++++
.../commands/StatusLocatorCommandDunitTest.java | 243 ++++++++++++++
.../geode/test/junit/rules/GfshCommandRule.java | 2 +-
4 files changed, 596 insertions(+), 276 deletions(-)
diff --git a/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/LauncherLifecycleCommandsDUnitTest.java b/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/LauncherLifecycleCommandsDUnitTest.java
index f605291..b5a8ea9 100644
--- a/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/LauncherLifecycleCommandsDUnitTest.java
+++ b/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/LauncherLifecycleCommandsDUnitTest.java
@@ -27,10 +27,8 @@ import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
-import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
-import java.lang.management.ManagementFactory;
import java.net.InetAddress;
import java.nio.charset.Charset;
import java.text.DateFormat;
@@ -77,7 +75,6 @@ import org.apache.geode.internal.AvailablePortHelper;
import org.apache.geode.internal.lang.ObjectUtils;
import org.apache.geode.internal.lang.StringUtils;
import org.apache.geode.internal.lang.SystemUtils;
-import org.apache.geode.internal.process.ProcessType;
import org.apache.geode.internal.process.ProcessUtils;
import org.apache.geode.internal.util.IOUtils;
import org.apache.geode.management.cli.Result;
@@ -282,120 +279,6 @@ public class LauncherLifecycleCommandsDUnitTest extends CliCommandTestBase {
return serviceState.getStatus();
}
- protected void writePid(final File pidFile, final int pid) throws IOException {
- assertTrue("The PID file must actually exist!", pidFile != null && pidFile.isFile());
-
- FileWriter writer = null;
-
- try {
- writer = new FileWriter(pidFile, false);
- writer.write(String.valueOf(pid));
- writer.write(System.getProperty("line.separator"));
- writer.flush();
- } finally {
- IOUtils.close(writer);
- }
- }
-
- @Test
- public void test000StartLocatorCapturesOutputOnError() throws IOException {
- final int locatorPort = AvailablePortHelper.getRandomAvailableTCPPort();
-
- String pathname = (getClass().getSimpleName() + "_" + getTestMethodName());
- File workingDirectory = temporaryFolder.newFolder(pathname);
-
- assertTrue(workingDirectory.isDirectory() || workingDirectory.mkdir());
-
- File pidFile = new File(workingDirectory, ProcessType.LOCATOR.getPidFileName());
-
- assertTrue(pidFile.createNewFile());
-
- writePid(pidFile, getPidOrOne());
- pidFile.deleteOnExit();
-
- assertTrue(pidFile.isFile());
-
- CommandStringBuilder command = new CommandStringBuilder(CliStrings.START_LOCATOR);
-
- command.addOption(CliStrings.START_LOCATOR__MEMBER_NAME, pathname);
- command.addOption(CliStrings.START_LOCATOR__DIR, workingDirectory.getCanonicalPath());
- command.addOption(CliStrings.START_LOCATOR__PORT, String.valueOf(locatorPort));
- command.addOption(CliStrings.START_LOCATOR__ENABLE__SHARED__CONFIGURATION,
- Boolean.FALSE.toString());
- command.addOption(CliStrings.START_LOCATOR__J,
- "-D" + DistributionConfig.GEMFIRE_PREFIX + "http-service-port=0");
- command.addOption(CliStrings.START_LOCATOR__J, "-D" + DistributionConfig.GEMFIRE_PREFIX
- + "jmx-manager-port=" + AvailablePortHelper.getRandomAvailableTCPPort());
-
- CommandResult result = executeCommand(command.toString());
-
- assertNotNull(result);
- assertEquals(Result.Status.ERROR, result.getStatus());
-
- String resultString = toString(result);
-
- assertTrue(resultString,
- resultString.contains(
- "Exception in thread \"main\" java.lang.RuntimeException: A PID file already exists and a Locator may be running in "
- + IOUtils.tryGetCanonicalFileElseGetAbsoluteFile(workingDirectory)));
- assertTrue(resultString,
- resultString.contains(
- "Caused by: org.apache.geode.internal.process.FileAlreadyExistsException: Pid file already exists: "
- + IOUtils.tryGetCanonicalFileElseGetAbsoluteFile(pidFile)));
- }
-
- /*
- * This method makes an effort to get the PID of the running process. If it is unable to determine
- * accurately, it simply returns 1.
- */
- private int getPidOrOne() {
- int pid = 1;
- String[] name = ManagementFactory.getRuntimeMXBean().getName().split("@");
- if (name.length > 1) {
- try {
- pid = Integer.parseInt(name[0]);
- } catch (NumberFormatException nex) {
- // Ignored
- }
- }
-
- return pid;
- }
-
- @Test
- public void test001StartLocatorFailsFastOnMissingGemFirePropertiesFile() throws IOException {
- String gemfirePropertiesPathname = "/path/to/missing/gemfire.properties";
-
- CommandStringBuilder command = new CommandStringBuilder(CliStrings.START_LOCATOR);
- String pathName = getClass().getSimpleName().concat("_").concat(getTestMethodName());
- final File workingDirectory = temporaryFolder.newFolder(pathName);
-
- command.addOption(CliStrings.START_LOCATOR__MEMBER_NAME, pathName);
- command.addOption(CliStrings.START_LOCATOR__DIR, workingDirectory.getCanonicalPath());
- command.addOption(CliStrings.START_LOCATOR__PORT, "0");
- command.addOption(CliStrings.START_LOCATOR__PROPERTIES, gemfirePropertiesPathname);
- command.addOption(CliStrings.START_LOCATOR__J,
- "-D" + DistributionConfig.GEMFIRE_PREFIX + "http-service-port=0");
- command.addOption(CliStrings.START_LOCATOR__J,
- "-D" + DistributionConfig.GEMFIRE_PREFIX + "jmx-manager=false");
- command.addOption(CliStrings.START_LOCATOR__J,
- "-D" + DistributionConfig.GEMFIRE_PREFIX + "jmx-manager-port=0");
- command.addOption(CliStrings.START_LOCATOR__J,
- "-D" + DistributionConfig.GEMFIRE_PREFIX + "jmx-manager-start=false");
-
- CommandResult result = executeCommand(command.toString());
-
- assertNotNull(result);
- assertEquals(Result.Status.ERROR, result.getStatus());
-
- String resultString = toString(result);
-
- assertTrue(resultString,
- resultString
- .contains(MessageFormat.format(CliStrings.GEODE_0_PROPERTIES_1_NOT_FOUND_MESSAGE,
- StringUtils.EMPTY, gemfirePropertiesPathname)));
- }
-
/**
* Test to verify GEODE-2138
*
@@ -447,42 +330,6 @@ public class LauncherLifecycleCommandsDUnitTest extends CliCommandTestBase {
}
@Test
- public void test002StartLocatorFailsFastOnMissingGemFireSecurityPropertiesFile()
- throws IOException {
- String gemfireSecurityPropertiesPathname = "/path/to/missing/gemfire-security.properties";
- String pathName = getClass().getSimpleName().concat("_").concat(getTestMethodName());
- final File workingDirectory = temporaryFolder.newFolder(pathName);
-
- CommandStringBuilder command = new CommandStringBuilder(CliStrings.START_LOCATOR);
-
- command.addOption(CliStrings.START_LOCATOR__MEMBER_NAME, pathName);
- command.addOption(CliStrings.START_LOCATOR__DIR, workingDirectory.getCanonicalPath());
- command.addOption(CliStrings.START_LOCATOR__PORT, "0");
- command.addOption(CliStrings.START_LOCATOR__SECURITY_PROPERTIES,
- gemfireSecurityPropertiesPathname);
- command.addOption(CliStrings.START_LOCATOR__J,
- "-D" + DistributionConfig.GEMFIRE_PREFIX + "http-service-port=0");
- command.addOption(CliStrings.START_LOCATOR__J,
- "-D" + DistributionConfig.GEMFIRE_PREFIX + "jmx-manager=false");
- command.addOption(CliStrings.START_LOCATOR__J,
- "-D" + DistributionConfig.GEMFIRE_PREFIX + "jmx-manager-port=0");
- command.addOption(CliStrings.START_LOCATOR__J,
- "-D" + DistributionConfig.GEMFIRE_PREFIX + "jmx-manager-start=false");
-
- CommandResult result = executeCommand(command.toString());
-
- assertNotNull(result);
- assertEquals(Result.Status.ERROR, result.getStatus());
-
- String resultString = toString(result);
-
- assertTrue(resultString,
- resultString
- .contains(MessageFormat.format(CliStrings.GEODE_0_PROPERTIES_1_NOT_FOUND_MESSAGE,
- "Security ", gemfireSecurityPropertiesPathname)));
- }
-
- @Test
public void test003StartServerFailsFastOnMissingCacheXmlFile() throws IOException {
String cacheXmlPathname = "/path/to/missing/cache.xml";
@@ -582,128 +429,6 @@ public class LauncherLifecycleCommandsDUnitTest extends CliCommandTestBase {
}
@Test
- public void test006StartLocatorInRelativeDirectory() {
- final int locatorPort = AvailablePortHelper.getRandomAvailableTCPPort();
-
- String pathname = (getClass().getSimpleName() + "_" + getTestMethodName());
- File workingDirectory = new File(pathname);
-
- assertTrue(workingDirectory.isDirectory() || workingDirectory.mkdir());
-
- try {
- CommandStringBuilder command = new CommandStringBuilder(CliStrings.START_LOCATOR);
-
- command.addOption(CliStrings.START_LOCATOR__MEMBER_NAME, pathname);
- command.addOption(CliStrings.START_LOCATOR__CONNECT, Boolean.FALSE.toString());
- command.addOption(CliStrings.START_LOCATOR__DIR, pathname);
- command.addOption(CliStrings.START_LOCATOR__PORT, String.valueOf(locatorPort));
- command.addOption(CliStrings.START_LOCATOR__ENABLE__SHARED__CONFIGURATION,
- Boolean.FALSE.toString());
- command.addOption(CliStrings.START_LOCATOR__J,
- "-D" + DistributionConfig.GEMFIRE_PREFIX + "http-service-port=0");
- command.addOption(CliStrings.START_LOCATOR__J, "-D" + DistributionConfig.GEMFIRE_PREFIX
- + "jmx-manager-port=" + AvailablePortHelper.getRandomAvailableTCPPort());
-
- CommandResult result = executeCommand(command.toString());
-
- assertNotNull(result);
- assertEquals(Result.Status.OK, result.getStatus());
-
- String locatorOutput = toString(result);
-
- assertNotNull(locatorOutput);
- assertTrue("Locator output was: " + locatorOutput, locatorOutput.contains(
- "Locator in " + IOUtils.tryGetCanonicalFileElseGetAbsoluteFile(workingDirectory)));
- } finally {
- stopLocator(workingDirectory);
- }
- }
-
- @Test
- public void test007StatusLocatorUsingMemberNameIDWhenGfshIsNotConnected() {
- CommandResult result =
- executeCommand(CliStrings.STATUS_LOCATOR + " --name=" + getTestMethodName());
-
- assertNotNull(result);
- assertEquals(Result.Status.ERROR, result.getStatus());
- assertEquals(
- CliStrings.format(CliStrings.STATUS_SERVICE__GFSH_NOT_CONNECTED_ERROR_MESSAGE, "Locator"),
- StringUtils.trim(toString(result)));
- }
-
- @Test
- public void test008StatusLocatorUsingMemberName() throws IOException {
- final int[] ports = AvailablePortHelper.getRandomAvailableTCPPorts(2);
-
- final int jmxManagerPort = ports[0];
- final int locatorPort = ports[1];
-
- String pathname = (getClass().getSimpleName() + "_" + getTestMethodName());
- File workingDirectory = temporaryFolder.newFolder(pathname);
-
- assertTrue(workingDirectory.isDirectory() || workingDirectory.mkdir());
-
- try {
- CommandStringBuilder command = new CommandStringBuilder(CliStrings.START_LOCATOR);
-
- command.addOption(CliStrings.START_LOCATOR__MEMBER_NAME, pathname);
- command.addOption(CliStrings.START_LOCATOR__CONNECT, Boolean.FALSE.toString());
- command.addOption(CliStrings.START_LOCATOR__DIR, workingDirectory.getCanonicalPath());
- command.addOption(CliStrings.START_LOCATOR__PORT, String.valueOf(locatorPort));
- command.addOption(CliStrings.START_LOCATOR__ENABLE__SHARED__CONFIGURATION,
- Boolean.FALSE.toString());
- command.addOption(CliStrings.START_LOCATOR__FORCE, Boolean.TRUE.toString());
- command.addOption(CliStrings.START_LOCATOR__J,
- "-D" + DistributionConfig.GEMFIRE_PREFIX + "http-service-port=0");
- command.addOption(CliStrings.START_LOCATOR__J,
- "-D" + DistributionConfig.GEMFIRE_PREFIX + "jmx-manager-port=" + jmxManagerPort);
-
- CommandResult result = executeCommand(command.toString());
-
- assertNotNull(result);
- assertEquals(Result.Status.OK, result.getStatus());
-
- LocatorLauncher locatorLauncher = new LocatorLauncher.Builder()
- .setCommand(LocatorLauncher.Command.STATUS).setBindAddress(null).setPort(locatorPort)
- .setWorkingDirectory(workingDirectory.getPath()).build();
-
- assertNotNull(locatorLauncher);
-
- LocatorState expectedLocatorState =
- locatorLauncher.waitOnStatusResponse(60, 10, TimeUnit.SECONDS);
-
- assertNotNull(expectedLocatorState);
- assertEquals(Status.ONLINE, expectedLocatorState.getStatus());
-
- result = executeCommand(
- String.format("%1$s --locator=localhost[%2$d]", CliStrings.CONNECT, locatorPort));
-
- assertNotNull(result);
- assertEquals(Result.Status.OK, result.getStatus());
-
- result = executeCommand(
- String.format("%1$s --name=invalidLocatorMemberName", CliStrings.STATUS_LOCATOR));
-
- assertNotNull(result);
- assertEquals(Result.Status.ERROR, result.getStatus());
- assertEquals(
- CliStrings.format(CliStrings.STATUS_LOCATOR__NO_LOCATOR_FOUND_FOR_MEMBER_ERROR_MESSAGE,
- "invalidLocatorMemberName"),
- StringUtils.trim(toString(result)));
-
- result =
- executeCommand(String.format("%1$s --name=%2$s", CliStrings.STATUS_LOCATOR, pathname));
-
- assertNotNull(result);
- assertEquals(Result.Status.OK, result.getStatus());
- assertTrue(serviceStateStatusStringNormalized(toString(result))
- .contains(serviceStateStatusStringNormalized(expectedLocatorState)));
- } finally {
- stopLocator(workingDirectory);
- }
- }
-
- @Test
public void test009StatusLocatorUsingMemberId() throws Exception {
final int[] ports = AvailablePortHelper.getRandomAvailableTCPPorts(2);
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
new file mode 100644
index 0000000..3c2c7f6
--- /dev/null
+++ b/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/StartLocatorCommandDUnitTest.java
@@ -0,0 +1,352 @@
+/*
+ * 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.apache.geode.management.internal.cli.i18n.CliStrings.GEODE_0_PROPERTIES_1_NOT_FOUND_MESSAGE;
+import static org.apache.geode.management.internal.cli.i18n.CliStrings.START_LOCATOR;
+import static org.apache.geode.management.internal.cli.i18n.CliStrings.START_LOCATOR__DIR;
+import static org.apache.geode.management.internal.cli.i18n.CliStrings.START_LOCATOR__LOCATORS;
+import static org.apache.geode.management.internal.cli.i18n.CliStrings.START_LOCATOR__MEMBER_NAME;
+import static org.apache.geode.management.internal.cli.i18n.CliStrings.START_LOCATOR__PORT;
+import static org.apache.geode.management.internal.cli.i18n.CliStrings.START_LOCATOR__PROPERTIES;
+import static org.apache.geode.management.internal.cli.i18n.CliStrings.START_LOCATOR__SECURITY_PROPERTIES;
+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.text.MessageFormat;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+import org.apache.geode.internal.AvailablePortHelper;
+import org.apache.geode.internal.process.ProcessType;
+import org.apache.geode.internal.util.IOUtils;
+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;
+
+public class StartLocatorCommandDUnitTest {
+ private static MemberVM locator;
+ private static String locatorConnectionString;
+
+ @ClassRule
+ public static GfshCommandRule gfsh = new GfshCommandRule();
+
+ @ClassRule
+ public static final ClusterStartupRule cluster = new ClusterStartupRule();
+
+ @Rule
+ public TemporaryFolder tempFolder = new TemporaryFolder();
+
+ @BeforeClass
+ public static void before() {
+ // locator used to clean up JVMs after test
+ locator = cluster.startLocatorVM(0, 0);
+
+ locatorConnectionString = "localhost[" + locator.getPort() + "]";
+ }
+
+ @AfterClass
+ public static void after() throws Exception {
+ gfsh.connectAndVerify(locator);
+ gfsh.execute("shutdown --include-locators");
+ }
+
+ @Test
+ public void testWithConflictingPIDFile() throws Exception {
+ final String fileName = ProcessType.LOCATOR.getPidFileName();
+ final String memberName = "testWithConflictingPIDFile-locator";
+
+ // create dir for pid file
+ File dir = tempFolder.newFolder();
+
+ // create pid file
+ File pidFile = new File(dir.getAbsolutePath(), fileName);
+ assertThat(pidFile.createNewFile()).isTrue();
+
+ // write pid to pid file
+ try (FileWriter fileWriter = new FileWriter(pidFile, false)) {
+ fileWriter.write(getPidOrOne().toString() + "\n");
+ fileWriter.flush();
+ }
+
+ assertThat(pidFile.isFile()).isTrue();
+
+ CommandStringBuilder command = new CommandStringBuilder(START_LOCATOR)
+ .addOption(START_LOCATOR__MEMBER_NAME, memberName)
+ .addOption(START_LOCATOR__LOCATORS, locatorConnectionString)
+ .addOption(START_LOCATOR__DIR, pidFile.getParentFile().getCanonicalPath())
+ .addOption(START_LOCATOR__PORT, "0");
+
+ CommandResult result = gfsh.executeCommand(command.getCommandString());
+
+ final String expectedError = "A PID file already exists and a Locator may be running in "
+ + pidFile.getParentFile().getCanonicalPath();
+ final 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);
+ assertThat(result.getMessageFromContent()).contains(expectedCause);
+ }
+
+ @Test
+ public void testWithMissingGemFirePropertiesFile() throws IOException {
+ final String missingPropertiesPath = "/path/to/missing/gemfire.properties";
+ final String memberName = "testWithMissingGemFirePropertiesFile-locator";
+ final String expectedError =
+ MessageFormat.format(GEODE_0_PROPERTIES_1_NOT_FOUND_MESSAGE, "", missingPropertiesPath);
+
+ File workingDir = tempFolder.newFolder();
+
+ CommandStringBuilder command = new CommandStringBuilder(START_LOCATOR)
+ .addOption(START_LOCATOR__MEMBER_NAME, memberName)
+ .addOption(START_LOCATOR__DIR, workingDir.getAbsolutePath())
+ .addOption(START_LOCATOR__PROPERTIES, missingPropertiesPath);
+
+ CommandResult result = gfsh.executeCommand(command.getCommandString());
+
+ assertThat(result.getStatus()).isEqualTo(Result.Status.ERROR);
+ assertThat(result.getMessageFromContent()).contains(expectedError);
+ }
+
+ @Test
+ public void testWithMissingGemFireSecurityPropertiesFile() throws IOException {
+ final String missingSecurityPropertiesPath = "/path/to/missing/gemfire-security.properties";
+ final String memberName = "testWithMissingGemFireSecurityPropertiesFile-locator";
+ final String expectedError = MessageFormat.format(GEODE_0_PROPERTIES_1_NOT_FOUND_MESSAGE,
+ "Security ", missingSecurityPropertiesPath);
+
+ File workingDir = tempFolder.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__SECURITY_PROPERTIES, missingSecurityPropertiesPath);
+
+ CommandResult result = gfsh.executeCommand(command.getCommandString());
+
+ assertThat(result.getStatus()).isEqualTo(Result.Status.ERROR);
+ assertThat(result.getMessageFromContent()).contains(expectedError);
+ }
+
+ @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 ("
+ + locatorPort + ") is not available on localhost.";
+
+ try (Socket interferingProcess = new Socket()) {
+ interferingProcess.bind(new InetSocketAddress(locatorPort));
+
+ File workingDir = tempFolder.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());
+
+ CommandResult result = gfsh.executeCommand(command.getCommandString());
+
+ assertThat(result.getStatus()).isEqualTo(Result.Status.ERROR);
+ assertThat(result.getMessageFromContent()).doesNotContain(unexpectedMessage);
+ assertThat(result.getMessageFromContent()).contains(expectedMessage);
+ }
+ }
+
+ @Test
+ public void testWithAvailablePort() throws IOException {
+ final Integer locatorPort = AvailablePortHelper.getRandomAvailableTCPPort();
+ final String memberName = "testWithAvailablePort-locator";
+ final String expectedMessage =
+ "[" + locatorPort + "] as " + memberName + " is currently online.";
+
+ File workingDir = tempFolder.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());
+
+ CommandResult result = gfsh.executeCommand(command.getCommandString());
+
+ assertThat(result.getStatus()).isEqualTo(Result.Status.OK);
+ assertThat(result.getMessageFromContent()).contains(expectedMessage);
+ }
+
+ @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.";
+
+ File workingDir = tempFolder.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, "0");
+
+ CommandResult result = gfsh.executeCommand(command.getCommandString());
+
+ assertThat(result.getStatus()).isEqualTo(Result.Status.OK);
+ assertThat(result.getMessageFromContent()).doesNotContain(unexpectedMessage);
+ assertThat(result.getMessageFromContent()).containsPattern(expectedMessage);
+ }
+
+ @Ignore // Ignore until test until tests in CI use a different user
+ @Test
+ public void testInMissingRelativeDirectoryWithoutCreatePermissions() {
+ // path to a missing dir that cannot be created due to insufficient permissions
+ final String missingDirPath = "/missing/path/to/start/in";
+ final String expectedMessage = "Could not create directory " + missingDirPath
+ + ". Please verify directory path or user permissions.";
+ final String memberName = "testWithMissingRelativeDirectory-locator";
+
+ CommandStringBuilder command = new CommandStringBuilder(START_LOCATOR)
+ .addOption(START_LOCATOR__MEMBER_NAME, memberName)
+ .addOption(START_LOCATOR__LOCATORS, locatorConnectionString)
+ .addOption(START_LOCATOR__DIR, missingDirPath);
+
+ CommandResult result = gfsh.executeCommand(command.getCommandString());
+
+ assertThat(result.getStatus()).isEqualTo(Result.Status.ERROR);
+ assertThat(result.getMessageFromContent()).contains(expectedMessage);
+ }
+
+ @Test
+ public void testInMissingRelativeDirectoryThatCanBeCreated() {
+ // path to a missing dir that can be created
+ final String missingDirPath = System.getProperty("user.dir") + "/missing/path/to/start/in";
+ final String memberName = "testWithMissingRelativeDirectory-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);
+
+ try {
+ CommandResult result = gfsh.executeCommand(command.getCommandString());
+
+ assertThat(result.getStatus()).isEqualTo(Result.Status.OK);
+ assertThat(result.getMessageFromContent()).contains(expectedMessage);
+ } finally {
+ File toDelete = new File(missingDirPath);
+ deleteLocatorFiles(toDelete);
+ }
+ }
+
+ @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
+ assertThat(result.getMessageFromContent()).doesNotContain("Gemfire")
+ .doesNotContain("GemFire");
+ assertThat(result.getMessageFromContent()).containsPattern(expectedVersionPattern);
+ } finally {
+ String pathToFile = System.getProperty("user.dir") + "/" + memberName;
+ 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/StatusLocatorCommandDunitTest.java b/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/StatusLocatorCommandDunitTest.java
new file mode 100644
index 0000000..8249f28
--- /dev/null
+++ b/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/StatusLocatorCommandDunitTest.java
@@ -0,0 +1,243 @@
+/*
+ * 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 java.util.concurrent.TimeUnit.SECONDS;
+import static org.apache.geode.internal.i18n.LocalizedStrings.Launcher_Builder_UNKNOWN_HOST_ERROR_MESSAGE;
+import static org.apache.geode.internal.i18n.LocalizedStrings.Launcher_Builder_WORKING_DIRECTORY_NOT_FOUND_ERROR_MESSAGE;
+import static org.apache.geode.management.internal.cli.i18n.CliStrings.LOCATOR_TERM_NAME;
+import static org.apache.geode.management.internal.cli.i18n.CliStrings.STATUS_LOCATOR;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.SoftAssertions.assertSoftly;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+import org.apache.geode.distributed.LocatorLauncher;
+import org.apache.geode.distributed.LocatorLauncher.LocatorState;
+import org.apache.geode.management.cli.Result;
+import org.apache.geode.management.internal.cli.i18n.CliStrings;
+import org.apache.geode.management.internal.cli.result.CommandResult;
+import org.apache.geode.test.junit.rules.GfshCommandRule;
+import org.apache.geode.test.junit.rules.GfshCommandRule.PortType;
+
+public class StatusLocatorCommandDunitTest {
+ private static final Integer TIMEOUT = 300;
+ private static final Integer INTERVAL = 10;
+ private static final String locatorName = "locator";
+
+ private static LocatorLauncher locator;
+
+ @ClassRule
+ public static GfshCommandRule gfsh = new GfshCommandRule();
+
+ @ClassRule
+ public static TemporaryFolder tempDir = new TemporaryFolder();
+
+ @BeforeClass
+ public static void before() throws IOException {
+ File workingDir = tempDir.newFolder("workingDir");
+
+ locator = new LocatorLauncher.Builder().setMemberName(locatorName).setPort(0)
+ .setWorkingDirectory(workingDir.getAbsolutePath())
+ .set("cluster-configuration-dir", workingDir.getAbsolutePath()).build();
+ locator.start();
+ }
+
+ @AfterClass
+ public static void after() {
+ locator.stop();
+ }
+
+ @Test
+ public void testWithDisconnectedGfsh() throws Exception {
+ final String expectedResult =
+ CliStrings.format(CliStrings.STATUS_SERVICE__GFSH_NOT_CONNECTED_ERROR_MESSAGE,
+ LOCATOR_TERM_NAME);
+
+ if (gfsh.isConnected()) {
+ gfsh.disconnect();
+ }
+
+ gfsh.executeAndAssertThat(STATUS_LOCATOR + " --name=" + locatorName)
+ .statusIsError()
+ .containsOutput(expectedResult);
+ }
+
+ @Test
+ public void testWithMemberAddress() throws Exception {
+ gfsh.connectAndVerify(locator.getPort(), PortType.locator);
+
+ LocatorState state = locator.waitOnStatusResponse(TIMEOUT, INTERVAL, SECONDS);
+
+ CommandResult result =
+ gfsh.executeCommand(STATUS_LOCATOR + " --host=localhost --port=" + locator.getPort());
+
+ assertThat(result.getStatus()).isEqualTo(Result.Status.OK);
+ assertStatusCommandOutput(result.getMessageFromContent(), state);
+ }
+
+ @Test
+ public void testWithInvalidMemberAddress() throws Exception {
+ final String expectedError =
+ Launcher_Builder_UNKNOWN_HOST_ERROR_MESSAGE.toString(LOCATOR_TERM_NAME);
+
+ gfsh.connectAndVerify(locator.getPort(), PortType.locator);
+
+ CommandResult result =
+ gfsh.executeCommand(STATUS_LOCATOR + " --host=invalidHostName --port=" + locator.getPort());
+
+ assertThat(result.getStatus()).isEqualTo(Result.Status.ERROR);
+ assertThat(result.getMessageFromContent()).contains(expectedError);
+ }
+
+ @Test
+ public void testWithMemberName() throws Exception {
+ gfsh.connectAndVerify(locator.getPort(), PortType.locator);
+
+ LocatorState state = locator.waitOnStatusResponse(TIMEOUT, INTERVAL, SECONDS);
+
+ CommandResult result = gfsh.executeCommand(STATUS_LOCATOR + " --name=" + locatorName);
+
+ assertThat(result.getStatus()).isEqualTo(Result.Status.OK);
+ assertStatusCommandOutput(result.getMessageFromContent(), state);
+ }
+
+ @Test
+ public void testWithInvalidMemberName() throws Exception {
+ final String expectedError = CliStrings.format(
+ CliStrings.STATUS_LOCATOR__NO_LOCATOR_FOUND_FOR_MEMBER_ERROR_MESSAGE, "invalidLocatorName");
+
+ gfsh.connectAndVerify(locator.getPort(), PortType.locator);
+
+ CommandResult result = gfsh.executeCommand(STATUS_LOCATOR + " --name=invalidLocatorName");
+
+ assertThat(result.getStatus()).isEqualTo(Result.Status.ERROR);
+ assertThat(result.getMessageFromContent()).contains(expectedError);
+ }
+
+ @Test
+ public void testWithMemberID() throws Exception {
+ gfsh.connectAndVerify(locator.getPort(), PortType.locator);
+
+ LocatorState state = locator.waitOnStatusResponse(TIMEOUT, INTERVAL, SECONDS);
+
+ CommandResult result = gfsh.executeCommand(STATUS_LOCATOR + " --name=" + locator.getMemberId());
+
+ assertThat(result.getStatus()).isEqualTo(Result.Status.OK);
+ assertStatusCommandOutput(result.getMessageFromContent(), state);
+ }
+
+ @Test
+ public void testWithInvalidMemberID() throws Exception {
+ final String expectedError =
+ CliStrings.format(CliStrings.STATUS_LOCATOR__NO_LOCATOR_FOUND_FOR_MEMBER_ERROR_MESSAGE,
+ locator.getMemberId() + "1");
+
+ gfsh.connectAndVerify(locator.getPort(), PortType.locator);
+
+ CommandResult result =
+ gfsh.executeCommand(STATUS_LOCATOR + " --name=" + locator.getMemberId() + "1");
+
+ assertThat(result.getStatus()).isEqualTo(Result.Status.ERROR);
+ assertThat(result.getMessageFromContent()).contains(expectedError);
+ }
+
+ @Test
+ public void testWithDirOnline() throws Exception {
+ gfsh.connectAndVerify(locator.getPort(), PortType.locator);
+
+ LocatorState state = locator.waitOnStatusResponse(TIMEOUT, INTERVAL, SECONDS);
+
+ CommandResult result =
+ gfsh.executeCommand(STATUS_LOCATOR + " --dir=" + locator.getWorkingDirectory());
+
+ assertThat(result.getStatus()).isEqualTo(Result.Status.OK);
+ assertStatusCommandOutput(result.getMessageFromContent(), state);
+ }
+
+ @Test
+ public void testWithDirOffline() throws Exception {
+ if (gfsh.isConnected()) {
+ gfsh.disconnect();
+ }
+
+ LocatorState state = locator.waitOnStatusResponse(TIMEOUT, INTERVAL, SECONDS);
+
+ CommandResult result =
+ gfsh.executeCommand(STATUS_LOCATOR + " --dir=" + locator.getWorkingDirectory());
+
+ assertThat(result.getStatus()).isEqualTo(Result.Status.OK);
+ assertStatusCommandOutput(result.getMessageFromContent(), state);
+ }
+
+ @Test
+ public void testWithInvalidDirOnline() throws Exception {
+ final String expectedError =
+ Launcher_Builder_WORKING_DIRECTORY_NOT_FOUND_ERROR_MESSAGE.toString(LOCATOR_TERM_NAME);
+
+ gfsh.connectAndVerify(locator.getPort(), PortType.locator);
+
+ CommandResult result = gfsh.executeCommand(STATUS_LOCATOR + " --dir=/invalid/working/dir");
+
+ assertThat(result.getStatus()).isEqualTo(Result.Status.ERROR);
+ assertThat(result.getMessageFromContent()).contains(expectedError);
+ }
+
+ @Test
+ public void testWithInvalidDirOffline() throws Exception {
+ final String expectedError =
+ Launcher_Builder_WORKING_DIRECTORY_NOT_FOUND_ERROR_MESSAGE.toString(LOCATOR_TERM_NAME);
+
+ if (gfsh.isConnected()) {
+ gfsh.disconnect();
+ }
+
+ CommandResult result = gfsh.executeCommand(STATUS_LOCATOR + " --dir=/invalid/working/dir");
+
+ assertThat(result.getStatus()).isEqualTo(Result.Status.ERROR);
+ assertThat(result.getMessageFromContent()).contains(expectedError);
+ }
+
+ public void assertStatusCommandOutput(String locatorStatusCommandMessage, LocatorState state) {
+ assertSoftly(softly -> {
+ softly.assertThat(locatorStatusCommandMessage)
+ .contains("Process ID: " + state.getPid())
+ .contains("Geode Version: " + state.getGemFireVersion())
+ .contains("Java Version: " + state.getJavaVersion())
+ .contains("Log File: " + state.getLogFile())
+ .contains("JVM Arguments: " + parseJvmArgs(state.getJvmArguments()))
+ .containsPattern("Uptime: \\d+");
+ });
+ }
+
+ public String parseJvmArgs(List<String> jvmArgs) {
+ String parsedArgs = jvmArgs.get(0);
+
+ for (int i = 1; i < jvmArgs.size(); i++) {
+ parsedArgs += " ";
+ parsedArgs += jvmArgs.get(i);
+ }
+
+ return parsedArgs;
+ }
+}
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/test/junit/rules/GfshCommandRule.java b/geode-core/src/integrationTest/java/org/apache/geode/test/junit/rules/GfshCommandRule.java
index 8a03309f04..f999cd7 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/test/junit/rules/GfshCommandRule.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/test/junit/rules/GfshCommandRule.java
@@ -39,7 +39,7 @@ import org.apache.geode.test.junit.assertions.CommandResultAssert;
/**
* Class which eases the connection to the locator/jmxManager in Gfsh shell and execute gfsh
- * commands.
+ * commands. This rule can't be used to start locators or servers; instead use GfshRule.
*
* <p>
* if used with {@link ConnectionConfiguration}, you will need to specify a port number when