GEODE-3436: revert recent refactoring of GFSH commands Revert "GEODE-3264: Refactoring MemberCommands" This reverts commit d27f8b956de7d9c5d95ebdc68dfc67ee8b2d7b51.
Revert "GEODE-3259: Refactoring DurableClientCommands" This reverts commit 440c87f81fab96f9ce38a2d53ded75e5fe8390d7. Revert "GEODE-3254: Refactoring ConfigCommands" This reverts commit 97c4e9a59f17c7bc914e39dd048b0a4cd96293c4. Revert "GEODE-3262: Refactoring IndexCommands" This reverts commit ed293e817e547fb5ecd399bf4ba10d694af51e0a. Revert "GEODE-3260: Refactoring FunctionCommands" This reverts commit 90f5440de8ec747f301a309a0a34101e8defcd29. Revert "GEODE-3258: Refactoring DiskStoreCommands" This reverts commit 5d6cad7755ec3c4fe931e3d0f8e89fb181038543. Revert "GEODE-3337: Refactoring LauncherLifecycleCommandsDUnitTest" This reverts commit 210ff9f15460c993f2bf7fd682d50ee65462cd23. Revert "GEODE-3265: Refactoring MiscellaneousCommands" This reverts commit 63169699e933f6e0fdd90b95ed039e4e3c92c32c. Revert "GEODE-3261: Refactoring GfshHelpCommands" This reverts commit cf91426692349d0c81ce77394935576d9cc336e8. Revert "GEODE-3267: Refactoring QueueCommands" This reverts commit fd47ed660168864a6f81b2a4cd7dbceebc99a282. Revert "GEODE-3270: Refactoring (renaming) StatusCommands" This reverts commit 359e3fff6482ecfb375939d387f4dad3a636246b. Revert "GEODE-3267: Refactoring QueueCommands - updated based on feedback" This reverts commit 957d583e54dc34c029885f32a54f0b25a3ac1094. Revert "GEODE-3268: Refactoring RegionCommands" This reverts commit 64de3b69c2aecb4930bcfd0a1161569b1d5fda89. Revert "GEODE-3266: Refactoring PDXCommands" This reverts commit 67185abcdd68b908dea6888cb94286b8aa9ea49f. Revert "GEODE-3257: Refactoring DeployCommands" This reverts commit 9d967446a44a78b612f605b6a8f8eedcfc625b3a. Revert "GEODE-3255: Refactor CreateAlterDestroyRegionCommands and tests" This reverts commit 756efe77c86bb03ac9984655e7bd040659e85890. Revert "GEODE-3230: Cleaning up unused (Cli)Strings" This reverts commit a7f29525df2981c1c99abac96ea83cb965295970. This closes #711 Project: http://git-wip-us.apache.org/repos/asf/geode/repo Commit: http://git-wip-us.apache.org/repos/asf/geode/commit/645a32d0 Tree: http://git-wip-us.apache.org/repos/asf/geode/tree/645a32d0 Diff: http://git-wip-us.apache.org/repos/asf/geode/diff/645a32d0 Branch: refs/heads/feature/GEODE-3249 Commit: 645a32d045958ff859967240416a57f6c570a00f Parents: 44fb3f2 Author: Kirk Lund <kl...@apache.org> Authored: Sat Aug 12 09:38:20 2017 -0700 Committer: Kirk Lund <kl...@apache.org> Committed: Sun Aug 13 15:43:27 2017 -0700 ---------------------------------------------------------------------- .../org/apache/geode/BundledJarsJUnitTest.java | 44 +- .../commands/GfshCommandIntegrationTest.java | 69 +- .../LauncherLifecycleCommandsDUnitTest.java | 1115 ++++++++++ .../cli/commands/StartLocatorCommandTest.java | 4 +- .../cli/commands/StartServerCommandTest.java | 4 +- ...deStatusClusterConfigServiceCommandTest.java | 391 ---- .../shell/GfshExitCodeStatusCommandsTest.java | 391 ++++ .../test/dunit/rules/gfsh/ProcessLogger.java | 10 +- .../geode/management/internal/cli/Launcher.java | 1 + .../commands/AlterOfflineDiskStoreCommand.java | 141 -- .../cli/commands/AlterRegionCommand.java | 229 --- .../cli/commands/AlterRuntimeConfigCommand.java | 246 --- .../cli/commands/AlterRuntimeInterceptor.java | 39 - .../cli/commands/BackupDiskStoreCommand.java | 142 -- .../cli/commands/ChangeLogLevelCommand.java | 163 -- .../commands/ClearDefinedIndexesCommand.java | 40 - .../cli/commands/CloseDurableCQsCommand.java | 83 - .../cli/commands/CloseDurableClientCommand.java | 77 - .../cli/commands/CompactDiskStoreCommand.java | 185 -- .../CompactOfflineDiskStoreCommand.java | 176 -- .../internal/cli/commands/ConfigCommands.java | 490 +++++ .../cli/commands/ConfigurePDXCommand.java | 138 -- .../commands/CountDurableCQEventsCommand.java | 88 - .../CreateAlterDestroyRegionCommands.java | 1146 +++++++++++ .../commands/CreateAsyncEventQueueCommand.java | 171 -- .../commands/CreateDefinedIndexesCommand.java | 154 -- .../cli/commands/CreateDiskStoreCommand.java | 166 -- .../cli/commands/CreateIndexCommand.java | 196 -- .../cli/commands/CreateRegionCommand.java | 741 ------- .../cli/commands/DefineIndexCommand.java | 95 - .../internal/cli/commands/DeployCommand.java | 190 -- .../internal/cli/commands/DeployCommands.java | 336 +++ .../cli/commands/DescribeConfigCommand.java | 153 -- .../cli/commands/DescribeDiskStoreCommand.java | 179 -- .../cli/commands/DescribeMemberCommand.java | 133 -- .../DescribeOfflineDiskStoreCommand.java | 75 - .../cli/commands/DescribeRegionCommand.java | 364 ---- .../cli/commands/DestroyDiskStoreCommand.java | 106 - .../cli/commands/DestroyFunctionCommand.java | 163 -- .../cli/commands/DestroyIndexCommand.java | 174 -- .../cli/commands/DestroyRegionCommand.java | 222 -- .../cli/commands/DiskStoreCommands.java | 1433 +++++++++++++ .../cli/commands/DiskStoreCommandsUtils.java | 60 - .../cli/commands/DurableClientCommands.java | 420 ++++ .../DurableClientCommandsResultBuilder.java | 164 -- .../cli/commands/ExecuteFunctionCommand.java | 330 --- .../cli/commands/ExportConfigCommand.java | 159 -- .../commands/ExportOfflineDiskStoreCommand.java | 68 - .../cli/commands/ExportStackTraceCommand.java | 157 -- .../internal/cli/commands/FunctionCommands.java | 537 +++++ .../internal/cli/commands/GCCommand.java | 131 -- .../internal/cli/commands/GfshHelpCommand.java | 51 - .../internal/cli/commands/GfshHelpCommands.java | 55 + .../internal/cli/commands/GfshHintCommand.java | 42 - .../internal/cli/commands/IndexCommands.java | 668 ++++++ .../internal/cli/commands/IndexDefinition.java | 27 - .../commands/IndexStatisticsDetailsAdapter.java | 58 - .../commands/ListAsyncEventQueuesCommand.java | 118 -- .../cli/commands/ListDeployedCommand.java | 102 - .../cli/commands/ListDiskStoresCommand.java | 113 - .../commands/ListDurableClientCQsCommand.java | 121 -- .../cli/commands/ListFunctionCommand.java | 100 - .../internal/cli/commands/ListIndexCommand.java | 119 -- .../cli/commands/ListMemberCommand.java | 77 - .../cli/commands/ListRegionCommand.java | 86 - .../internal/cli/commands/MemberCommands.java | 197 ++ .../cli/commands/MiscellaneousCommands.java | 1926 ++++++++++++++++++ .../internal/cli/commands/NetstatCommand.java | 212 -- .../internal/cli/commands/PDXCommands.java | 195 ++ .../internal/cli/commands/PDXRenameCommand.java | 81 - .../internal/cli/commands/QueueCommands.java | 259 +++ .../internal/cli/commands/RegionCommands.java | 474 +++++ .../cli/commands/RegionCommandsUtils.java | 59 - .../commands/RevokeMissingDiskStoreCommand.java | 61 - .../internal/cli/commands/ShellCommands.java | 5 +- .../cli/commands/ShowDeadlockCommand.java | 92 - .../internal/cli/commands/ShowLogCommand.java | 102 - .../cli/commands/ShowMetricsCommand.java | 1085 ---------- .../commands/ShowMissingDiskStoreCommand.java | 150 -- .../internal/cli/commands/ShutdownCommand.java | 209 -- .../cli/commands/StartLocatorCommand.java | 67 +- .../cli/commands/StartMemberCommand.java | 248 --- .../internal/cli/commands/StartMemberUtils.java | 251 +++ .../cli/commands/StartServerCommand.java | 117 +- .../StatusClusterConfigServiceCommand.java | 82 - .../internal/cli/commands/StatusCommands.java | 82 + .../internal/cli/commands/UndeployCommand.java | 114 -- .../UpgradeOfflineDiskStoreCommand.java | 177 -- .../cli/commands/ValidateDiskStoreCommand.java | 105 - .../commands/lifecycle/StopLocatorCommand.java | 16 +- .../internal/cli/converters/HelpConverter.java | 25 +- .../functions/CreateDefinedIndexesFunction.java | 3 +- .../cli/functions/DataCommandFunction.java | 8 +- .../GetSubscriptionQueueSizeFunction.java | 2 +- .../cli/functions/RegionCreateFunction.java | 8 +- .../management/internal/cli/help/Helper.java | 20 +- .../internal/cli/i18n/CliStrings.java | 397 +++- .../controllers/ConfigCommandsController.java | 17 +- .../controllers/DeployCommandsController.java | 24 +- .../DiskStoreCommandsController.java | 18 +- .../DurableClientCommandsController.java | 15 +- .../controllers/FunctionCommandsController.java | 13 +- .../controllers/IndexCommandsController.java | 13 +- .../controllers/MemberCommandsController.java | 23 +- .../MiscellaneousCommandsController.java | 16 +- .../web/controllers/PdxCommandsController.java | 11 +- .../controllers/QueueCommandsController.java | 10 +- .../controllers/RegionCommandsController.java | 14 +- .../geode/redis/internal/RegionProvider.java | 15 +- .../commands/AlterRegionCommandDUnitTest.java | 641 ------ ...eateAlterDestroyRegionCommandsDUnitTest.java | 1211 ++++++++++- .../CreateAlterDestroyRegionCommandsTest.java | 53 + .../commands/CreateRegionCommandDUnitTest.java | 318 --- .../cli/commands/CreateRegionCommandTest.java | 58 - .../cli/commands/DeployCommandsDUnitTest.java | 2 +- .../commands/DestroyRegionCommandDUnitTest.java | 388 ---- .../commands/DiskStoreCommandsDUnitTest.java | 46 +- .../commands/DiskStoreCommandsJUnitTest.java | 112 +- .../cli/commands/GfshCommandJUnitTest.java | 219 +- .../cli/commands/IndexCommandsJUnitTest.java | 223 ++ ...stAndDescribeDiskStoreCommandsDUnitTest.java | 36 +- .../cli/commands/ListIndexCommandDUnitTest.java | 38 +- .../cli/commands/ListIndexCommandJUnitTest.java | 223 -- .../cli/commands/LogLevelInterceptorTest.java | 21 +- .../MiscellaneousCommandsDUnitTest.java | 136 +- .../cli/commands/ShowStackTraceDUnitTest.java | 23 +- .../commands/StartLocatorCommandUnitTest.java | 59 - .../cli/commands/StartMemberCommandTest.java | 335 --- .../commands/StartServerCommandUnitTest.java | 78 - .../commands/StatusLocatorCommandUnitTest.java | 53 - .../lifecycle/StopLocatorCommandUnitTest.java | 74 - .../cli/help/HelperIntegrationTest.java | 73 +- .../internal/security/TestCommand.java | 27 +- .../org/apache/geode/redis/SetsJUnitTest.java | 21 +- .../apache/geode/redis/SortedSetsJUnitTest.java | 34 +- .../DurableClientCommandsDUnitTest.java | 4 +- .../rules/RetryRuleLocalWithErrorTest.java | 2 +- 137 files changed, 12540 insertions(+), 13212 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/geode/blob/645a32d0/geode-assembly/src/test/java/org/apache/geode/BundledJarsJUnitTest.java ---------------------------------------------------------------------- diff --git a/geode-assembly/src/test/java/org/apache/geode/BundledJarsJUnitTest.java b/geode-assembly/src/test/java/org/apache/geode/BundledJarsJUnitTest.java index 3a5538c..3f0e2c0 100644 --- a/geode-assembly/src/test/java/org/apache/geode/BundledJarsJUnitTest.java +++ b/geode-assembly/src/test/java/org/apache/geode/BundledJarsJUnitTest.java @@ -16,6 +16,14 @@ package org.apache.geode; import static org.junit.Assert.assertTrue; +import org.apache.commons.io.FileUtils; +import org.apache.geode.test.junit.categories.IntegrationTest; +import org.apache.geode.test.junit.categories.RestAPITest; +import org.apache.geode.util.test.TestUtil; +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.categories.Category; + import java.io.File; import java.io.IOException; import java.nio.file.Files; @@ -28,20 +36,11 @@ import java.util.jar.JarFile; import java.util.stream.Collectors; import java.util.stream.Stream; -import org.apache.commons.io.FileUtils; -import org.junit.Before; -import org.junit.Test; -import org.junit.experimental.categories.Category; - -import org.apache.geode.test.junit.categories.IntegrationTest; -import org.apache.geode.test.junit.categories.RestAPITest; -import org.apache.geode.util.test.TestUtil; - @Category({IntegrationTest.class, RestAPITest.class}) public class BundledJarsJUnitTest { private static final String VERSION_PATTERN = "[0-9-_.v]{3,}.*\\.jar$"; - private static final String GEODE_HOME = System.getenv("GEODE_HOME"); + protected static final String GEODE_HOME = System.getenv("GEODE_HOME"); private Set<String> expectedJars; @Before @@ -66,22 +65,27 @@ public class BundledJarsJUnitTest { TreeSet<String> missingJars = new TreeSet<String>(expectedJars); missingJars.removeAll(bundledJarNames); - String message = - "The bundled jars have changed. Please make sure you update the licence and notice" - + "\nas described in https://cwiki.apache.org/confluence/display/GEODE/License+Guide+for+Contributors" - + "\nWhen fixed, copy geode-assembly/build/test/bundled_jars.txt" - + "\nto src/test/resources/expected_jars.txt" + "\nRemoved Jars\n--------------\n" - + String.join("\n", missingJars) + "\n\nAdded Jars\n--------------\n" - + String.join("\n", newJars) + "\n\n"; - - assertTrue(message, expectedJars.equals(bundledJarNames)); + StringBuilder message = new StringBuilder(); + message.append( + "The bundled jars have changed. Please make sure you update the licence and notice"); + message.append( + "\nas described in https://cwiki.apache.org/confluence/display/GEODE/License+Guide+for+Contributors"); + message.append("\nWhen fixed, copy geode-assembly/build/test/bundled_jars.txt"); + message.append("\nto src/test/resources/expected_jars.txt"); + message.append("\nRemoved Jars\n--------------\n"); + message.append(String.join("\n", missingJars)); + message.append("\n\nAdded Jars\n--------------\n"); + message.append(String.join("\n", newJars)); + message.append("\n\n"); + + assertTrue(message.toString(), expectedJars.equals(bundledJarNames)); } /** * Find all of the jars bundled with the project. Key is the name of the jar, value is the path. */ - private TreeMap<String, String> getBundledJars() { + protected TreeMap<String, String> getBundledJars() { File geodeHomeDirectory = new File(GEODE_HOME); assertTrue( http://git-wip-us.apache.org/repos/asf/geode/blob/645a32d0/geode-assembly/src/test/java/org/apache/geode/management/internal/cli/commands/GfshCommandIntegrationTest.java ---------------------------------------------------------------------- diff --git a/geode-assembly/src/test/java/org/apache/geode/management/internal/cli/commands/GfshCommandIntegrationTest.java b/geode-assembly/src/test/java/org/apache/geode/management/internal/cli/commands/GfshCommandIntegrationTest.java index a191905..263b12c 100644 --- a/geode-assembly/src/test/java/org/apache/geode/management/internal/cli/commands/GfshCommandIntegrationTest.java +++ b/geode-assembly/src/test/java/org/apache/geode/management/internal/cli/commands/GfshCommandIntegrationTest.java @@ -15,11 +15,16 @@ package org.apache.geode.management.internal.cli.commands; +import static org.assertj.core.api.Java6Assertions.assertThat; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import java.io.File; +import java.io.FileWriter; import java.io.IOException; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -28,12 +33,14 @@ import java.util.jar.Attributes; import java.util.jar.JarFile; import java.util.jar.Manifest; +import org.apache.commons.io.FileUtils; import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.rules.TemporaryFolder; import org.junit.rules.TestName; +import org.apache.geode.internal.util.IOUtils; import org.apache.geode.test.junit.categories.IntegrationTest; @Category(IntegrationTest.class) @@ -45,8 +52,60 @@ public class GfshCommandIntegrationTest { public TestName testName = new TestName(); @Test + public void workingDirDefaultsToMemberName() { + StartServerCommand startServer = new StartServerCommand(); + String workingDir = StartMemberUtils.resolveWorkingDir(null, "server1"); + assertThat(new File(workingDir)).exists(); + assertThat(workingDir).endsWith("server1"); + } + + @Test + public void workingDirGetsCreatedIfNecessary() throws Exception { + File workingDir = temporaryFolder.newFolder("foo"); + FileUtils.deleteQuietly(workingDir); + String workingDirString = workingDir.getAbsolutePath(); + + StartServerCommand startServer = new StartServerCommand(); + + String resolvedWorkingDir = StartMemberUtils.resolveWorkingDir(workingDirString, "server1"); + assertThat(new File(resolvedWorkingDir)).exists(); + assertThat(workingDirString).endsWith("foo"); + } + + @Test + public void testWorkingDirWithRelativePath() throws Exception { + Path relativePath = Paths.get("some").resolve("relative").resolve("path"); + assertThat(relativePath.isAbsolute()).isFalse(); + + StartServerCommand startServer = new StartServerCommand(); + + String resolvedWorkingDir = + StartMemberUtils.resolveWorkingDir(relativePath.toString(), "server1"); + + assertThat(resolvedWorkingDir).isEqualTo(relativePath.toAbsolutePath().toString()); + } + + @Test + public void testReadPid() throws IOException { + final int expectedPid = 12345; + + File folder = temporaryFolder.newFolder(); + File pidFile = + new File(folder, getClass().getSimpleName() + "_" + testName.getMethodName() + ".pid"); + + assertTrue(pidFile.createNewFile()); + + pidFile.deleteOnExit(); + writePid(pidFile, expectedPid); + + final int actualPid = StartMemberUtils.readPid(pidFile); + + assertEquals(expectedPid, actualPid); + } + + @Test public void testGemFireCoreClasspath() throws IOException { - File coreDependenciesJar = new File(StartMemberCommand.CORE_DEPENDENCIES_JAR_PATHNAME); + File coreDependenciesJar = new File(StartMemberUtils.CORE_DEPENDENCIES_JAR_PATHNAME); assertNotNull(coreDependenciesJar); assertTrue(coreDependenciesJar + " is not a file", coreDependenciesJar.isFile()); Collection<String> expectedJarDependencies = @@ -108,5 +167,11 @@ public class GfshCommandIntegrationTest { missingExpectedJarDependenciesList.isEmpty()); } - + private void writePid(final File pidFile, final int pid) throws IOException { + final FileWriter fileWriter = new FileWriter(pidFile, false); + fileWriter.write(String.valueOf(pid)); + fileWriter.write("\n"); + fileWriter.flush(); + IOUtils.close(fileWriter); + } } http://git-wip-us.apache.org/repos/asf/geode/blob/645a32d0/geode-assembly/src/test/java/org/apache/geode/management/internal/cli/commands/LauncherLifecycleCommandsDUnitTest.java ---------------------------------------------------------------------- diff --git a/geode-assembly/src/test/java/org/apache/geode/management/internal/cli/commands/LauncherLifecycleCommandsDUnitTest.java b/geode-assembly/src/test/java/org/apache/geode/management/internal/cli/commands/LauncherLifecycleCommandsDUnitTest.java new file mode 100644 index 0000000..6e5d17c --- /dev/null +++ b/geode-assembly/src/test/java/org/apache/geode/management/internal/cli/commands/LauncherLifecycleCommandsDUnitTest.java @@ -0,0 +1,1115 @@ +/* + * 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.distributed.ConfigurationProperties.DURABLE_CLIENT_ID; +import static org.apache.geode.distributed.ConfigurationProperties.START_LOCATOR; +import static org.apache.geode.test.dunit.Assert.assertEquals; +import static org.apache.geode.test.dunit.Assert.assertFalse; +import static org.apache.geode.test.dunit.Assert.assertNotNull; +import static org.apache.geode.test.dunit.Assert.assertTrue; +import static org.apache.geode.test.dunit.Wait.waitForCriterion; + +import java.io.BufferedReader; +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; +import java.text.MessageFormat; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Queue; +import java.util.Set; +import java.util.concurrent.ConcurrentLinkedDeque; +import java.util.concurrent.TimeUnit; + +import javax.management.MBeanServerConnection; +import javax.management.ObjectName; +import javax.management.Query; +import javax.management.QueryExp; +import javax.management.remote.JMXConnector; +import javax.management.remote.JMXConnectorFactory; +import javax.management.remote.JMXServiceURL; + +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.junit.runners.MethodSorters; + +import org.apache.geode.cache.Region; +import org.apache.geode.cache.client.ClientCache; +import org.apache.geode.cache.client.ClientCacheFactory; +import org.apache.geode.cache.client.ClientRegionFactory; +import org.apache.geode.cache.client.ClientRegionShortcut; +import org.apache.geode.cache.client.Pool; +import org.apache.geode.cache.client.PoolFactory; +import org.apache.geode.cache.client.PoolManager; +import org.apache.geode.distributed.AbstractLauncher.ServiceState; +import org.apache.geode.distributed.AbstractLauncher.Status; +import org.apache.geode.distributed.LocatorLauncher; +import org.apache.geode.distributed.LocatorLauncher.Builder; +import org.apache.geode.distributed.LocatorLauncher.Command; +import org.apache.geode.distributed.LocatorLauncher.LocatorState; +import org.apache.geode.distributed.ServerLauncher; +import org.apache.geode.distributed.ServerLauncher.ServerState; +import org.apache.geode.distributed.internal.DistributionConfig; +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; +import org.apache.geode.management.internal.cli.i18n.CliStrings; +import org.apache.geode.management.internal.cli.result.CommandResult; +import org.apache.geode.management.internal.cli.util.CommandStringBuilder; +import org.apache.geode.test.dunit.WaitCriterion; +import org.apache.geode.test.junit.categories.DistributedTest; + +/** + * The LauncherLifecycleCommandsDUnitTest class is a test suite of integration tests testing the + * contract and functionality of the GemFire launcher lifecycle commands inside Gfsh. + * + * @see javax.management.MBeanServerConnection + * @see javax.management.remote.JMXConnector + * @see org.apache.geode.distributed.AbstractLauncher + * @see org.apache.geode.distributed.LocatorLauncher + * @see org.apache.geode.distributed.ServerLauncher + * @see org.apache.geode.internal.AvailablePortHelper + * @see org.apache.geode.management.internal.cli.shell.Gfsh + * @see org.apache.geode.management.internal.cli.commands.CliCommandTestBase + * @see org.apache.geode.management.internal.cli.util.CommandStringBuilder + * @since GemFire 7.0 + */ +@Category(DistributedTest.class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class LauncherLifecycleCommandsDUnitTest extends CliCommandTestBase { + + protected static final DateFormat TIMESTAMP = new SimpleDateFormat("yyyyMMddHHmmssSSS"); + + private final Queue<Integer> processIds = new ConcurrentLinkedDeque<>(); + + protected static String getMemberId(final int jmxManagerPort, final String memberName) + throws Exception { + return getMemberId(InetAddress.getLocalHost().getHostName(), jmxManagerPort, memberName); + } + + protected static String getMemberId(final String jmxManagerHost, final int jmxManagerPort, + final String memberName) throws Exception { + JMXConnector connector = null; + + try { + connector = JMXConnectorFactory.connect(new JMXServiceURL(String.format( + "service:jmx:rmi://%1$s/jndi/rmi://%1$s:%2$d/jmxrmi", jmxManagerHost, jmxManagerPort))); + + MBeanServerConnection connection = connector.getMBeanServerConnection(); + + ObjectName objectNamePattern = ObjectName.getInstance("GemFire:type=Member,*"); + + QueryExp query = Query.eq(Query.attr("Name"), Query.value(memberName)); + + Set<ObjectName> objectNames = connection.queryNames(objectNamePattern, query); + + assertNotNull(objectNames); + assertFalse(objectNames.isEmpty()); + assertEquals(1, objectNames.size()); + + // final ObjectName objectName = ObjectName.getInstance("GemFire:type=Member,Name=" + + // memberName); + ObjectName objectName = objectNames.iterator().next(); + + // System.err.printf("ObjectName for Member with Name (%1$s) is %2$s%n", memberName, + // objectName); + + return ObjectUtils.toString(connection.getAttribute(objectName, "Id")); + } finally { + IOUtils.close(connector); + } + } + + @Override + public final void postTearDown() throws Exception { + Integer pid; + + while ((pid = processIds.poll()) != null) { + if (ProcessUtils.isProcessAlive(pid)) { + try { + String killCommand = String.format("%1$s %2$d", + SystemUtils.isWindows() ? "taskkill /F /PID" : "kill -9", pid); + Runtime.getRuntime().exec(killCommand); + } catch (Throwable ignore) { + } + } + } + } + + @SuppressWarnings("unused") + protected void assertStatus(final LocatorState expectedStatus, final LocatorState actualStatus) { + assertEquals(expectedStatus.getStatus(), actualStatus.getStatus()); + assertEquals(expectedStatus.getTimestamp(), actualStatus.getTimestamp()); + assertEquals(expectedStatus.getServiceLocation(), actualStatus.getServiceLocation()); + assertTrue(ObjectUtils.equalsIgnoreNull(expectedStatus.getPid(), actualStatus.getPid())); + assertEquals(expectedStatus.getUptime(), actualStatus.getUptime()); + assertEquals(expectedStatus.getWorkingDirectory(), actualStatus.getWorkingDirectory()); + assertEquals(expectedStatus.getJvmArguments(), actualStatus.getJvmArguments()); + assertEquals(expectedStatus.getClasspath(), actualStatus.getClasspath()); + assertEquals(expectedStatus.getGemFireVersion(), actualStatus.getGemFireVersion()); + assertEquals(expectedStatus.getJavaVersion(), actualStatus.getJavaVersion()); + } + + protected Integer readPid(final File workingDirectory) throws IOException { + assertTrue(String.format("The working directory (%1$s) must exist!", workingDirectory), + workingDirectory != null && workingDirectory.isDirectory()); + + File[] files = workingDirectory.listFiles(pathname -> (pathname != null && pathname.isFile() + && pathname.getAbsolutePath().endsWith(".pid"))); + + assertNotNull(files); + assertTrue(files.length > 0); + + File pidFile = files[0]; + + BufferedReader fileReader = null; + + try { + fileReader = new BufferedReader(new FileReader(pidFile), 1024); + return Integer.parseInt(fileReader.readLine().trim()); + } catch (Exception ignore) { + return null; + } finally { + IOUtils.close(fileReader); + } + } + + protected String serviceStateStatusStringNormalized(final ServiceState serviceState) { + return serviceStateStatusStringNormalized(serviceState.toString()); + } + + protected String serviceStateStatusStringNormalized(final String serviceStateStatus) { + assertNotNull(serviceStateStatus); + assertTrue("serviceStateStatus is missing 'Uptime': " + serviceStateStatus, + serviceStateStatus.contains("Uptime")); + assertTrue("serviceStateStatus is missing 'JVM Arguments': " + serviceStateStatus, + serviceStateStatus.contains("JVM Arguments")); + + return serviceStateStatus.substring(0, serviceStateStatus.indexOf("Uptime")) + .concat(serviceStateStatus.substring(serviceStateStatus.indexOf("JVM Arguments"))); + } + + protected Status stopLocator(final File workingDirectory) { + return stopLocator(IOUtils.tryGetCanonicalPathElseGetAbsolutePath(workingDirectory)); + } + + protected Status stopLocator(final String workingDirectory) { + return waitForGemFireProcessToStop( + new Builder().setCommand(Command.STOP).setWorkingDirectory(workingDirectory).build().stop(), + workingDirectory); + } + + protected Status stopServer(final String workingDirectory) { + return waitForGemFireProcessToStop( + new ServerLauncher.Builder().setCommand(ServerLauncher.Command.STOP) + .setWorkingDirectory(workingDirectory).build().stop(), + workingDirectory); + } + + protected String toString(final Result result) { + assert result != null : "The Result object from the command execution cannot be null!"; + + StringBuilder buffer = new StringBuilder(StringUtils.LINE_SEPARATOR); + + while (result.hasNextLine()) { + buffer.append(result.nextLine()); + buffer.append(StringUtils.LINE_SEPARATOR); + } + + return buffer.toString(); + } + + protected Status waitForGemFireProcessToStop(final ServiceState serviceState, + final String workingDirectory) { + if (!Status.STOPPED.equals(serviceState.getStatus())) { + try { + final Integer pid = readPid(new File(workingDirectory)); + + if (pid != null) { + WaitCriterion waitCriteria = new WaitCriterion() { + @Override + public boolean done() { + return !ProcessUtils.isProcessAlive(pid); + } + + @Override + public String description() { + return String.format("Waiting for GemFire Process with PID (%1$d) to stop.", pid); + } + }; + + waitForCriterion(waitCriteria, TimeUnit.SECONDS.toMillis(15), + TimeUnit.SECONDS.toMillis(5), false); + + if (!waitCriteria.done()) { + processIds.offer(pid); + } + } + } catch (IOException ignore) { + } + } + + 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 + * + * @throws IOException + */ + @Test + public void testVersionTitleForStartServerAndLocator() throws IOException { + final int locatorPort = AvailablePortHelper.getRandomAvailableTCPPort(); + + String pathname = (getClass().getSimpleName() + "_" + getTestMethodName()); + String pathnameLoc = pathname + "_loc"; + String pathnameSer = pathname + "_ser"; + + File workingDirectoryLoc = temporaryFolder.newFolder(pathnameLoc); + File workingDirectorySer = temporaryFolder.newFolder(pathnameSer); + + assertTrue(workingDirectoryLoc.isDirectory() || workingDirectoryLoc.mkdir()); + assertTrue(workingDirectorySer.isDirectory() || workingDirectorySer.mkdir()); + + try { + // verify the start locator output does not contain string "gemfire" + CommandStringBuilder locCommand = new CommandStringBuilder(CliStrings.START_LOCATOR); + locCommand.addOption(CliStrings.START_LOCATOR__MEMBER_NAME, pathnameLoc); + locCommand.addOption(CliStrings.START_LOCATOR__CONNECT, Boolean.FALSE.toString()); + locCommand.addOption(CliStrings.START_LOCATOR__DIR, workingDirectoryLoc.getCanonicalPath()); + locCommand.addOption(CliStrings.START_LOCATOR__PORT, String.valueOf(locatorPort)); + + CommandResult locResult = executeCommand(locCommand.toString()); + assertNotNull(locResult); + assertEquals(Result.Status.OK, locResult.getStatus()); + String locatorOutput = toString(locResult); + assertNotNull(locatorOutput); + assertTrue("Locator output was: " + locatorOutput, !locatorOutput.contains("Gemfire")); + + // verify the start server output does not contain string "gemfire" + CommandStringBuilder serCommand = new CommandStringBuilder(CliStrings.START_SERVER); + serCommand.addOption(CliStrings.START_SERVER__NAME, pathnameSer); + serCommand.addOption(CliStrings.START_SERVER__DIR, workingDirectorySer.getCanonicalPath()); + + CommandResult serResult = executeCommand(serCommand.toString()); + assertNotNull(serResult); + assertEquals(Result.Status.OK, serResult.getStatus()); + String serverOutput = toString(serResult); + + assertTrue("Server start output was: " + serverOutput, !serverOutput.contains("Gemfire")); + } finally { + stopLocator(workingDirectoryLoc); + stopServer(IOUtils.tryGetCanonicalPathElseGetAbsolutePath(workingDirectorySer)); + } + } + + @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"; + + CommandStringBuilder command = new CommandStringBuilder(CliStrings.START_SERVER); + String pathName = getClass().getSimpleName().concat("_").concat(getTestMethodName()); + final File workingDirectory = temporaryFolder.newFolder(pathName); + + command.addOption(CliStrings.START_SERVER__NAME, pathName); + command.addOption(CliStrings.START_SERVER__DIR, workingDirectory.getCanonicalPath()); + command.addOption(CliStrings.START_SERVER__CACHE_XML_FILE, cacheXmlPathname); + + CommandResult result = executeCommand(command.toString()); + + assertNotNull(result); + assertEquals(Result.Status.ERROR, result.getStatus()); + + String resultString = toString(result); + + assertTrue(resultString, resultString + .contains(MessageFormat.format(CliStrings.CACHE_XML_NOT_FOUND_MESSAGE, cacheXmlPathname))); + } + + @Test + public void test004StartServerFailsFastOnMissingGemFirePropertiesFile() throws IOException { + String gemfirePropertiesFile = "/path/to/missing/gemfire.properties"; + + CommandStringBuilder command = new CommandStringBuilder(CliStrings.START_SERVER); + + String pathName = getClass().getSimpleName().concat("_").concat(getTestMethodName()); + final File workingDirectory = temporaryFolder.newFolder(pathName); + + command.addOption(CliStrings.START_SERVER__NAME, pathName); + command.addOption(CliStrings.START_SERVER__DIR, workingDirectory.getCanonicalPath()); + command.addOption(CliStrings.START_SERVER__PROPERTIES, gemfirePropertiesFile); + + 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, gemfirePropertiesFile))); + } + + @Test + public void testStartServerFailsFastOnMissingPassword() throws IOException { + + CommandStringBuilder command = new CommandStringBuilder(CliStrings.START_SERVER); + + String pathName = getClass().getSimpleName().concat("_").concat(getTestMethodName()); + final File workingDirectory = temporaryFolder.newFolder(pathName); + + command.addOption(CliStrings.START_SERVER__NAME, pathName); + command.addOption(CliStrings.START_SERVER__DIR, workingDirectory.getCanonicalPath()); + command.addOption(CliStrings.START_SERVER__USERNAME, "test"); + + CommandResult result = executeCommand(command.toString()); + + assertNotNull(result); + assertEquals(Result.Status.ERROR, result.getStatus()); + + String resultString = toString(result); + + assertTrue(resultString, resultString.contains("password must be specified")); + } + + @Test + public void test005StartServerFailsFastOnMissingGemFireSecurityPropertiesFile() + throws IOException { + String gemfireSecuritiesPropertiesFile = "/path/to/missing/gemfire-securities.properties"; + + CommandStringBuilder command = new CommandStringBuilder(CliStrings.START_SERVER); + + String pathName = getClass().getSimpleName().concat("_").concat(getTestMethodName()); + final File workingDirectory = temporaryFolder.newFolder(pathName); + + command.addOption(CliStrings.START_SERVER__NAME, pathName); + command.addOption(CliStrings.START_SERVER__DIR, workingDirectory.getCanonicalPath()); + command.addOption(CliStrings.START_SERVER__SECURITY_PROPERTIES, + gemfireSecuritiesPropertiesFile); + + 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 ", gemfireSecuritiesPropertiesFile))); + } + + @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); + + 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=%2$s", CliStrings.STATUS_LOCATOR, + getMemberId(jmxManagerPort, pathname))); + + assertNotNull(result); + assertEquals(Result.Status.OK, result.getStatus()); + assertTrue(serviceStateStatusStringNormalized(toString(result)) + .contains(serviceStateStatusStringNormalized(expectedLocatorState))); + } finally { + stopLocator(workingDirectory); + } + } + + @Test + public void test010StopLocatorUsingMemberNameIDWhenGfshIsNotConnected() { + CommandResult result = + executeCommand(CliStrings.STOP_LOCATOR + " --name=" + getTestMethodName()); + + assertNotNull(result); + assertEquals(Result.Status.ERROR, result.getStatus()); + assertEquals( + CliStrings.format(CliStrings.STOP_SERVICE__GFSH_NOT_CONNECTED_ERROR_MESSAGE, "Locator"), + StringUtils.trim(toString(result))); + } + + @Test + public void test011StopLocatorUsingMemberName() 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); + + try { + assertTrue(workingDirectory.isDirectory() || workingDirectory.mkdir()); + + 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()); + + final LocatorLauncher locatorLauncher = + new Builder().setCommand(Command.STOP).setBindAddress(null).setPort(locatorPort) + .setWorkingDirectory(workingDirectory.getPath()).build(); + + assertNotNull(locatorLauncher); + + LocatorState locatorStatus = locatorLauncher.waitOnStatusResponse(60, 10, TimeUnit.SECONDS); + + assertNotNull(locatorStatus); + assertEquals(Status.ONLINE, locatorStatus.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.STOP_LOCATOR)); + + assertNotNull(result); + assertEquals(Result.Status.ERROR, result.getStatus()); + assertEquals( + CliStrings.format(CliStrings.STOP_LOCATOR__NO_LOCATOR_FOUND_FOR_MEMBER_ERROR_MESSAGE, + "invalidLocatorMemberName"), + StringUtils.trim(toString(result))); + + locatorStatus = locatorLauncher.status(); + + assertNotNull(locatorStatus); + assertEquals(Status.ONLINE, locatorStatus.getStatus()); + + result = executeCommand(String.format("%1$s --name=%2$s", CliStrings.STOP_LOCATOR, pathname)); + + assertNotNull(result); + assertEquals(Result.Status.OK, result.getStatus()); + + // TODO figure out what output to assert and validate on now that 'stop locator' uses Gfsh's + // logger + // and standard err/out... + // assertIndexDetailsEquals(CliStrings.format(CliStrings.STOP_LOCATOR__SHUTDOWN_MEMBER_MESSAGE, + // pathname), + // StringUtils.trim(toString(result))); + + WaitCriterion waitCriteria = new WaitCriterion() { + @Override + public boolean done() { + final LocatorState locatorStatus = locatorLauncher.status(); + return (locatorStatus != null && Status.NOT_RESPONDING.equals(locatorStatus.getStatus())); + } + + @Override + public String description() { + return "wait for the Locator to stop; the Locator will no longer respond after it stops"; + } + }; + + waitForCriterion(waitCriteria, 15 * 1000, 5000, true); + + locatorStatus = locatorLauncher.status(); + + assertNotNull(locatorStatus); + assertEquals(Status.NOT_RESPONDING, locatorStatus.getStatus()); + } finally { + } + + } + + // @see Trac Bug # 46760 + @Test + public void test012StopLocatorUsingMemberId() throws Exception { + 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); + + try { + assertTrue(workingDirectory.isDirectory() || workingDirectory.mkdir()); + + 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()); + + final LocatorLauncher locatorLauncher = + new Builder().setCommand(Command.STOP).setBindAddress(null).setPort(locatorPort) + .setWorkingDirectory(workingDirectory.getPath()).build(); + + assertNotNull(locatorLauncher); + + LocatorState locatorState = locatorLauncher.waitOnStatusResponse(60, 10, TimeUnit.SECONDS); + + assertNotNull(locatorState); + assertEquals(Status.ONLINE, locatorState.getStatus()); + + result = executeCommand( + String.format("%1$s --locator=localhost[%2$d]", CliStrings.CONNECT, locatorPort)); + + assertNotNull(result); + assertEquals(Result.Status.OK, result.getStatus()); + + String memberId = getMemberId(jmxManagerPort, pathname); + + result = executeCommand(String.format("%1$s --name=%2$s", CliStrings.STOP_LOCATOR, memberId)); + + assertNotNull(result); + assertEquals(Result.Status.OK, result.getStatus()); + + // TODO figure out what output to assert and validate on now that 'stop locator' uses Gfsh's + // logger + // and standard err/out... + // assertIndexDetailsEquals(CliStrings.format(CliStrings.STOP_LOCATOR__SHUTDOWN_MEMBER_MESSAGE, + // memberId), + // StringUtils.trim(toString(result))); + + WaitCriterion waitCriteria = new WaitCriterion() { + @Override + public boolean done() { + LocatorState locatorState = locatorLauncher.status(); + return (locatorState != null && Status.NOT_RESPONDING.equals(locatorState.getStatus())); + } + + @Override + public String description() { + return "wait for the Locator to stop; the Locator will no longer respond after it stops"; + } + }; + + waitForCriterion(waitCriteria, 15 * 1000, 5000, true); + + locatorState = locatorLauncher.status(); + + assertNotNull(locatorState); + assertEquals(Status.NOT_RESPONDING, locatorState.getStatus()); + } finally { + } + } + + @Test + public void test014GemFireServerJvmProcessTerminatesOnOutOfMemoryError() throws Exception { + int ports[] = AvailablePortHelper.getRandomAvailableTCPPorts(2); + final int serverPort = ports[0]; + final int locatorPort = ports[1]; + + String pathname = getClass().getSimpleName().concat("_").concat(getTestMethodName()); + File workingDirectory = temporaryFolder.newFolder(pathname); + + assertTrue(workingDirectory.isDirectory() || workingDirectory.mkdir()); + + CommandStringBuilder command = new CommandStringBuilder(CliStrings.START_SERVER); + + command.addOption(CliStrings.START_SERVER__NAME, + pathname + TIMESTAMP.format(Calendar.getInstance().getTime())); + command.addOption(CliStrings.START_SERVER__SERVER_PORT, String.valueOf(serverPort)); + command.addOption(CliStrings.START_SERVER__USE_CLUSTER_CONFIGURATION, Boolean.FALSE.toString()); + command.addOption(CliStrings.START_SERVER__MAXHEAP, "10M"); + command.addOption(CliStrings.START_SERVER__LOG_LEVEL, "config"); + command.addOption(CliStrings.START_SERVER__DIR, workingDirectory.getCanonicalPath()); + command.addOption(CliStrings.START_SERVER__CACHE_XML_FILE, + IOUtils.tryGetCanonicalPathElseGetAbsolutePath(writeAndGetCacheXmlFile(workingDirectory))); + command.addOption(CliStrings.START_SERVER__INCLUDE_SYSTEM_CLASSPATH); + command.addOption(CliStrings.START_SERVER__J, "-D" + DistributionConfig.GEMFIRE_PREFIX + "" + + START_LOCATOR + "=localhost[" + locatorPort + "]"); + + + CommandResult result = executeCommand(command.toString()); + System.out.println("result=" + result); + + assertNotNull(result); + assertEquals(Result.Status.OK, result.getStatus()); + + ServerLauncher serverLauncher = + new ServerLauncher.Builder().setCommand(ServerLauncher.Command.STATUS) + .setWorkingDirectory(IOUtils.tryGetCanonicalPathElseGetAbsolutePath(workingDirectory)) + .build(); + + assertNotNull(serverLauncher); + + ServerState serverState = serverLauncher.status(); + + assertNotNull(serverState); + assertEquals(Status.ONLINE, serverState.getStatus()); + + // Verify our GemFire Server JVM process is running! + assertTrue(serverState.isVmWithProcessIdRunning()); + + ClientCache clientCache = setupClientCache(pathname + String.valueOf(serverPort), serverPort); + + assertNotNull(clientCache); + + try { + Region<Long, String> exampleRegion = clientCache.getRegion("/Example"); + // run the GemFire Server "out-of-town" with an OutOfMemoryError! + for (long index = 0; index < Long.MAX_VALUE; index++) { + exampleRegion.put(index, String.valueOf(index)); + } + } catch (Exception ignore) { + System.err.printf("%1$s: %2$s%n", ignore.getClass().getName(), ignore.getMessage()); + } finally { + clientCache.close(); + + final int serverPid = serverState.getPid(); + + WaitCriterion waitCriteria = new WaitCriterion() { + @Override + public boolean done() { + return !ProcessUtils.isProcessAlive(serverPid); + } + + @Override + public String description() { + return "Wait for the GemFire Server JVM process that ran out-of-memory to exit."; + } + }; + + waitForCriterion(waitCriteria, TimeUnit.SECONDS.toMillis(30), TimeUnit.SECONDS.toMillis(10), + true); + + // Verify our GemFire Server JVM process is was terminated! + assertFalse(serverState.isVmWithProcessIdRunning()); + + serverState = serverLauncher.status(); + + assertNotNull(serverState); + assertEquals(Status.NOT_RESPONDING, serverState.getStatus()); + } + } + + private File writeAndGetCacheXmlFile(final File workingDirectory) throws IOException { + File cacheXml = new File(workingDirectory, "cache.xml"); + StringBuilder buffer = new StringBuilder("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); + + buffer.append(StringUtils.LINE_SEPARATOR); + buffer.append( + "<!DOCTYPE cache PUBLIC \"-//GemStone Systems, Inc.//GemFire Declarative Caching 7.0//EN\""); + buffer.append(StringUtils.LINE_SEPARATOR); + buffer.append(" \"http://www.gemstone.com/dtd/cache7_0.dtd\">"); + buffer.append(StringUtils.LINE_SEPARATOR); + buffer.append("<cache>"); + buffer.append(StringUtils.LINE_SEPARATOR); + buffer.append(" <region name=\"Example\" refid=\"REPLICATE\"/>"); + buffer.append(StringUtils.LINE_SEPARATOR); + buffer.append("</cache>"); + + BufferedWriter fileWriter = null; + + try { + fileWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(cacheXml, false), + Charset.forName("UTF-8").newEncoder())); + fileWriter.write(buffer.toString()); + fileWriter.flush(); + } finally { + IOUtils.close(fileWriter); + } + + return cacheXml; + } + + private ClientCache setupClientCache(final String durableClientId, final int serverPort) { + ClientCache clientCache = + new ClientCacheFactory().set(DURABLE_CLIENT_ID, durableClientId).create(); + + PoolFactory poolFactory = PoolManager.createFactory(); + + poolFactory.setMaxConnections(10); + poolFactory.setMinConnections(1); + poolFactory.setReadTimeout(5000); + poolFactory.addServer("localhost", serverPort); + + Pool pool = poolFactory.create("serverConnectionPool"); + + assertNotNull("The 'serverConnectionPool' was not properly configured and initialized!", pool); + + ClientRegionFactory<Long, String> regionFactory = + clientCache.createClientRegionFactory(ClientRegionShortcut.PROXY); + + regionFactory.setPoolName(pool.getName()); + regionFactory.setKeyConstraint(Long.class); + regionFactory.setValueConstraint(String.class); + + Region<Long, String> exampleProxy = regionFactory.create("Example"); + + assertNotNull("The 'Example' Client Region was not properly configured and initialized", + exampleProxy); + + return clientCache; + } + +} http://git-wip-us.apache.org/repos/asf/geode/blob/645a32d0/geode-assembly/src/test/java/org/apache/geode/management/internal/cli/commands/StartLocatorCommandTest.java ---------------------------------------------------------------------- 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 e9ca6dc..5a7c11c 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 @@ -56,9 +56,9 @@ public class StartLocatorCommandTest { public void testLocatorClasspathOrder() { String userClasspath = "/path/to/user/lib/app.jar:/path/to/user/classes"; String expectedClasspath = - locatorCommands.getGemFireJarPath().concat(File.pathSeparator).concat(userClasspath) + StartMemberUtils.getGemFireJarPath().concat(File.pathSeparator).concat(userClasspath) .concat(File.pathSeparator).concat(System.getProperty("java.class.path")) - .concat(File.pathSeparator).concat(StartMemberCommand.CORE_DEPENDENCIES_JAR_PATHNAME); + .concat(File.pathSeparator).concat(StartMemberUtils.CORE_DEPENDENCIES_JAR_PATHNAME); String actualClasspath = locatorCommands.getLocatorClasspath(true, userClasspath); assertEquals(expectedClasspath, actualClasspath); } http://git-wip-us.apache.org/repos/asf/geode/blob/645a32d0/geode-assembly/src/test/java/org/apache/geode/management/internal/cli/commands/StartServerCommandTest.java ---------------------------------------------------------------------- diff --git a/geode-assembly/src/test/java/org/apache/geode/management/internal/cli/commands/StartServerCommandTest.java b/geode-assembly/src/test/java/org/apache/geode/management/internal/cli/commands/StartServerCommandTest.java index a5012f3..e704248 100644 --- a/geode-assembly/src/test/java/org/apache/geode/management/internal/cli/commands/StartServerCommandTest.java +++ b/geode-assembly/src/test/java/org/apache/geode/management/internal/cli/commands/StartServerCommandTest.java @@ -54,8 +54,8 @@ public class StartServerCommandTest { public void testServerClasspathOrder() { String userClasspath = "/path/to/user/lib/app.jar:/path/to/user/classes"; String expectedClasspath = - serverCommands.getGemFireJarPath().concat(File.pathSeparator).concat(userClasspath) - .concat(File.pathSeparator).concat(StartMemberCommand.CORE_DEPENDENCIES_JAR_PATHNAME); + StartMemberUtils.getGemFireJarPath().concat(File.pathSeparator).concat(userClasspath) + .concat(File.pathSeparator).concat(StartMemberUtils.CORE_DEPENDENCIES_JAR_PATHNAME); String actualClasspath = serverCommands.getServerClasspath(false, userClasspath); assertEquals(expectedClasspath, actualClasspath); } http://git-wip-us.apache.org/repos/asf/geode/blob/645a32d0/geode-assembly/src/test/java/org/apache/geode/management/internal/cli/shell/GfshExitCodeStatusClusterConfigServiceCommandTest.java ---------------------------------------------------------------------- diff --git a/geode-assembly/src/test/java/org/apache/geode/management/internal/cli/shell/GfshExitCodeStatusClusterConfigServiceCommandTest.java b/geode-assembly/src/test/java/org/apache/geode/management/internal/cli/shell/GfshExitCodeStatusClusterConfigServiceCommandTest.java deleted file mode 100755 index 15b4f8b..0000000 --- a/geode-assembly/src/test/java/org/apache/geode/management/internal/cli/shell/GfshExitCodeStatusClusterConfigServiceCommandTest.java +++ /dev/null @@ -1,391 +0,0 @@ -/* - * 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.shell; - -import static java.util.concurrent.TimeUnit.MINUTES; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import junitparams.JUnitParamsRunner; -import junitparams.Parameters; -import org.junit.Assume; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Rule; -import org.junit.Test; -import org.junit.experimental.categories.Category; -import org.junit.runner.RunWith; - -import org.apache.geode.internal.AvailablePort; -import org.apache.geode.internal.ExitCode; -import org.apache.geode.internal.process.PidFile; -import org.apache.geode.management.internal.cli.util.CommandStringBuilder; -import org.apache.geode.management.internal.cli.util.ThreePhraseGenerator; -import org.apache.geode.test.dunit.rules.gfsh.GfshExecution; -import org.apache.geode.test.dunit.rules.gfsh.GfshRule; -import org.apache.geode.test.dunit.rules.gfsh.GfshScript; -import org.apache.geode.test.junit.categories.AcceptanceTest; - -// Originally created in response to GEODE-2971 - -@Category(AcceptanceTest.class) -@RunWith(JUnitParamsRunner.class) -public class GfshExitCodeStatusClusterConfigServiceCommandTest { - private static File toolsJar; - private static final ThreePhraseGenerator nameGenerator = new ThreePhraseGenerator(); - private static final String memberControllerName = "member-controller"; - - @Rule - public GfshRule gfsh = new GfshRule(); - private String locatorName; - private String serverName; - - private int locatorPort; - - // Some test configuration shorthands - private static final TestConfiguration LOCATOR_ONLINE_BUT_NOT_CONNECTED = - new TestConfiguration(true, false, false); - private static final TestConfiguration LOCATOR_ONLINE_AND_CONNECTED = - new TestConfiguration(true, false, true); - private static final TestConfiguration BOTH_ONLINE_BUT_NOT_CONNECTED = - new TestConfiguration(true, true, false); - private static final TestConfiguration BOTH_ONLINE_AND_CONNECTED = - new TestConfiguration(true, true, true); - - @BeforeClass - public static void classSetup() { - File javaHome = new File(System.getProperty("java.home")); - String toolsPath = - javaHome.getName().equalsIgnoreCase("jre") ? "../lib/tools.jar" : "lib/tools.jar"; - toolsJar = new File(javaHome, toolsPath); - } - - @Before - public void setup() { - locatorName = "locator-" + nameGenerator.generate('-'); - serverName = "server-" + nameGenerator.generate('-'); - locatorPort = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET); - } - - @Test - @Parameters( - value = {"status locator --port=-10", "status locator --pid=-1", "status server --pid=-1"}) - public void statusCommandWithInvalidOptionValueShouldFail(String cmd) { - GfshScript.of(cmd).withName("test-frame").awaitAtMost(1, MINUTES) - .expectExitCode(ExitCode.FATAL.getValue()).execute(gfsh); - } - - - @Test - @Parameters(value = {"status locator --host=somehostname", "status locator --port=10334", - "status locator --dir=.", "status server --dir=.", "status locator --name=some-locator-name", - "status server --name=some-server-name", "status locator --pid=100", - "status server --pid=100"}) - public void statusCommandWithValidOptionValueShouldFailWithNoMembers(String cmd) { - GfshScript.of(cmd).withName("test-frame").awaitAtMost(1, MINUTES) - .expectExitCode(ExitCode.FATAL.getValue()).execute(gfsh); - } - - - @Test - public void onlineStatusCommandShouldFailWhenNotConnected_locator_name() { - TestConfiguration config = LOCATOR_ONLINE_BUT_NOT_CONNECTED; - config.startNecessaryMembers(startLocatorCommand(), startServerCommand(), gfsh); - - String statusCommand = statusLocatorCommandByName(); - executeScriptWithExpectedExitCode(statusCommand, config, ExitCode.FATAL); - } - - - @Test - public void onlineStatusCommandShouldFailWhenNotConnected_server_name() { - TestConfiguration config = BOTH_ONLINE_BUT_NOT_CONNECTED; - config.startNecessaryMembers(startLocatorCommand(), startServerCommand(), gfsh); - - String statusCommand = statusServerCommandByName(); - executeScriptWithExpectedExitCode(statusCommand, config, ExitCode.FATAL); - } - - @Test - public void offlineStatusCommandShouldSucceedWhenNotConnected_locator_port() { - // --host defaults to localhost, so `status locator --port=xxx` should still succeed. - TestConfiguration config = LOCATOR_ONLINE_BUT_NOT_CONNECTED; - config.startNecessaryMembers(startLocatorCommand(), startServerCommand(), gfsh); - - String statusCommand = statusLocatorCommandByPort(); - executeScriptWithExpectedExitCode(statusCommand, config, ExitCode.NORMAL); - } - - @Test - public void offlineStatusCommandShouldSucceedWhenNotConnected_locator_host_and_port() { - // Since this is still local to the testing VM's machine, `status locator --host=localhost - // --port=xxx` should succeed - TestConfiguration config = LOCATOR_ONLINE_BUT_NOT_CONNECTED; - config.startNecessaryMembers(startLocatorCommand(), startServerCommand(), gfsh); - - String statusCommand = statusLocatorCommandByHostAndPort(); - executeScriptWithExpectedExitCode(statusCommand, config, ExitCode.NORMAL); - } - - - - @Test - public void onlineStatusCommandShouldSucceedWhenConnected_locator_name() { - TestConfiguration config = LOCATOR_ONLINE_AND_CONNECTED; - config.startNecessaryMembers(startLocatorCommand(), startServerCommand(), gfsh); - - String statusCommand = statusLocatorCommandByName(); - executeScriptWithExpectedExitCode(statusCommand, config, ExitCode.NORMAL); - } - - - @Test - public void onlineStatusCommandShouldSucceedWhenConnected_server_name() { - TestConfiguration config = BOTH_ONLINE_AND_CONNECTED; - config.startNecessaryMembers(startLocatorCommand(), startServerCommand(), gfsh); - - String statusCommand = statusServerCommandByName(); - executeScriptWithExpectedExitCode(statusCommand, config, ExitCode.NORMAL); - } - - @Test - public void onlineStatusCommandShouldSucceedWhenConnected_locator_port() { - TestConfiguration config = LOCATOR_ONLINE_AND_CONNECTED; - config.startNecessaryMembers(startLocatorCommand(), startServerCommand(), gfsh); - - String statusCommand = statusLocatorCommandByPort(); - executeScriptWithExpectedExitCode(statusCommand, config, ExitCode.NORMAL); - } - - @Test - public void onlineStatusCommandShouldSucceedWhenConnected_locator_host_and_port() { - TestConfiguration config = LOCATOR_ONLINE_AND_CONNECTED; - config.startNecessaryMembers(startLocatorCommand(), startServerCommand(), gfsh); - - String statusCommand = statusLocatorCommandByHostAndPort(); - executeScriptWithExpectedExitCode(statusCommand, config, ExitCode.NORMAL); - } - - - - @Test - public void offlineStatusCommandShouldSucceedWhenConnected_locator_dir() { - TestConfiguration config = LOCATOR_ONLINE_AND_CONNECTED; - config.startNecessaryMembers(startLocatorCommand(), startServerCommand(), gfsh); - - String statusCommand = statusLocatorCommandByDir(); - executeScriptWithExpectedExitCode(statusCommand, config, ExitCode.NORMAL); - } - - @Test - public void offlineStatusCommandShouldSucceedWhenConnected_server_dir() { - TestConfiguration config = BOTH_ONLINE_AND_CONNECTED; - config.startNecessaryMembers(startLocatorCommand(), startServerCommand(), gfsh); - - String statusCommand = statusServerCommandByDir(); - executeScriptWithExpectedExitCode(statusCommand, config, ExitCode.NORMAL); - } - - @Test - public void offlineStatusCommandShouldSucceedWhenConnected_locator_pid() throws IOException { - Assume.assumeTrue(toolsJar.exists()); - TestConfiguration config = LOCATOR_ONLINE_AND_CONNECTED; - config.startNecessaryMembers(startLocatorCommand(), startServerCommand(), gfsh); - - String statusCommand = statusLocatorCommandByPid(); - executeScriptWithExpectedExitCode(statusCommand, config, ExitCode.NORMAL); - } - - @Test - public void offlineStatusCommandShouldSucceedWhenConnected_server_pid() throws IOException { - Assume.assumeTrue(toolsJar.exists()); - TestConfiguration config = BOTH_ONLINE_AND_CONNECTED; - config.startNecessaryMembers(startLocatorCommand(), startServerCommand(), gfsh); - - String statusCommand = statusServerCommandByPid(); - executeScriptWithExpectedExitCode(statusCommand, config, ExitCode.NORMAL); - } - - - - @Test - public void offlineStatusCommandShouldSucceedEvenWhenNotConnected_locator_dir() { - TestConfiguration config = LOCATOR_ONLINE_BUT_NOT_CONNECTED; - config.startNecessaryMembers(startLocatorCommand(), startServerCommand(), gfsh); - - String statusCommand = statusLocatorCommandByDir(); - executeScriptWithExpectedExitCode(statusCommand, config, ExitCode.NORMAL); - } - - @Test - public void offlineStatusCommandShouldSucceedEvenWhenNotConnected_server_dir() { - TestConfiguration config = BOTH_ONLINE_BUT_NOT_CONNECTED; - config.startNecessaryMembers(startLocatorCommand(), startServerCommand(), gfsh); - - String statusCommand = statusServerCommandByDir(); - executeScriptWithExpectedExitCode(statusCommand, config, ExitCode.NORMAL); - } - - @Test - public void offlineStatusCommandShouldSucceedEvenWhenNotConnected_locator_pid() - throws IOException { - Assume.assumeTrue(toolsJar.exists()); - TestConfiguration config = LOCATOR_ONLINE_BUT_NOT_CONNECTED; - config.startNecessaryMembers(startLocatorCommand(), startServerCommand(), gfsh); - - String statusCommand = statusLocatorCommandByPid(); - executeScriptWithExpectedExitCode(statusCommand, config, ExitCode.NORMAL); - } - - @Test - public void offlineStatusCommandShouldSucceedEvenWhenNotConnected_server_pid() - throws IOException { - Assume.assumeTrue(toolsJar.exists()); - TestConfiguration config = BOTH_ONLINE_BUT_NOT_CONNECTED; - config.startNecessaryMembers(startLocatorCommand(), startServerCommand(), gfsh); - - String statusCommand = statusServerCommandByPid(); - executeScriptWithExpectedExitCode(statusCommand, config, ExitCode.NORMAL); - } - - - - private String startLocatorCommand() { - return new CommandStringBuilder("start locator").addOption("name", locatorName) - .addOption("port", String.valueOf(locatorPort)).toString(); - } - - - private String startServerCommand() { - return new CommandStringBuilder("start server").addOption("name", serverName).toString(); - } - - - private String connectCommand() { - return new CommandStringBuilder("connect") - .addOption("locator", String.format("localhost[%d]", locatorPort)).toString(); - } - - - private String statusServerCommandByName() { - return new CommandStringBuilder("status server").addOption("name", serverName).toString(); - } - - private String statusServerCommandByDir() { - String serverDir = gfsh.getTemporaryFolder().getRoot().toPath().resolve(memberControllerName) - .resolve(serverName).toAbsolutePath().toString(); - return new CommandStringBuilder("status server").addOption("dir", serverDir).toString(); - } - - - private String statusServerCommandByPid() throws IOException { - int serverPid = snoopMemberFile(serverName, "server.pid"); - return new CommandStringBuilder("status server").addOption("pid", String.valueOf(serverPid)) - .toString(); - } - - private String statusLocatorCommandByName() { - return new CommandStringBuilder("status locator").addOption("name", locatorName).toString(); - } - - private String statusLocatorCommandByPort() { - return new CommandStringBuilder("status locator").addOption("port", String.valueOf(locatorPort)) - .toString(); - } - - private String statusLocatorCommandByHostAndPort() { - return new CommandStringBuilder("status locator").addOption("host", "localhost") - .addOption("port", String.valueOf(locatorPort)).toString(); - } - - private String statusLocatorCommandByDir() { - String locatorDir = gfsh.getTemporaryFolder().getRoot().toPath().resolve(memberControllerName) - .resolve(locatorName).toAbsolutePath().toString(); - return new CommandStringBuilder("status locator").addOption("dir", locatorDir).toString(); - } - - - private String statusLocatorCommandByPid() throws IOException { - int locatorPid = snoopMemberFile(locatorName, "locator.pid"); - return new CommandStringBuilder("status locator").addOption("pid", String.valueOf(locatorPid)) - .toString(); - } - - private int snoopMemberFile(String memberName, String pidFileEndsWith) throws IOException { - File directory = gfsh.getTemporaryFolder().getRoot().toPath().resolve(memberControllerName) - .resolve(memberName).toFile(); - File[] files = directory.listFiles(); - if (files == null) { - throw new RuntimeException(String.format( - "Expected directory ('%s') for member '%s' either does not denote a directory, or an I/O error occurred.", - directory.toString(), memberName)); - } - File pidFile = Arrays.stream(files).filter(file -> file.getName().endsWith(pidFileEndsWith)) - .findFirst().orElseThrow(() -> new RuntimeException(String - .format("Expected member '%s' to have pid file but could not find it.", memberName))); - return new PidFile(pidFile).readPid(); - } - - private void executeScriptWithExpectedExitCode(String statusCommand, TestConfiguration config, - ExitCode expectedExit) { - - String[] gfshScriptCommands = config.connectedToLocator - ? new String[] {connectCommand(), statusCommand} : new String[] {statusCommand}; - GfshScript gfshScript = GfshScript.of(gfshScriptCommands).withName("test-frame") - .awaitAtMost(1, MINUTES).expectExitCode(expectedExit.getValue()); - if (toolsJar.exists()) { - gfshScript.addToClasspath(toolsJar.getAbsolutePath()); - } - gfshScript.execute(gfsh); - } - - - private static class TestConfiguration { - TestConfiguration(boolean locatorStarted, boolean serverStarted, boolean connectedToLocator) { - this.locatorStarted = locatorStarted; - this.serverStarted = serverStarted; - this.connectedToLocator = connectedToLocator; - } - - private boolean locatorStarted; - private boolean serverStarted; - private boolean connectedToLocator; - - void startNecessaryMembers(String startLocator, String startServer, GfshRule gfsh) { - if (!locatorStarted && !serverStarted) { - return; - } - - List<String> commands = new ArrayList<>(); - if (locatorStarted) { - commands.add(startLocator); - } - if (serverStarted) { - commands.add(startServer); - } - - GfshExecution exec = GfshScript.of(commands.toArray(new String[] {})) - .withName(memberControllerName).awaitAtMost(1, MINUTES).execute(gfsh); - if (exec.getProcess().exitValue() != 0) { - throw new RuntimeException( - "The locator and server launcher exited with non-zero exit code. This failure is beyond the scope of this test."); - } - } - } -}