GEODE-563: Moving gfsh tests from closed
Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/eddef322 Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/eddef322 Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/eddef322 Branch: refs/heads/feature/GEODE-291 Commit: eddef322defedea8396697e65c989b85c3d9c433 Parents: 1e93c6f Author: Jens Deppe <[email protected]> Authored: Thu Dec 3 10:21:59 2015 -0800 Committer: Jens Deppe <[email protected]> Committed: Tue Dec 8 09:23:28 2015 -0800 ---------------------------------------------------------------------- gemfire-assembly/build.gradle | 13 + .../LauncherLifecycleCommandsDUnitTest.java | 1005 +++++++++ .../LauncherLifecycleCommandsJUnitTest.java | 625 ++++++ .../SharedConfigurationEndToEndDUnitTest.java | 434 ++++ .../management/internal/cli/HeadlessGfsh.java | 376 ++++ .../internal/cli/HeadlessGfshJUnitTest.java | 87 + .../management/internal/cli/ResultHandler.java | 23 + .../internal/cli/TableBuilderJUnitTest.java | 183 ++ .../cli/commands/CliCommandTestBase.java | 560 +++++ .../cli/commands/ConfigCommandsDUnitTest.java | 497 +++++ ...eateAlterDestroyRegionCommandsDUnitTest.java | 1148 ++++++++++ .../cli/commands/DeployCommandsDUnitTest.java | 480 ++++ .../commands/DiskStoreCommandsDUnitTest.java | 1154 ++++++++++ .../cli/commands/FunctionCommandsDUnitTest.java | 593 +++++ .../commands/GemfireDataCommandsDUnitTest.java | 2087 ++++++++++++++++++ ...WithCacheLoaderDuringCacheMissDUnitTest.java | 371 ++++ .../cli/commands/IndexCommandsDUnitTest.java | 817 +++++++ ...stAndDescribeDiskStoreCommandsDUnitTest.java | 197 ++ .../ListAndDescribeRegionDUnitTest.java | 320 +++ .../cli/commands/ListIndexCommandDUnitTest.java | 672 ++++++ .../cli/commands/MemberCommandsDUnitTest.java | 286 +++ .../MiscellaneousCommandsDUnitTest.java | 492 +++++ ...laneousCommandsExportLogsPart1DUnitTest.java | 139 ++ ...laneousCommandsExportLogsPart2DUnitTest.java | 148 ++ ...laneousCommandsExportLogsPart3DUnitTest.java | 150 ++ ...laneousCommandsExportLogsPart4DUnitTest.java | 141 ++ .../cli/commands/QueueCommandsDUnitTest.java | 385 ++++ .../SharedConfigurationCommandsDUnitTest.java | 338 +++ .../cli/commands/ShellCommandsDUnitTest.java | 365 +++ .../cli/commands/ShowDeadlockDUnitTest.java | 271 +++ .../cli/commands/ShowMetricsDUnitTest.java | 347 +++ .../cli/commands/ShowStackTraceDUnitTest.java | 149 ++ .../cli/commands/UserCommandsDUnitTest.java | 164 ++ 33 files changed, 15017 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/eddef322/gemfire-assembly/build.gradle ---------------------------------------------------------------------- diff --git a/gemfire-assembly/build.gradle b/gemfire-assembly/build.gradle index 8de6d4e..514b4a1 100755 --- a/gemfire-assembly/build.gradle +++ b/gemfire-assembly/build.gradle @@ -31,6 +31,8 @@ dependencies { testCompile project(path: ':gemfire-junit', configuration: 'testOutput') testCompile project(path: ':gemfire-core', configuration: 'testOutput') + + testRuntime files("${System.getProperty('java.home')}/../lib/tools.jar") } sourceSets { @@ -287,6 +289,17 @@ afterEvaluate { } } +// Create a configuration closure to configure test targets with the install directory +def dependOnInstalledProduct = { + dependsOn installDist + def install = file("$buildDir/install/${distributions.main.baseName}") + environment ('GEMFIRE', install) +} + +// Add the configuration closure to the test targets so they depend on the install directory +test dependOnInstalledProduct +distributedTest dependOnInstalledProduct + artifacts { archives depsJar, gfshDepsJar } http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/eddef322/gemfire-assembly/src/test/java/com/gemstone/gemfire/management/internal/cli/commands/LauncherLifecycleCommandsDUnitTest.java ---------------------------------------------------------------------- diff --git a/gemfire-assembly/src/test/java/com/gemstone/gemfire/management/internal/cli/commands/LauncherLifecycleCommandsDUnitTest.java b/gemfire-assembly/src/test/java/com/gemstone/gemfire/management/internal/cli/commands/LauncherLifecycleCommandsDUnitTest.java new file mode 100644 index 0000000..afb2770 --- /dev/null +++ b/gemfire-assembly/src/test/java/com/gemstone/gemfire/management/internal/cli/commands/LauncherLifecycleCommandsDUnitTest.java @@ -0,0 +1,1005 @@ +/* + * 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 com.gemstone.gemfire.management.internal.cli.commands; + +import com.gemstone.gemfire.cache.Region; +import com.gemstone.gemfire.cache.client.ClientCache; +import com.gemstone.gemfire.cache.client.ClientCacheFactory; +import com.gemstone.gemfire.cache.client.ClientRegionFactory; +import com.gemstone.gemfire.cache.client.ClientRegionShortcut; +import com.gemstone.gemfire.cache.client.Pool; +import com.gemstone.gemfire.cache.client.PoolFactory; +import com.gemstone.gemfire.cache.client.PoolManager; +import com.gemstone.gemfire.distributed.AbstractLauncher.ServiceState; +import com.gemstone.gemfire.distributed.AbstractLauncher.Status; +import com.gemstone.gemfire.distributed.LocatorLauncher; +import com.gemstone.gemfire.distributed.LocatorLauncher.Builder; +import com.gemstone.gemfire.distributed.LocatorLauncher.Command; +import com.gemstone.gemfire.distributed.LocatorLauncher.LocatorState; +import com.gemstone.gemfire.distributed.ServerLauncher; +import com.gemstone.gemfire.distributed.ServerLauncher.ServerState; +import com.gemstone.gemfire.distributed.internal.DistributionConfig; +import com.gemstone.gemfire.internal.AvailablePortHelper; +import com.gemstone.gemfire.internal.lang.ObjectUtils; +import com.gemstone.gemfire.internal.lang.StringUtils; +import com.gemstone.gemfire.internal.lang.SystemUtils; +import com.gemstone.gemfire.internal.process.ProcessType; +import com.gemstone.gemfire.internal.util.IOUtils; +import com.gemstone.gemfire.management.cli.Result; +import com.gemstone.gemfire.management.internal.cli.i18n.CliStrings; +import com.gemstone.gemfire.management.internal.cli.result.CommandResult; +import com.gemstone.gemfire.management.internal.cli.util.CommandStringBuilder; +import org.junit.FixMethodOrder; +import org.junit.runners.MethodSorters; + +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 java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileFilter; +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; + +/** + * The LauncherLifecycleCommandsDUnitTest class is a test suite of integration tests testing the contract and + * functionality of the GemFire launcher lifecycle commands inside Gfsh. + * + * @author John Blum + * @see javax.management.MBeanServerConnection + * @see javax.management.remote.JMXConnector + * @see com.gemstone.gemfire.distributed.AbstractLauncher + * @see com.gemstone.gemfire.distributed.LocatorLauncher + * @see com.gemstone.gemfire.distributed.ServerLauncher + * @see com.gemstone.gemfire.internal.AvailablePortHelper + * @see com.gemstone.gemfire.management.internal.cli.shell.Gfsh + * @see com.gemstone.gemfire.management.internal.cli.commands.CliCommandTestBase + * @see com.gemstone.gemfire.management.internal.cli.commands.LauncherLifecycleCommands + * @see com.gemstone.gemfire.management.internal.cli.util.CommandStringBuilder + * @since 7.0 + */ +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class LauncherLifecycleCommandsDUnitTest extends CliCommandTestBase { + + protected static final long COMMAND_EXECUTION_TIMEOUT = TimeUnit.MINUTES.toSeconds(2); + + protected static final DateFormat TIMESTAMP = new SimpleDateFormat("yyyyMMddHHmmssSSS"); + + private final Queue<Integer> processIds = new ConcurrentLinkedDeque<>(); + + public LauncherLifecycleCommandsDUnitTest(final String testName) { + super(testName); + } + + 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 void setUp() throws Exception { + super.setUp(); + } + + @Override + protected void tearDownAfter() throws Exception { + super.tearDownAfter(); + + LauncherLifecycleCommands launcherLifecycleCommands = new LauncherLifecycleCommands(); + Integer pid; + + while ((pid = processIds.poll()) != null) { + if (launcherLifecycleCommands.isVmWithProcessIdRunning(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(new FileFilter() { + @Override + public boolean accept(final File pathname) { + return (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 File workingDirectory) { + return stopServer(IOUtils.tryGetCanonicalPathElseGetAbsolutePath(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() { + private LauncherLifecycleCommands launcherLifecycleCommands = new LauncherLifecycleCommands(); + + @Override + public boolean done() { + return !launcherLifecycleCommands.isVmWithProcessIdRunning(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); + } + } + + public void test000StartLocatorCapturesOutputOnError() throws IOException { + final int locatorPort = AvailablePortHelper.getRandomAvailableTCPPort(); + + String pathname = (getClass().getSimpleName() + "_" + testName); + File workingDirectory = new File(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, 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, "-Dgemfire.http-service-port=0"); + command.addOption(CliStrings.START_LOCATOR__J, + "-Dgemfire.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: com.gemstone.gemfire.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; + } + + public void test001StartLocatorFailsFastOnMissingGemFirePropertiesFile() { + String gemfirePropertiesPathname = "/path/to/missing/gemfire.properties"; + + CommandStringBuilder command = new CommandStringBuilder(CliStrings.START_LOCATOR); + + command.addOption(CliStrings.START_LOCATOR__MEMBER_NAME, getClass().getSimpleName().concat("_").concat(testName)); + command.addOption(CliStrings.START_LOCATOR__PORT, "0"); + command.addOption(CliStrings.START_LOCATOR__PROPERTIES, gemfirePropertiesPathname); + command.addOption(CliStrings.START_LOCATOR__J, "-Dgemfire.http-service-port=0"); + command.addOption(CliStrings.START_LOCATOR__J, "-Dgemfire.jmx-manager=false"); + command.addOption(CliStrings.START_LOCATOR__J, "-Dgemfire.jmx-manager-port=0"); + command.addOption(CliStrings.START_LOCATOR__J, "-Dgemfire.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.GEMFIRE_0_PROPERTIES_1_NOT_FOUND_MESSAGE, StringUtils.EMPTY_STRING, + gemfirePropertiesPathname))); + } + + public void test002StartLocatorFailsFastOnMissingGemFireSecurityPropertiesFile() { + String gemfireSecurityPropertiesPathname = "/path/to/missing/gemfire-security.properties"; + + CommandStringBuilder command = new CommandStringBuilder(CliStrings.START_LOCATOR); + + command.addOption(CliStrings.START_LOCATOR__MEMBER_NAME, getClass().getSimpleName().concat("_").concat(testName)); + command.addOption(CliStrings.START_LOCATOR__PORT, "0"); + command.addOption(CliStrings.START_LOCATOR__SECURITY_PROPERTIES, gemfireSecurityPropertiesPathname); + command.addOption(CliStrings.START_LOCATOR__J, "-Dgemfire.http-service-port=0"); + command.addOption(CliStrings.START_LOCATOR__J, "-Dgemfire.jmx-manager=false"); + command.addOption(CliStrings.START_LOCATOR__J, "-Dgemfire.jmx-manager-port=0"); + command.addOption(CliStrings.START_LOCATOR__J, "-Dgemfire.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.GEMFIRE_0_PROPERTIES_1_NOT_FOUND_MESSAGE, "Security ", + gemfireSecurityPropertiesPathname))); + } + + public void test003StartServerFailsFastOnMissingCacheXmlFile() { + String cacheXmlPathname = "/path/to/missing/cache.xml"; + + CommandStringBuilder command = new CommandStringBuilder(CliStrings.START_SERVER); + + command.addOption(CliStrings.START_SERVER__NAME, getClass().getSimpleName().concat("_").concat(testName)); + 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))); + } + + public void test004StartServerFailsFastOnMissingGemFirePropertiesFile() { + String gemfirePropertiesFile = "/path/to/missing/gemfire.properties"; + + CommandStringBuilder command = new CommandStringBuilder(CliStrings.START_SERVER); + + command.addOption(CliStrings.START_SERVER__NAME, getClass().getSimpleName().concat("_").concat(testName)); + 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.GEMFIRE_0_PROPERTIES_1_NOT_FOUND_MESSAGE, StringUtils.EMPTY_STRING, + gemfirePropertiesFile))); + } + + public void test005StartServerFailsFastOnMissingGemFireSecurityPropertiesFile() { + String gemfireSecuritiesPropertiesFile = "/path/to/missing/gemfire-securities.properties"; + + CommandStringBuilder command = new CommandStringBuilder(CliStrings.START_SERVER); + + command.addOption(CliStrings.START_SERVER__NAME, getClass().getSimpleName().concat("_").concat(testName)); + 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.GEMFIRE_0_PROPERTIES_1_NOT_FOUND_MESSAGE, "Security ", + gemfireSecuritiesPropertiesFile))); + } + + public void test006StartLocatorInRelativeDirectory() { + final int locatorPort = AvailablePortHelper.getRandomAvailableTCPPort(); + + String pathname = (getClass().getSimpleName() + "_" + testName); + 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, "-Dgemfire.http-service-port=0"); + command.addOption(CliStrings.START_LOCATOR__J, + "-Dgemfire.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); + } + } + + public void test007StatusLocatorUsingMemberNameIDWhenGfshIsNotConnected() { + CommandResult result = executeCommand(CliStrings.STATUS_LOCATOR + " --name=" + testName); + + assertNotNull(result); + assertEquals(Result.Status.ERROR, result.getStatus()); + assertEquals(CliStrings.format(CliStrings.STATUS_SERVICE__GFSH_NOT_CONNECTED_ERROR_MESSAGE, "Locator"), + StringUtils.trim(toString(result))); + } + + public void test008StatusLocatorUsingMemberName() { + final int[] ports = AvailablePortHelper.getRandomAvailableTCPPorts(2); + + final int jmxManagerPort = ports[0]; + final int locatorPort = ports[1]; + + String pathname = (getClass().getSimpleName() + "_" + testName); + 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__FORCE, Boolean.TRUE.toString()); + command.addOption(CliStrings.START_LOCATOR__J, "-Dgemfire.http-service-port=0"); + command.addOption(CliStrings.START_LOCATOR__J, "-Dgemfire.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); + } + } + + 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() + "_" + testName); + 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__FORCE, Boolean.TRUE.toString()); + command.addOption(CliStrings.START_LOCATOR__J, "-Dgemfire.http-service-port=0"); + command.addOption(CliStrings.START_LOCATOR__J, "-Dgemfire.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); + } + } + + public void test010StopLocatorUsingMemberNameIDWhenGfshIsNotConnected() { + CommandResult result = executeCommand(CliStrings.STOP_LOCATOR + " --name=" + testName); + + assertNotNull(result); + assertEquals(Result.Status.ERROR, result.getStatus()); + assertEquals(CliStrings.format(CliStrings.STOP_SERVICE__GFSH_NOT_CONNECTED_ERROR_MESSAGE, "Locator"), + StringUtils.trim(toString(result))); + } + + public void test011StopLocatorUsingMemberName() { + final int[] ports = AvailablePortHelper.getRandomAvailableTCPPorts(2); + + final int jmxManagerPort = ports[0]; + final int locatorPort = ports[1]; + + String pathname = (getClass().getSimpleName() + "_" + testName); + File workingDirectory = new File(pathname); + + 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, 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__FORCE, Boolean.TRUE.toString()); + command.addOption(CliStrings.START_LOCATOR__J, "-Dgemfire.http-service-port=0"); + command.addOption(CliStrings.START_LOCATOR__J, "-Dgemfire.jmx-manager-port=" + jmxManagerPort); + + CommandResult result = executeCommand(command.toString()); + + assertNotNull(result); + assertEquals(Result.Status.OK, result.getStatus()); + + final LocatorLauncher locatorLauncher = new LocatorLauncher.Builder().setCommand( + LocatorLauncher.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... + //assertEquals(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()); + } + + // @see Trac Bug # 46760 + 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() + "_" + testName); + File workingDirectory = new File(pathname); + + 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, 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__FORCE, Boolean.TRUE.toString()); + command.addOption(CliStrings.START_LOCATOR__J, "-Dgemfire.http-service-port=0"); + command.addOption(CliStrings.START_LOCATOR__J, "-Dgemfire.jmx-manager-port=" + jmxManagerPort); + + CommandResult result = executeCommand(command.toString()); + + assertNotNull(result); + assertEquals(Result.Status.OK, result.getStatus()); + + final LocatorLauncher locatorLauncher = new LocatorLauncher.Builder().setCommand( + LocatorLauncher.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... + //assertEquals(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()); + } + + public void test013StartServerWithSpring() { + String pathname = (getClass().getSimpleName() + "_" + testName); + File workingDirectory = new File(pathname); + + assertTrue(workingDirectory.isDirectory() || workingDirectory.mkdir()); + + CommandStringBuilder command = new CommandStringBuilder(CliStrings.START_SERVER); + + command.addOption(CliStrings.START_SERVER__NAME, getClass().getSimpleName().concat("_").concat(testName)); + command.addOption(CliStrings.START_SERVER__USE_CLUSTER_CONFIGURATION, Boolean.FALSE.toString()); + command.addOption(CliStrings.START_SERVER__LOG_LEVEL, "config"); + command.addOption(CliStrings.START_SERVER__INCLUDE_SYSTEM_CLASSPATH); + command.addOption(CliStrings.START_SERVER__DISABLE_DEFAULT_SERVER); + command.addOption(CliStrings.START_SERVER__DIR, pathname); + command.addOption(CliStrings.START_SERVER__SPRING_XML_LOCATION, "spring/spring-gemfire-context.xml"); + + CommandResult result = executeCommand(command.toString()); + + assertNotNull(result); + assertEquals(Result.Status.OK, result.getStatus()); + + final ServerLauncher springGemFireServer = new ServerLauncher.Builder().setCommand( + ServerLauncher.Command.STATUS).setWorkingDirectory( + IOUtils.tryGetCanonicalPathElseGetAbsolutePath(workingDirectory)).build(); + + assertNotNull(springGemFireServer); + + ServerState serverState = springGemFireServer.status(); + + assertNotNull(serverState); + assertEquals(Status.ONLINE, serverState.getStatus()); + + // Now that the GemFire Server bootstrapped with Spring started up OK, stop it! + stopServer(springGemFireServer.getWorkingDirectory()); + + WaitCriterion waitCriteria = new WaitCriterion() { + @Override + public boolean done() { + ServerState serverState = springGemFireServer.status(); + return (serverState != null && Status.NOT_RESPONDING.equals(serverState.getStatus())); + } + + @Override + public String description() { + return "wait for the Locator to stop; the Locator will no longer respond after it stops"; + } + }; + + waitForCriterion(waitCriteria, TimeUnit.SECONDS.toMillis(15), TimeUnit.SECONDS.toMillis(5), true); + + serverState = springGemFireServer.status(); + + assertNotNull(serverState); + assertEquals(Status.NOT_RESPONDING, serverState.getStatus()); + } + + 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(testName); + File workingDirectory = new File(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, pathname); + 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, + "-Dgemfire." + DistributionConfig.START_LOCATOR_NAME + "=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(new LauncherLifecycleCommands().isVmWithProcessIdRunning(serverState.getPid())); + + 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() { + private LauncherLifecycleCommands launcherLifecycleCommands = new LauncherLifecycleCommands(); + + @Override + public boolean done() { + return !launcherLifecycleCommands.isVmWithProcessIdRunning(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(new LauncherLifecycleCommands().isVmWithProcessIdRunning(serverState.getPid())); + + 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/incubator-geode/blob/eddef322/gemfire-assembly/src/test/java/com/gemstone/gemfire/management/internal/cli/commands/LauncherLifecycleCommandsJUnitTest.java ---------------------------------------------------------------------- diff --git a/gemfire-assembly/src/test/java/com/gemstone/gemfire/management/internal/cli/commands/LauncherLifecycleCommandsJUnitTest.java b/gemfire-assembly/src/test/java/com/gemstone/gemfire/management/internal/cli/commands/LauncherLifecycleCommandsJUnitTest.java new file mode 100755 index 0000000..d7e7970 --- /dev/null +++ b/gemfire-assembly/src/test/java/com/gemstone/gemfire/management/internal/cli/commands/LauncherLifecycleCommandsJUnitTest.java @@ -0,0 +1,625 @@ +/* + * 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 com.gemstone.gemfire.management.internal.cli.commands; + +import com.gemstone.gemfire.GemFireException; +import com.gemstone.gemfire.cache.server.CacheServer; +import com.gemstone.gemfire.distributed.ServerLauncher; +import com.gemstone.gemfire.distributed.internal.DistributionConfig; +import com.gemstone.gemfire.internal.DistributionLocator; +import com.gemstone.gemfire.internal.lang.StringUtils; +import com.gemstone.gemfire.internal.lang.SystemUtils; +import com.gemstone.gemfire.internal.util.IOUtils; +import com.gemstone.gemfire.management.internal.cli.i18n.CliStrings; +import com.gemstone.gemfire.test.junit.categories.UnitTest; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Properties; +import java.util.Set; +import java.util.Stack; +import java.util.jar.Attributes; +import java.util.jar.Attributes.Name; +import java.util.jar.JarFile; +import java.util.jar.Manifest; + +import static org.junit.Assert.*; + +/** + * The LauncherLifecycleCommandsJUnitTest class is a test suite of test cases testing the contract and functionality of + * the lifecycle launcher GemFire shell (Gfsh) commands. + * + * @author John Blum + * @see com.gemstone.gemfire.management.internal.cli.commands.LauncherLifecycleCommands + * @see org.junit.Assert + * @see org.junit.Test + * @since 7.0 + */ +@SuppressWarnings("unused") +@Category(UnitTest.class) +public class LauncherLifecycleCommandsJUnitTest { + + private static final String GFSH_DEPENDENCIES_JAR_PATHNAME = IOUtils.appendToPath(System.getenv("GEMFIRE"), "lib", + "gfsh-dependencies.jar"); + + private LauncherLifecycleCommands launcherCommands; + + @Before + public void setup() { + launcherCommands = new LauncherLifecycleCommands(); + } + + @After + public void tearDown() { + launcherCommands = null; + } + + protected LauncherLifecycleCommands getLauncherLifecycleCommands() { + return launcherCommands; + } + + protected 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); + } + + @Test + public void testAddGemFirePropertyFileToCommandLine() { + final List<String> commandLine = new ArrayList<>(); + + assertTrue(commandLine.isEmpty()); + + getLauncherLifecycleCommands().addGemFirePropertyFile(commandLine, null); + + assertTrue(commandLine.isEmpty()); + + getLauncherLifecycleCommands().addGemFirePropertyFile(commandLine, StringUtils.EMPTY_STRING); + + assertTrue(commandLine.isEmpty()); + + getLauncherLifecycleCommands().addGemFirePropertyFile(commandLine, " "); + + assertTrue(commandLine.isEmpty()); + + getLauncherLifecycleCommands().addGemFirePropertyFile(commandLine, "/path/to/gemfire.properties"); + + assertFalse(commandLine.isEmpty()); + assertTrue(commandLine.contains("-DgemfirePropertyFile=/path/to/gemfire.properties")); + } + + @Test + public void testAddGemFireSystemPropertiesToCommandLine() { + final List<String> commandLine = new ArrayList<>(); + + assertTrue(commandLine.isEmpty()); + + getLauncherLifecycleCommands().addGemFireSystemProperties(commandLine, new Properties()); + + assertTrue(commandLine.isEmpty()); + + final Properties gemfireProperties = new Properties(); + + gemfireProperties.setProperty(DistributionConfig.LOCATORS_NAME, "localhost[11235]"); + gemfireProperties.setProperty(DistributionConfig.LOG_LEVEL_NAME, "config"); + gemfireProperties.setProperty(DistributionConfig.LOG_FILE_NAME, StringUtils.EMPTY_STRING); + gemfireProperties.setProperty(DistributionConfig.MCAST_PORT_NAME, "0"); + gemfireProperties.setProperty(DistributionConfig.NAME_NAME, "tidepool"); + + getLauncherLifecycleCommands().addGemFireSystemProperties(commandLine, gemfireProperties); + + assertFalse(commandLine.isEmpty()); + assertEquals(4, commandLine.size()); + + for (final String propertyName : gemfireProperties.stringPropertyNames()) { + final String propertyValue = gemfireProperties.getProperty(propertyName); + if (StringUtils.isBlank(propertyValue)) { + for (final String systemProperty : commandLine) { + assertFalse(systemProperty.startsWith("-Dgemfire.".concat(propertyName).concat("="))); + } + } else { + assertTrue(commandLine.contains("-Dgemfire.".concat(propertyName).concat("=").concat(propertyValue))); + } + } + } + + @Test + public void testAddInitialHeapToCommandLine() { + final List<String> commandLine = new ArrayList<>(); + + assertTrue(commandLine.isEmpty()); + + getLauncherLifecycleCommands().addInitialHeap(commandLine, null); + + assertTrue(commandLine.isEmpty()); + + getLauncherLifecycleCommands().addInitialHeap(commandLine, StringUtils.EMPTY_STRING); + + assertTrue(commandLine.isEmpty()); + + getLauncherLifecycleCommands().addInitialHeap(commandLine, " "); + + assertTrue(commandLine.isEmpty()); + + getLauncherLifecycleCommands().addInitialHeap(commandLine, "512M"); + + assertFalse(commandLine.isEmpty()); + assertEquals("-Xms512M", commandLine.get(0)); + } + + @Test + public void testAddJvmArgumentsAndOptionsToCommandLine() { + final List<String> commandLine = new ArrayList<>(); + + assertTrue(commandLine.isEmpty()); + + getLauncherLifecycleCommands().addJvmArgumentsAndOptions(commandLine, null); + + assertTrue(commandLine.isEmpty()); + + getLauncherLifecycleCommands().addJvmArgumentsAndOptions(commandLine, new String[]{}); + + assertTrue(commandLine.isEmpty()); + + getLauncherLifecycleCommands().addJvmArgumentsAndOptions(commandLine, + new String[]{"-DmyProp=myVal", "-d64", "-server", "-Xprof"}); + + assertFalse(commandLine.isEmpty()); + assertEquals(4, commandLine.size()); + assertEquals("-DmyProp=myVal", commandLine.get(0)); + assertEquals("-d64", commandLine.get(1)); + assertEquals("-server", commandLine.get(2)); + assertEquals("-Xprof", commandLine.get(3)); + } + + // Fix for Bug #47192 - "Making GemFire (JVM) to exit in case of OutOfMemory" + @Test + public void testAddJvmOptionsForOutOfMemoryErrors() { + final List<String> jvmOptions = new ArrayList<>(1); + + getLauncherLifecycleCommands().addJvmOptionsForOutOfMemoryErrors(jvmOptions); + + if (SystemUtils.isHotSpotVM()) { + if (SystemUtils.isWindows()) { + assertTrue(jvmOptions.contains("-XX:OnOutOfMemoryError=taskkill /F /PID %p")); + } else { + assertTrue(jvmOptions.contains("-XX:OnOutOfMemoryError=kill -KILL %p")); + } + } else if (SystemUtils.isJ9VM()) { + assertEquals(1, jvmOptions.size()); + assertTrue(jvmOptions.contains("-Xcheck:memory")); + } else if (SystemUtils.isJRockitVM()) { + assertEquals(1, jvmOptions.size()); + assertTrue(jvmOptions.contains("-XXexitOnOutOfMemory")); + } else { + assertTrue(jvmOptions.isEmpty()); + } + } + + @Test + public void testAddMaxHeapToCommandLine() { + final List<String> commandLine = new ArrayList<>(); + + assertTrue(commandLine.isEmpty()); + + getLauncherLifecycleCommands().addMaxHeap(commandLine, null); + + assertTrue(commandLine.isEmpty()); + + getLauncherLifecycleCommands().addMaxHeap(commandLine, StringUtils.EMPTY_STRING); + + assertTrue(commandLine.isEmpty()); + + getLauncherLifecycleCommands().addMaxHeap(commandLine, " "); + + assertTrue(commandLine.isEmpty()); + + getLauncherLifecycleCommands().addMaxHeap(commandLine, "1024M"); + + assertFalse(commandLine.isEmpty()); + assertEquals(3, commandLine.size()); + assertEquals("-Xmx1024M", commandLine.get(0)); + assertEquals("-XX:+UseConcMarkSweepGC", commandLine.get(1)); + assertEquals("-XX:CMSInitiatingOccupancyFraction=" + LauncherLifecycleCommands.CMS_INITIAL_OCCUPANCY_FRACTION, + commandLine.get(2)); + } + + @Test(expected = AssertionError.class) + public void testReadPidWithNull() { + try { + getLauncherLifecycleCommands().readPid(null); + } catch (AssertionError expected) { + assertEquals("The file from which to read the process ID (pid) cannot be null!", expected.getMessage()); + throw expected; + } + } + + @Test + public void testReadPidWithNonExistingFile() { + assertEquals(LauncherLifecycleCommands.INVALID_PID, + getLauncherLifecycleCommands().readPid(new File("/path/to/non_existing/pid.file"))); + } + + @Test + public void testReadPid() throws IOException { + final int expectedPid = 12345; + + File pidFile = new File(getClass().getSimpleName().concat("_testReadPid.pid")); + + assertTrue(pidFile.createNewFile()); + + pidFile.deleteOnExit(); + writePid(pidFile, expectedPid); + + final int actualPid = getLauncherLifecycleCommands().readPid(pidFile); + + assertEquals(expectedPid, actualPid); + } + + @Test + @SuppressWarnings("deprecation") + public void testGetClasspath() { + assertEquals(System.getProperty("java.class.path"), getLauncherLifecycleCommands().getClasspath(null)); + } + + @Test + @SuppressWarnings("deprecation") + public void testGetClasspathWithUserDefinedClasspath() { + assertEquals(System.getProperty("java.class.path") + File.pathSeparator + "/path/to/user/classes", + getLauncherLifecycleCommands().getClasspath("/path/to/user/classes")); + } + + @Test + public void testGemFireCoreClasspath() throws IOException { + File coreDependenciesJar = new File(LauncherLifecycleCommands.CORE_DEPENDENCIES_JAR_PATHNAME); + + assertNotNull(coreDependenciesJar); + assertTrue(coreDependenciesJar + " is not a file", coreDependenciesJar.isFile()); + + Collection<String> expectedJarDependencies = Arrays.asList("antlr", "commons-io", "commons-lang", "commons-logging", + "gemfire", "jackson-annotations", "jackson-core", "jackson-databind", "jansi", "jline", "snappy-java", + "spring-core", "spring-shell", "jetty-server", "jetty-servlet", "jetty-webapp", "jetty-util", "jetty-http", + "servlet-api", "jetty-io", "jetty-security", "jetty-xml" + + ); + + assertJarFileManifestClassPath(coreDependenciesJar, expectedJarDependencies); + } + + @Test + public void testGetSpringJars() { + List<String> actualSpringJarPathnames = new LauncherLifecycleCommands().getSpringJars(); + + assertNotNull(actualSpringJarPathnames); + assertEquals(LauncherLifecycleCommands.SPRING_JAR_NAME_PREFIXES.size(), actualSpringJarPathnames.size()); + + int springCoreVersion = -1; + int springDataCommonsVersion = -1; + int springDataGemFireVersion = -1; + + Set<String> expectedSpringJarNames = new HashSet<>(LauncherLifecycleCommands.SPRING_JAR_NAME_PREFIXES); + + assertFalse(expectedSpringJarNames.isEmpty()); + + for (String springJarPathname : actualSpringJarPathnames) { + String springJarName = springJarPathname.substring(springJarPathname.lastIndexOf(File.separator) + 1); + String springJarNamePrefix = springJarName.substring(0, springJarName.lastIndexOf("-")); + + switch (springJarNamePrefix) { + case LauncherLifecycleCommands.SPRING_BEANS_JAR_NAME_PREFIX: + springCoreVersion = Integer.parseInt(StringUtils.getDigitsOnly(springJarName)); + break; + case LauncherLifecycleCommands.SPRING_DATA_COMMONS_JAR_NAME_PREFIX: + springDataCommonsVersion = Integer.parseInt(StringUtils.getDigitsOnly(springJarName)); + break; + case LauncherLifecycleCommands.SPRING_DATA_GEMFIRE_JAR_NAME_PREFIX: + springDataGemFireVersion = Integer.parseInt(StringUtils.getDigitsOnly(springJarName)); + break; + } + + expectedSpringJarNames.remove(springJarNamePrefix); + } + + assertTrue(String.format("Expected empty; but was (%1$s)", expectedSpringJarNames), + expectedSpringJarNames.isEmpty()); + assertEquals(3212, springCoreVersion); + assertEquals(191, springDataCommonsVersion); + assertEquals(151, springDataGemFireVersion); + } + + @Test + public void testGetSystemClasspath() { + assertEquals(System.getProperty("java.class.path"), getLauncherLifecycleCommands().getSystemClasspath()); + } + + @Test + public void testLocatorClasspathOrder() { + String userClasspath = "/path/to/user/lib/app.jar:/path/to/user/classes"; + + String expectedClasspath = launcherCommands.getGemFireJarPath().concat(File.pathSeparator).concat( + userClasspath).concat(File.pathSeparator).concat(System.getProperty("java.class.path")).concat( + File.pathSeparator).concat(LauncherLifecycleCommands.CORE_DEPENDENCIES_JAR_PATHNAME); + + String actualClasspath = launcherCommands.getLocatorClasspath(true, userClasspath); + + assertEquals(expectedClasspath, actualClasspath); + } + + @Test + public void testServerClasspathOrder() { + String userClasspath = "/path/to/user/lib/app.jar:/path/to/user/classes"; + + String expectedClasspath = launcherCommands.getGemFireJarPath().concat(File.pathSeparator).concat( + userClasspath).concat(File.pathSeparator).concat( + LauncherLifecycleCommands.CORE_DEPENDENCIES_JAR_PATHNAME).concat(File.pathSeparator).concat( + toPath(launcherCommands.getSpringJars().toArray())); + + String actualClasspath = launcherCommands.getServerClasspath(false, true, userClasspath); + + assertEquals(expectedClasspath, actualClasspath); + } + + private String toPath(Object... pathElements) { + String path = ""; + + for (Object pathElement : pathElements) { + path += (path.isEmpty() ? StringUtils.EMPTY_STRING : File.pathSeparator); + path += pathElement; + } + + return path; + } + + @Test + public void testToClasspath() { + final boolean EXCLUDE_SYSTEM_CLASSPATH = false; + final boolean INCLUDE_SYSTEM_CLASSPATH = true; + + String[] jarFilePathnames = {"/path/to/user/libs/A.jar", "/path/to/user/libs/B.jar", "/path/to/user/libs/C.jar"}; + + String[] userClasspaths = {"/path/to/classes:/path/to/libs/1.jar:/path/to/libs/2.jar", "/path/to/ext/libs/1.jar:/path/to/ext/classes:/path/to/ext/lib/10.jar"}; + + String expectedClasspath = LauncherLifecycleCommands.GEMFIRE_JAR_PATHNAME.concat(File.pathSeparator).concat( + toClasspath(userClasspaths)).concat(File.pathSeparator).concat(toClasspath(jarFilePathnames)); + + assertEquals(expectedClasspath, + getLauncherLifecycleCommands().toClasspath(EXCLUDE_SYSTEM_CLASSPATH, jarFilePathnames, userClasspaths)); + + expectedClasspath = LauncherLifecycleCommands.GEMFIRE_JAR_PATHNAME.concat(File.pathSeparator).concat( + toClasspath(userClasspaths)).concat(File.pathSeparator).concat(System.getProperty("java.class.path")).concat( + File.pathSeparator).concat(toClasspath(jarFilePathnames)); + + assertEquals(expectedClasspath, + getLauncherLifecycleCommands().toClasspath(INCLUDE_SYSTEM_CLASSPATH, jarFilePathnames, userClasspaths)); + + expectedClasspath = LauncherLifecycleCommands.GEMFIRE_JAR_PATHNAME.concat(File.pathSeparator).concat( + System.getProperty("java.class.path")); + + assertEquals(expectedClasspath, + getLauncherLifecycleCommands().toClasspath(INCLUDE_SYSTEM_CLASSPATH, null, (String[]) null)); + + assertEquals(LauncherLifecycleCommands.GEMFIRE_JAR_PATHNAME, + getLauncherLifecycleCommands().toClasspath(EXCLUDE_SYSTEM_CLASSPATH, null, (String[]) null)); + + assertEquals(LauncherLifecycleCommands.GEMFIRE_JAR_PATHNAME, + getLauncherLifecycleCommands().toClasspath(EXCLUDE_SYSTEM_CLASSPATH, new String[0], "")); + } + + @Test + public void testToClassPathOrder() { + String userClasspathOne = "/path/to/user/lib/a.jar:/path/to/user/classes"; + String userClasspathTwo = "/path/to/user/lib/x.jar:/path/to/user/lib/y.jar:/path/to/user/lib/z.jar"; + + String expectedClasspath = launcherCommands.getGemFireJarPath().concat(File.pathSeparator).concat( + userClasspathOne).concat(File.pathSeparator).concat(userClasspathTwo).concat(File.pathSeparator).concat( + System.getProperty("java.class.path")).concat(File.pathSeparator).concat( + LauncherLifecycleCommands.CORE_DEPENDENCIES_JAR_PATHNAME).concat(File.pathSeparator).concat( + LauncherLifecycleCommands.CORE_DEPENDENCIES_JAR_PATHNAME); + + String actualClasspath = launcherCommands.toClasspath(true, + new String[]{LauncherLifecycleCommands.CORE_DEPENDENCIES_JAR_PATHNAME, LauncherLifecycleCommands.CORE_DEPENDENCIES_JAR_PATHNAME}, + userClasspathOne, userClasspathTwo); + + assertEquals(expectedClasspath, actualClasspath); + } + + private void assertJarFileManifestClassPath(final File dependenciesJar, + final Collection<String> expectedJarDependencies) throws IOException { + JarFile dependenciesJarFile = new JarFile(dependenciesJar); + Manifest manifest = dependenciesJarFile.getManifest(); + + assertNotNull(manifest); + + Attributes attributes = manifest.getMainAttributes(); + + assertNotNull(attributes); + assertTrue(attributes.containsKey(Name.CLASS_PATH)); + + String[] actualJarDependencies = attributes.getValue(Name.CLASS_PATH).split(" "); + + assertNotNull(actualJarDependencies); + assertTrue(String.format("Expected the actual number of JAR dependencies to be (%1$d); but was (%2$d)!", + expectedJarDependencies.size(), actualJarDependencies.length), + actualJarDependencies.length >= expectedJarDependencies.size()); + //assertTrue(Arrays.asList(actualJarDependencies).containsAll(expectedJarDependencies)); + + List<String> actualJarDependenciesList = new ArrayList<>(Arrays.asList(actualJarDependencies)); + List<String> missingExpectedJarDependenciesList = new ArrayList<>(expectedJarDependencies.size()); + + for (String expectedJarDependency : expectedJarDependencies) { + boolean containsExpectedJar = false; + + for (int index = 0, size = actualJarDependenciesList.size(); index < size; index++) { + if (actualJarDependenciesList.get(index).toLowerCase().contains(expectedJarDependency.toLowerCase())) { + actualJarDependenciesList.remove(index); + containsExpectedJar = true; + break; + } + } + + if (!containsExpectedJar) { + missingExpectedJarDependenciesList.add(expectedJarDependency); + } + } + + assertTrue(String.format( + "GemFire dependencies JAR file (%1$s) does not contain the expected dependencies (%2$s) in the Manifest Class-Path attribute (%3$s)!", + dependenciesJar, missingExpectedJarDependenciesList, attributes.getValue(Name.CLASS_PATH)), + missingExpectedJarDependenciesList.isEmpty()); + } + + private String toClasspath(final String... jarFilePathnames) { + String classpath = StringUtils.EMPTY_STRING; + + if (jarFilePathnames != null) { + for (final String jarFilePathname : jarFilePathnames) { + classpath += (classpath.isEmpty() ? StringUtils.EMPTY_STRING : File.pathSeparator); + classpath += jarFilePathname; + } + } + + return classpath; + } + + @Test + public void testGetJavaPathname() { + assertEquals(IOUtils.appendToPath(System.getProperty("java.home"), "bin", + "java" + LauncherLifecycleCommands.getExecutableSuffix()), + getLauncherLifecycleCommands().getJdkToolPathname("java" + LauncherLifecycleCommands.getExecutableSuffix(), + new GemFireException() { + })); + } + + @Test(expected = NullPointerException.class) + public void testGetJdkToolPathnameWithNullPathnames() { + try { + getLauncherLifecycleCommands().getJdkToolPathname((Stack<String>) null, new GemFireException() { + }); + } catch (NullPointerException expected) { + assertEquals("The JDK tool executable pathnames cannot be null!", expected.getMessage()); + throw expected; + } + } + + @Test(expected = NullPointerException.class) + public void testGetJdkToolPathnameWithNullGemFireException() { + try { + getLauncherLifecycleCommands().getJdkToolPathname(new Stack<String>(), null); + } catch (NullPointerException expected) { + assertEquals("The GemFireException cannot be null!", expected.getMessage()); + throw expected; + } + } + + @Test + public void testGetJdkToolPathnameForNonExistingTool() { + try { + final GemFireException expected = new GemFireException() { + @Override + public String getMessage() { + return "expected"; + } + }; + + getLauncherLifecycleCommands().getJdkToolPathname("nonExistingTool.exe", expected); + } catch (GemFireException expected) { + assertEquals("expected", expected.getMessage()); + } + } + + @Test + public void testGetLocatorId() { + assertEquals("tidepool[11235]", getLauncherLifecycleCommands().getLocatorId("tidepool", 11235)); + assertEquals("tidepool.gemstone.com[11235]", + getLauncherLifecycleCommands().getLocatorId("tidepool.gemstone.com", 11235)); + assertEquals("tidepool[" + DistributionLocator.DEFAULT_LOCATOR_PORT + "]", + getLauncherLifecycleCommands().getLocatorId("tidepool", null)); + } + + @Test + public void testGetServerId() { + assertEquals("tidepool[12480]", getLauncherLifecycleCommands().getServerId("tidepool", 12480)); + assertEquals("tidepool.vmware.com[12480]", + getLauncherLifecycleCommands().getServerId("tidepool.vmware.com", 12480)); + assertEquals("tidepool[" + CacheServer.DEFAULT_PORT + "]", + getLauncherLifecycleCommands().getServerId("tidepool", null)); + } + + @Test + public void testCreateJmxServerUrlWithMemberName() { + assertEquals("service:jmx:rmi://localhost:8192/jndi/rmi://localhost:8192/jmxrmi", + getLauncherLifecycleCommands().getJmxServiceUrlAsString("localhost[8192]")); + } + + @Test(expected = IllegalArgumentException.class) + public void testCreateJmxServiceUrlWithInvalidMemberName() { + try { + System.err.println(getLauncherLifecycleCommands().getJmxServiceUrlAsString("memberOne[]")); + } catch (IllegalArgumentException expected) { + assertEquals(CliStrings.START_JCONSOLE__CONNECT_BY_MEMBER_NAME_ID_ERROR_MESSAGE, expected.getMessage()); + throw expected; + } + } + + @Test + public void testCreateServerCommandLine() throws Exception { + ServerLauncher serverLauncher = new ServerLauncher.Builder().setCommand( + ServerLauncher.Command.START).setDisableDefaultServer(true).setMemberName( + "testCreateServerCommandLine").setRebalance(true) + //.setServerBindAddress("localhost") + .setServerPort(41214).setCriticalHeapPercentage(95.5f).setEvictionHeapPercentage(85.0f).build(); + + String[] commandLineElements = launcherCommands.createStartServerCommandLine(serverLauncher, null, null, + new Properties(), null, false, new String[0], false, null, null); + + assertNotNull(commandLineElements); + assertTrue(commandLineElements.length > 0); + + Set<String> expectedCommandLineElements = new HashSet<>(6); + + expectedCommandLineElements.add(serverLauncher.getCommand().getName()); + expectedCommandLineElements.add("--disable-default-server"); + expectedCommandLineElements.add(serverLauncher.getMemberName().toLowerCase()); + expectedCommandLineElements.add("--rebalance"); + //expectedCommandLineElements.add(String.format("--server-bind-address=%1$s", serverLauncher.getServerBindAddress().getHostName())); + expectedCommandLineElements.add(String.format("--server-port=%1$d", serverLauncher.getServerPort())); + expectedCommandLineElements.add( + String.format("--critical-heap-percentage=%1$s", serverLauncher.getCriticalHeapPercentage())); + expectedCommandLineElements.add( + String.format("--eviction-heap-percentage=%1$s", serverLauncher.getEvictionHeapPercentage())); + + for (String commandLineElement : commandLineElements) { + expectedCommandLineElements.remove(commandLineElement.toLowerCase()); + } + + assertTrue(String.format("Expected ([]); but was (%1$s)", expectedCommandLineElements), + expectedCommandLineElements.isEmpty()); + } + +}
