You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by kh...@apache.org on 2018/08/08 16:51:55 UTC
[geode] branch develop updated: Geode 3530 launcher lifecycle
server commands (#2267)
This is an automated email from the ASF dual-hosted git repository.
khowe pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/geode.git
The following commit(s) were added to refs/heads/develop by this push:
new 57581af Geode 3530 launcher lifecycle server commands (#2267)
57581af is described below
commit 57581af961203ed373456ce84a5c8e7bdb4e0ee6
Author: Helena Bales <hb...@pivotal.io>
AuthorDate: Wed Aug 8 09:51:50 2018 -0700
Geode 3530 launcher lifecycle server commands (#2267)
* GEODE-3530: Modernize LauncherLifecycleCommandsDUnit
* Extract server start and locator start/stop/status commands into their own
classes
* Remove the CliCommandTestBase
* make locator names match test method names
* add a method for writing classes to a jar file
* add a function to use up all the server's memory for testing
* add max heap property for out of memory test
Make the behavior of the server out of memory test more reliable by
adding a maxheap size (otherwise the size is decided by the JVM)
Signed-off-by: Ken Howe<kh...@pivotal.io>
---
.../LauncherLifecycleCommandsDUnitTest.java | 843 ---------------------
.../cli/commands/RunOutOfMemoryFunction.java | 34 +
.../cli/commands/StartLocatorCommandDUnitTest.java | 8 +-
.../cli/commands/StartServerCommandDUnitTest.java | 473 ++++++++++++
.../commands/StatusLocatorCommandDunitTest.java | 89 ---
.../cli/commands/StopLocatorCommandDUnitTest.java | 262 +++++++
.../apache/geode/test/compiler/ClassBuilder.java | 25 +-
.../org/apache/geode/test/compiler/TestObject.java | 21 +
.../geode/test/compiler/ClassBuilderTest.java | 62 ++
9 files changed, 879 insertions(+), 938 deletions(-)
diff --git a/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/LauncherLifecycleCommandsDUnitTest.java b/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/LauncherLifecycleCommandsDUnitTest.java
deleted file mode 100644
index b5a8ea9..0000000
--- a/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/LauncherLifecycleCommandsDUnitTest.java
+++ /dev/null
@@ -1,843 +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.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.IOException;
-import java.io.OutputStreamWriter;
-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.Rule;
-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.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.FlakyTest;
-import org.apache.geode.test.junit.rules.RequiresGeodeHome;
-
-/**
- * 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
- */
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-@SuppressWarnings("serial")
-public class LauncherLifecycleCommandsDUnitTest extends CliCommandTestBase {
-
- @Rule
- public RequiresGeodeHome requiresGeodeHome = new RequiresGeodeHome();
-
- 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) {
- 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) {
- final Integer pid = readPid(new File(workingDirectory));
- return waitForGemFireProcessToStop(
- new Builder().setCommand(Command.STOP).setWorkingDirectory(workingDirectory).build().stop(),
- pid);
- }
-
- protected Status stopServer(final String workingDirectory) {
- final Integer pid = readPid(new File(workingDirectory));
- return waitForGemFireProcessToStop(
- new ServerLauncher.Builder().setCommand(ServerLauncher.Command.STOP)
- .setWorkingDirectory(workingDirectory).build().stop(),
- pid);
- }
-
- 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 Integer pid) {
- if (!Status.STOPPED.equals(serviceState.getStatus())) {
-
- 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);
- }
- }
- }
-
- return serviceState.getStatus();
- }
-
- /**
- * Test to verify GEODE-2138
- *
- */
- @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 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 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
- @Category(FlakyTest.class) // GEODE-1866
- 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, "12M");
- 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;
- }
-
-}
diff --git a/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/RunOutOfMemoryFunction.java b/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/RunOutOfMemoryFunction.java
new file mode 100644
index 0000000..c030788
--- /dev/null
+++ b/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/RunOutOfMemoryFunction.java
@@ -0,0 +1,34 @@
+/*
+ * 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 org.apache.geode.cache.Region;
+import org.apache.geode.cache.execute.Function;
+import org.apache.geode.cache.execute.FunctionContext;
+
+public class RunOutOfMemoryFunction implements Function {
+
+ @Override
+ public void execute(FunctionContext context) {
+ byte[] bytes = new byte[Integer.MAX_VALUE / 2];
+ byte[] bytes1 = new byte[Integer.MAX_VALUE / 2];
+ byte[] bytes2 = new byte[Integer.MAX_VALUE / 2];
+
+ Region testRegion = context.getCache().getRegion("/testRegion");
+ testRegion.put("byteArray", bytes);
+ testRegion.put("byteArray1", bytes1);
+ testRegion.put("byteArray2", bytes2);
+ }
+}
diff --git a/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/StartLocatorCommandDUnitTest.java b/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/StartLocatorCommandDUnitTest.java
index 3c2c7f6..0e0bf18 100644
--- a/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/StartLocatorCommandDUnitTest.java
+++ b/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/StartLocatorCommandDUnitTest.java
@@ -35,7 +35,6 @@ import java.text.MessageFormat;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.ClassRule;
-import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
@@ -226,14 +225,13 @@ public class StartLocatorCommandDUnitTest {
assertThat(result.getMessageFromContent()).containsPattern(expectedMessage);
}
- @Ignore // Ignore until test until tests in CI use a different user
@Test
public void testInMissingRelativeDirectoryWithoutCreatePermissions() {
// path to a missing dir that cannot be created due to insufficient permissions
final String missingDirPath = "/missing/path/to/start/in";
final String expectedMessage = "Could not create directory " + missingDirPath
+ ". Please verify directory path or user permissions.";
- final String memberName = "testWithMissingRelativeDirectory-locator";
+ final String memberName = "testInMissingRelativeDirectoryWithoutCreatePermissions-locator";
CommandStringBuilder command = new CommandStringBuilder(START_LOCATOR)
.addOption(START_LOCATOR__MEMBER_NAME, memberName)
@@ -250,7 +248,7 @@ public class StartLocatorCommandDUnitTest {
public void testInMissingRelativeDirectoryThatCanBeCreated() {
// path to a missing dir that can be created
final String missingDirPath = System.getProperty("user.dir") + "/missing/path/to/start/in";
- final String memberName = "testWithMissingRelativeDirectory-locator";
+ final String memberName = "testInMissingRelativeDirectoryThatCanBeCreated-locator";
final String expectedMessage = "Locator in " + missingDirPath;
CommandStringBuilder command = new CommandStringBuilder(START_LOCATOR)
@@ -307,7 +305,7 @@ public class StartLocatorCommandDUnitTest {
assertThat(result.getStatus()).isEqualTo(Result.Status.OK);
assertThat(result.getMessageFromContent()).contains(expectedMessage);
- // Verify GEODE-2138
+ // Verify GEODE-2138 (Geode commands do not contain GemFire in output)
assertThat(result.getMessageFromContent()).doesNotContain("Gemfire")
.doesNotContain("GemFire");
assertThat(result.getMessageFromContent()).containsPattern(expectedVersionPattern);
diff --git a/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/StartServerCommandDUnitTest.java b/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/StartServerCommandDUnitTest.java
new file mode 100644
index 0000000..dd96e99
--- /dev/null
+++ b/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/StartServerCommandDUnitTest.java
@@ -0,0 +1,473 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.geode.management.internal.cli.commands;
+
+import static org.apache.geode.management.internal.cli.i18n.CliStrings.CACHE_XML_NOT_FOUND_MESSAGE;
+import static org.apache.geode.management.internal.cli.i18n.CliStrings.CREATE_REGION;
+import static org.apache.geode.management.internal.cli.i18n.CliStrings.CREATE_REGION__REGION;
+import static org.apache.geode.management.internal.cli.i18n.CliStrings.CREATE_REGION__REGIONSHORTCUT;
+import static org.apache.geode.management.internal.cli.i18n.CliStrings.GEODE_0_PROPERTIES_1_NOT_FOUND_MESSAGE;
+import static org.apache.geode.management.internal.cli.i18n.CliStrings.GROUP;
+import static org.apache.geode.management.internal.cli.i18n.CliStrings.START_SERVER;
+import static org.apache.geode.management.internal.cli.i18n.CliStrings.START_SERVER__CACHE_XML_FILE;
+import static org.apache.geode.management.internal.cli.i18n.CliStrings.START_SERVER__DIR;
+import static org.apache.geode.management.internal.cli.i18n.CliStrings.START_SERVER__FORCE;
+import static org.apache.geode.management.internal.cli.i18n.CliStrings.START_SERVER__LOCATORS;
+import static org.apache.geode.management.internal.cli.i18n.CliStrings.START_SERVER__MAXHEAP;
+import static org.apache.geode.management.internal.cli.i18n.CliStrings.START_SERVER__NAME;
+import static org.apache.geode.management.internal.cli.i18n.CliStrings.START_SERVER__OFF_HEAP_MEMORY_SIZE;
+import static org.apache.geode.management.internal.cli.i18n.CliStrings.START_SERVER__PROPERTIES;
+import static org.apache.geode.management.internal.cli.i18n.CliStrings.START_SERVER__SECURITY_PROPERTIES;
+import static org.apache.geode.management.internal.cli.i18n.CliStrings.START_SERVER__SERVER_PORT;
+import static org.apache.geode.management.internal.cli.i18n.CliStrings.START_SERVER__USERNAME;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.lang.management.ManagementFactory;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+import org.apache.geode.cache.execute.FunctionException;
+import org.apache.geode.cache.execute.FunctionService;
+import org.apache.geode.distributed.AbstractLauncher;
+import org.apache.geode.distributed.ServerLauncher;
+import org.apache.geode.internal.AvailablePortHelper;
+import org.apache.geode.internal.process.ProcessType;
+import org.apache.geode.internal.process.ProcessUtils;
+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.compiler.ClassBuilder;
+import org.apache.geode.test.dunit.rules.ClusterStartupRule;
+import org.apache.geode.test.dunit.rules.MemberVM;
+import org.apache.geode.test.junit.rules.GfshCommandRule;
+
+public class StartServerCommandDUnitTest {
+ private static MemberVM locator;
+ private static String locatorConnectionString;
+ private File workingDir;
+
+ @ClassRule
+ public static final ClusterStartupRule cluster = new ClusterStartupRule();
+
+ @ClassRule
+ public static final GfshCommandRule gfsh = new GfshCommandRule();
+
+ @Rule
+ public final TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+ @Before
+ public void before() throws IOException {
+ workingDir = temporaryFolder.newFolder();
+ }
+
+ @BeforeClass
+ public static void beforeClass() throws Exception {
+ // locator used to clean up members started during tests
+ locator = cluster.startLocatorVM(0, 0);
+
+ locatorConnectionString = "localhost[" + locator.getPort() + "]";
+
+ gfsh.connectAndVerify(locator);
+ }
+
+ @AfterClass
+ public static void afterClass() throws Exception {
+ gfsh.connectAndVerify(locator);
+ gfsh.execute("shutdown --include-locators");
+ }
+
+ @Test
+ public void testWithMissingCacheXml() throws IOException {
+ final Integer serverPort = AvailablePortHelper.getRandomAvailableTCPPort();
+ final String missingCacheXmlPath = "/missing/cache.xml";
+ final String memberName = "testWithMissingCacheXml-server";
+ final String expectedError =
+ CliStrings.format(CACHE_XML_NOT_FOUND_MESSAGE, missingCacheXmlPath);
+
+ String command = new CommandStringBuilder(START_SERVER)
+ .addOption(START_SERVER__NAME, memberName)
+ .addOption(START_SERVER__LOCATORS, locatorConnectionString)
+ .addOption(START_SERVER__SERVER_PORT, serverPort.toString())
+ .addOption(START_SERVER__CACHE_XML_FILE, missingCacheXmlPath)
+ .addOption(START_SERVER__DIR, workingDir.getCanonicalPath())
+ .getCommandString();
+
+ CommandResult result = gfsh.executeCommand(command);
+
+ assertThat(result.getStatus()).isEqualTo(Result.Status.ERROR);
+ assertThat(result.getMessageFromContent()).contains(expectedError);
+ }
+
+ @Test
+ public void testWithMissingGemFirePropertiesFile() throws IOException {
+ final Integer serverPort = AvailablePortHelper.getRandomAvailableTCPPort();
+ final String missingGemfirePropertiesPath = "/missing/gemfire.properties";
+ final String memberName = "testWithMissingGemFirePropertiesFile-server";
+ final String expectedError =
+ CliStrings.format(GEODE_0_PROPERTIES_1_NOT_FOUND_MESSAGE, "", missingGemfirePropertiesPath);
+
+ String command = new CommandStringBuilder(START_SERVER)
+ .addOption(START_SERVER__NAME, memberName)
+ .addOption(START_SERVER__LOCATORS, locatorConnectionString)
+ .addOption(START_SERVER__SERVER_PORT, serverPort.toString())
+ .addOption(START_SERVER__PROPERTIES, missingGemfirePropertiesPath)
+ .addOption(START_SERVER__DIR, workingDir.getCanonicalPath())
+ .getCommandString();
+
+ CommandResult result = gfsh.executeCommand(command);
+
+ assertThat(result.getStatus()).isEqualTo(Result.Status.ERROR);
+ assertThat(result.getMessageFromContent()).contains(expectedError);
+ }
+
+ @Test
+ public void testWithMissingPassword() throws IOException {
+ final Integer serverPort = AvailablePortHelper.getRandomAvailableTCPPort();
+ final String memberName = "testWithMissingPassword-server";
+ final String expectedError = "password must be specified.";
+
+ String command = new CommandStringBuilder(START_SERVER)
+ .addOption(START_SERVER__NAME, memberName)
+ .addOption(START_SERVER__LOCATORS, locatorConnectionString)
+ .addOption(START_SERVER__SERVER_PORT, serverPort.toString())
+ .addOption(START_SERVER__USERNAME, "usernameValue")
+ .addOption(START_SERVER__DIR, workingDir.getCanonicalPath())
+ .getCommandString();
+
+ CommandResult result = gfsh.executeCommand(command);
+
+ assertThat(result.getStatus()).isEqualTo(Result.Status.ERROR);
+ assertThat(result.getMessageFromContent()).contains(expectedError);
+ }
+
+ @Test
+ public void testWithMissingSecurityPropertiesFile() throws IOException {
+ final Integer serverPort = AvailablePortHelper.getRandomAvailableTCPPort();
+ final String missingSecurityPropertiesPath = "/missing/security.properties";
+ final String memberName = "testWithMissingSecurityPropertiesFile-server";
+ final String expectedError = CliStrings.format(GEODE_0_PROPERTIES_1_NOT_FOUND_MESSAGE,
+ "Security ", missingSecurityPropertiesPath);
+
+ String command = new CommandStringBuilder(START_SERVER)
+ .addOption(START_SERVER__NAME, memberName)
+ .addOption(START_SERVER__LOCATORS, locatorConnectionString)
+ .addOption(START_SERVER__SERVER_PORT, serverPort.toString())
+ .addOption(START_SERVER__DIR, workingDir.getCanonicalPath())
+ .addOption(START_SERVER__SECURITY_PROPERTIES, missingSecurityPropertiesPath)
+ .getCommandString();
+
+ CommandResult result = gfsh.executeCommand(command);
+
+ assertThat(result.getStatus()).isEqualTo(Result.Status.ERROR);
+ assertThat(result.getMessageFromContent()).contains(expectedError);
+ }
+
+ @Test
+ public void testWithUnavailablePort() throws IOException {
+ final Integer serverPort = AvailablePortHelper.getRandomAvailableTCPPort();
+ final String memberName = "testWithUnavailablePort-server";
+ final String expectedError =
+ "java.lang.RuntimeException: An IO error occurred while starting a Server";
+ final String expectedCause = "Caused by: java.net.BindException: "
+ + "Network is unreachable; port (" + serverPort + ") is not available on localhost.";
+
+ try (Socket interferingProcess = new Socket()) {
+ interferingProcess.bind(new InetSocketAddress(serverPort)); // make the target port
+ // unavailable
+
+ String command = new CommandStringBuilder(START_SERVER)
+ .addOption(START_SERVER__NAME, memberName)
+ .addOption(START_SERVER__LOCATORS, locatorConnectionString)
+ .addOption(START_SERVER__SERVER_PORT, serverPort.toString())
+ .addOption(START_SERVER__DIR, workingDir.getCanonicalPath())
+ .getCommandString();
+
+ CommandResult result = gfsh.executeCommand(command);
+
+ assertThat(result.getStatus()).isEqualTo(Result.Status.ERROR);
+ assertThat(result.getMessageFromContent()).contains(expectedError).contains(expectedCause);
+ }
+ }
+
+ @Test
+ public void testWithAvailablePort() throws IOException {
+ final Integer serverPort = AvailablePortHelper.getRandomAvailableTCPPort();
+ final String memberName = "testWithAvailablePort-server";
+ final String expectedMessage = "Server in " + workingDir.getCanonicalPath();
+ final String expectedMessage2 = "as " + memberName + " is currently online.";
+
+ String command = new CommandStringBuilder(START_SERVER)
+ .addOption(START_SERVER__NAME, memberName)
+ .addOption(START_SERVER__LOCATORS, locatorConnectionString)
+ .addOption(START_SERVER__SERVER_PORT, serverPort.toString())
+ .addOption(START_SERVER__DIR, workingDir.getCanonicalPath())
+ .getCommandString();
+
+ CommandResult result = gfsh.executeCommand(command);
+
+ assertThat(result.getStatus()).isEqualTo(Result.Status.OK);
+ assertThat(result.getMessageFromContent()).contains(expectedMessage).contains(expectedMessage2);
+ }
+
+ @Test
+ public void testWithMissingStartDirectoryThatCannotBeCreated() {
+ final Integer serverPort = AvailablePortHelper.getRandomAvailableTCPPort();
+ final String missingDirPath = "/missing/dir/to/start/in";
+ final String memberName = "testWithMissingStartDirectoryThatCannotBeCreated-server";
+ final String expectedError = "Could not create directory " + missingDirPath
+ + ". Please verify directory path or user permissions.";
+
+ String command = new CommandStringBuilder(START_SERVER)
+ .addOption(START_SERVER__NAME, memberName)
+ .addOption(START_SERVER__LOCATORS, locatorConnectionString)
+ .addOption(START_SERVER__SERVER_PORT, serverPort.toString())
+ .addOption(START_SERVER__DIR, missingDirPath)
+ .getCommandString();
+
+ CommandResult result = gfsh.executeCommand(command);
+
+ assertThat(result.getStatus()).isEqualTo(Result.Status.ERROR);
+ assertThat(result.getMessageFromContent()).contains(expectedError);
+ }
+
+ @Test
+ public void testWithMissingStartDirectoryThatCanBeCreated() throws IOException {
+ final Integer serverPort = AvailablePortHelper.getRandomAvailableTCPPort();
+ final String missingDirPath = workingDir.getCanonicalPath() + "/missing/dir/to/start/in";
+ final String memberName = "testWithMissingStartDirectoryThatCanBeCreated-server";
+ final String expectedMessage = "Server in " + missingDirPath;
+
+ try {
+ String command = new CommandStringBuilder(START_SERVER)
+ .addOption(START_SERVER__NAME, memberName)
+ .addOption(START_SERVER__LOCATORS, locatorConnectionString)
+ .addOption(START_SERVER__SERVER_PORT, serverPort.toString())
+ .addOption(START_SERVER__DIR, missingDirPath)
+ .getCommandString();
+
+ CommandResult result = gfsh.executeCommand(command);
+
+ assertThat(result.getStatus()).isEqualTo(Result.Status.OK);
+ assertThat(result.getMessageFromContent()).contains(expectedMessage);
+ } finally {
+ File toDelete = new File(missingDirPath);
+ deleteServerFiles(toDelete);
+ }
+ }
+
+ @Test
+ public void testWithConflictingPIDFile() throws IOException {
+ final String fileName = ProcessType.SERVER.getPidFileName();
+ final Integer serverPort = AvailablePortHelper.getRandomAvailableTCPPort();
+ final String memberName = "testWithConflictingPIDFile-server";
+
+ // create PID file
+ File pidFile = new File(workingDir.getAbsolutePath(), fileName);
+ assertThat(pidFile.createNewFile()).isTrue();
+
+ // write PID to PID file
+ try (FileWriter fileWriter = new FileWriter(pidFile, false)) {
+ fileWriter.write(getPidOrOne().toString() + "\n");
+ fileWriter.flush();
+ }
+ assertThat(pidFile.isFile()).isTrue();
+
+ String command = new CommandStringBuilder(START_SERVER)
+ .addOption(START_SERVER__NAME, memberName)
+ .addOption(START_SERVER__LOCATORS, locatorConnectionString)
+ .addOption(START_SERVER__SERVER_PORT, serverPort.toString())
+ .addOption(START_SERVER__DIR, pidFile.getParentFile().getCanonicalPath())
+ .getCommandString();
+
+ CommandResult result = gfsh.executeCommand(command);
+
+ final String expectedError = "A PID file already exists and a Server may be running in "
+ + pidFile.getParentFile().getCanonicalPath();
+ final String expectedCause = "Caused by: "
+ + "org.apache.geode.internal.process.FileAlreadyExistsException: Pid file already exists: "
+ + pidFile.getCanonicalPath();
+
+ assertThat(result.getStatus()).isEqualTo(Result.Status.ERROR);
+ assertThat(result.getMessageFromContent()).contains(expectedError).contains(expectedCause);
+
+ }
+
+ @Test
+ public void testWithForceOverwriteConflictingPIDFile() throws IOException {
+ final Integer serverPort = AvailablePortHelper.getRandomAvailableTCPPort();
+ final String memberName = "testWithForceOverwriteConflictingPIDFile-server";
+ final String fileName = ProcessType.SERVER.getPidFileName();
+
+ // create PID file
+ File pidFile = new File(workingDir.getAbsolutePath(), fileName);
+ assertThat(pidFile.createNewFile()).isTrue();
+
+ // write PID to PID file
+ try (FileWriter fileWriter = new FileWriter(pidFile, false)) {
+ fileWriter.write(getPidOrOne().toString() + "\n");
+ fileWriter.flush();
+ }
+ assertThat(pidFile.isFile()).isTrue();
+
+ String command = new CommandStringBuilder(START_SERVER)
+ .addOption(START_SERVER__NAME, memberName)
+ .addOption(START_SERVER__LOCATORS, locatorConnectionString)
+ .addOption(START_SERVER__SERVER_PORT, serverPort.toString())
+ .addOption(START_SERVER__DIR, pidFile.getParentFile().getCanonicalPath())
+ .addOption(START_SERVER__FORCE, "true")
+ .getCommandString();
+
+ CommandResult result = gfsh.executeCommand(command);
+
+ final String expectedMessage = "Server in " + pidFile.getParentFile().getCanonicalPath();
+
+ assertThat(result.getStatus()).isEqualTo(Result.Status.OK);
+ assertThat(result.getMessageFromContent()).contains(expectedMessage);
+ }
+
+ @Test
+ public void testWithConnectionToLocator() throws IOException {
+ final Integer serverPort = AvailablePortHelper.getRandomAvailableTCPPort();
+ final String memberName = "testWithConnectionToLocator-server";
+ final String expectedVersionPattern = "Geode Version: \\d+\\.\\d+\\.\\d+";
+ final String expectedMessage = "Server in " + workingDir.getCanonicalPath();
+
+ String command = new CommandStringBuilder(START_SERVER)
+ .addOption(START_SERVER__NAME, memberName)
+ .addOption(START_SERVER__LOCATORS, locatorConnectionString)
+ .addOption(START_SERVER__DIR, workingDir.getCanonicalPath())
+ .addOption(START_SERVER__SERVER_PORT, serverPort.toString())
+ .getCommandString();
+
+ CommandResult result = gfsh.executeCommand(command);
+
+ assertThat(result.getStatus()).isEqualTo(Result.Status.OK);
+ assertThat(result.getMessageFromContent()).contains(expectedMessage);
+
+ // verify GEODE-2138 (Geode commands do not contain GemFire in output)
+ assertThat(result.getMessageFromContent()).doesNotContain("Gemfire")
+ .doesNotContain("GemFire");
+ assertThat(result.getMessageFromContent()).containsPattern(expectedVersionPattern);
+ }
+
+ @Test
+ public void testServerJVMTerminatesOnOutOfMemoryError() throws IOException {
+ final Integer serverPort = AvailablePortHelper.getRandomAvailableTCPPort();
+ final String memberName = "testServerJVMTerminatesOnOutOfMemoryError-server";
+ final String groupName = "serverGroup";
+ final String regionName = "testRegion";
+
+ MemberVM server = cluster.startServerVM(1, locator.getPort());
+
+ String command = new CommandStringBuilder(START_SERVER)
+ .addOption(START_SERVER__NAME, memberName)
+ .addOption("group", groupName)
+ .addOption(START_SERVER__LOCATORS, locatorConnectionString)
+ .addOption(START_SERVER__OFF_HEAP_MEMORY_SIZE, "0M")
+ .addOption(START_SERVER__MAXHEAP, "300M")
+ .addOption(START_SERVER__SERVER_PORT, serverPort.toString())
+ .addOption(START_SERVER__DIR, workingDir.getCanonicalPath())
+ .getCommandString();
+
+ CommandResult result = gfsh.executeCommand(command);
+ assertThat(result.getStatus()).isEqualTo(Result.Status.OK);
+
+ command = new CommandStringBuilder(CREATE_REGION)
+ .addOption(CREATE_REGION__REGIONSHORTCUT, "PARTITION")
+ .addOption(GROUP, groupName)
+ .addOption(CREATE_REGION__REGION, regionName)
+ .getCommandString();
+
+ gfsh.executeAndAssertThat(command).statusIsSuccess();
+
+ ServerLauncher serverLauncher = new ServerLauncher.Builder()
+ .setCommand(ServerLauncher.Command.STATUS)
+ .setWorkingDirectory(workingDir.getCanonicalPath())
+ .build();
+ assertThat(serverLauncher).isNotNull();
+
+ ServerLauncher.ServerState serverState = serverLauncher.status();
+ assertThat(serverState.getStatus()).isEqualTo(AbstractLauncher.Status.ONLINE);
+ assertThat(serverState.isVmWithProcessIdRunning()).isTrue();
+
+ Integer serverPid = serverState.getPid();
+ assertThat(ProcessUtils.isProcessAlive(serverPid)).isTrue();
+
+ final String jarName = "RunOutOfMemory.jar";
+ File jar = temporaryFolder.newFile(jarName);
+ new ClassBuilder().writeJarFromClass(new RunOutOfMemoryFunction().getClass(), jar);
+ gfsh.executeAndAssertThat("deploy --groups=" + groupName + " --jar=" + jar).statusIsSuccess();
+
+ locator.invoke((() -> {
+ try {
+ FunctionService.onMember(groupName).execute(new RunOutOfMemoryFunction()).getResult();
+ } catch (FunctionException e) {
+ e.printStackTrace();
+ }
+ }));
+
+ gfsh.executeAndAssertThat("list members").statusIsSuccess().doesNotContainOutput(memberName)
+ .containsOutput(server.getName());
+
+ server.stop(Boolean.TRUE);
+
+ assertThat(ProcessUtils.isProcessAlive(serverPid)).isFalse();
+ }
+
+ private void deleteServerFiles(File toDelete) {
+ File[] nestedToDelete = toDelete.listFiles();
+
+ if (nestedToDelete != null && nestedToDelete.length > 0) {
+ for (File file : nestedToDelete) {
+ deleteServerFiles(file);
+ }
+ }
+
+ toDelete.delete();
+ }
+
+ /**
+ * Attempts to determine the PID of the running process from the ManagementFactory's runtime MBean
+ *
+ * @return 1 if unable to determine the pid
+ * @return the PID if possible
+ */
+ private Integer getPidOrOne() {
+ Integer pid = 1;
+ String[] name = ManagementFactory.getRuntimeMXBean().getName().split("@");
+ if (name.length > 1) {
+ try {
+ pid = Integer.parseInt(name[0]);
+ } catch (NumberFormatException nex) {
+ // Ignored
+ }
+ }
+
+ return pid;
+ }
+
+}
diff --git a/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/StatusLocatorCommandDunitTest.java b/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/StatusLocatorCommandDunitTest.java
index 8249f28..30004f8 100644
--- a/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/StatusLocatorCommandDunitTest.java
+++ b/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/StatusLocatorCommandDunitTest.java
@@ -15,9 +15,6 @@
package org.apache.geode.management.internal.cli.commands;
import static java.util.concurrent.TimeUnit.SECONDS;
-import static org.apache.geode.internal.i18n.LocalizedStrings.Launcher_Builder_UNKNOWN_HOST_ERROR_MESSAGE;
-import static org.apache.geode.internal.i18n.LocalizedStrings.Launcher_Builder_WORKING_DIRECTORY_NOT_FOUND_ERROR_MESSAGE;
-import static org.apache.geode.management.internal.cli.i18n.CliStrings.LOCATOR_TERM_NAME;
import static org.apache.geode.management.internal.cli.i18n.CliStrings.STATUS_LOCATOR;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.SoftAssertions.assertSoftly;
@@ -35,7 +32,6 @@ import org.junit.rules.TemporaryFolder;
import org.apache.geode.distributed.LocatorLauncher;
import org.apache.geode.distributed.LocatorLauncher.LocatorState;
import org.apache.geode.management.cli.Result;
-import org.apache.geode.management.internal.cli.i18n.CliStrings;
import org.apache.geode.management.internal.cli.result.CommandResult;
import org.apache.geode.test.junit.rules.GfshCommandRule;
import org.apache.geode.test.junit.rules.GfshCommandRule.PortType;
@@ -69,21 +65,6 @@ public class StatusLocatorCommandDunitTest {
}
@Test
- public void testWithDisconnectedGfsh() throws Exception {
- final String expectedResult =
- CliStrings.format(CliStrings.STATUS_SERVICE__GFSH_NOT_CONNECTED_ERROR_MESSAGE,
- LOCATOR_TERM_NAME);
-
- if (gfsh.isConnected()) {
- gfsh.disconnect();
- }
-
- gfsh.executeAndAssertThat(STATUS_LOCATOR + " --name=" + locatorName)
- .statusIsError()
- .containsOutput(expectedResult);
- }
-
- @Test
public void testWithMemberAddress() throws Exception {
gfsh.connectAndVerify(locator.getPort(), PortType.locator);
@@ -97,20 +78,6 @@ public class StatusLocatorCommandDunitTest {
}
@Test
- public void testWithInvalidMemberAddress() throws Exception {
- final String expectedError =
- Launcher_Builder_UNKNOWN_HOST_ERROR_MESSAGE.toString(LOCATOR_TERM_NAME);
-
- gfsh.connectAndVerify(locator.getPort(), PortType.locator);
-
- CommandResult result =
- gfsh.executeCommand(STATUS_LOCATOR + " --host=invalidHostName --port=" + locator.getPort());
-
- assertThat(result.getStatus()).isEqualTo(Result.Status.ERROR);
- assertThat(result.getMessageFromContent()).contains(expectedError);
- }
-
- @Test
public void testWithMemberName() throws Exception {
gfsh.connectAndVerify(locator.getPort(), PortType.locator);
@@ -123,19 +90,6 @@ public class StatusLocatorCommandDunitTest {
}
@Test
- public void testWithInvalidMemberName() throws Exception {
- final String expectedError = CliStrings.format(
- CliStrings.STATUS_LOCATOR__NO_LOCATOR_FOUND_FOR_MEMBER_ERROR_MESSAGE, "invalidLocatorName");
-
- gfsh.connectAndVerify(locator.getPort(), PortType.locator);
-
- CommandResult result = gfsh.executeCommand(STATUS_LOCATOR + " --name=invalidLocatorName");
-
- assertThat(result.getStatus()).isEqualTo(Result.Status.ERROR);
- assertThat(result.getMessageFromContent()).contains(expectedError);
- }
-
- @Test
public void testWithMemberID() throws Exception {
gfsh.connectAndVerify(locator.getPort(), PortType.locator);
@@ -148,21 +102,6 @@ public class StatusLocatorCommandDunitTest {
}
@Test
- public void testWithInvalidMemberID() throws Exception {
- final String expectedError =
- CliStrings.format(CliStrings.STATUS_LOCATOR__NO_LOCATOR_FOUND_FOR_MEMBER_ERROR_MESSAGE,
- locator.getMemberId() + "1");
-
- gfsh.connectAndVerify(locator.getPort(), PortType.locator);
-
- CommandResult result =
- gfsh.executeCommand(STATUS_LOCATOR + " --name=" + locator.getMemberId() + "1");
-
- assertThat(result.getStatus()).isEqualTo(Result.Status.ERROR);
- assertThat(result.getMessageFromContent()).contains(expectedError);
- }
-
- @Test
public void testWithDirOnline() throws Exception {
gfsh.connectAndVerify(locator.getPort(), PortType.locator);
@@ -190,34 +129,6 @@ public class StatusLocatorCommandDunitTest {
assertStatusCommandOutput(result.getMessageFromContent(), state);
}
- @Test
- public void testWithInvalidDirOnline() throws Exception {
- final String expectedError =
- Launcher_Builder_WORKING_DIRECTORY_NOT_FOUND_ERROR_MESSAGE.toString(LOCATOR_TERM_NAME);
-
- gfsh.connectAndVerify(locator.getPort(), PortType.locator);
-
- CommandResult result = gfsh.executeCommand(STATUS_LOCATOR + " --dir=/invalid/working/dir");
-
- assertThat(result.getStatus()).isEqualTo(Result.Status.ERROR);
- assertThat(result.getMessageFromContent()).contains(expectedError);
- }
-
- @Test
- public void testWithInvalidDirOffline() throws Exception {
- final String expectedError =
- Launcher_Builder_WORKING_DIRECTORY_NOT_FOUND_ERROR_MESSAGE.toString(LOCATOR_TERM_NAME);
-
- if (gfsh.isConnected()) {
- gfsh.disconnect();
- }
-
- CommandResult result = gfsh.executeCommand(STATUS_LOCATOR + " --dir=/invalid/working/dir");
-
- assertThat(result.getStatus()).isEqualTo(Result.Status.ERROR);
- assertThat(result.getMessageFromContent()).contains(expectedError);
- }
-
public void assertStatusCommandOutput(String locatorStatusCommandMessage, LocatorState state) {
assertSoftly(softly -> {
softly.assertThat(locatorStatusCommandMessage)
diff --git a/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/StopLocatorCommandDUnitTest.java b/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/StopLocatorCommandDUnitTest.java
new file mode 100644
index 0000000..5903796
--- /dev/null
+++ b/geode-assembly/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/StopLocatorCommandDUnitTest.java
@@ -0,0 +1,262 @@
+/*
+ * 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.internal.DistributionConfig.GEMFIRE_PREFIX;
+import static org.apache.geode.management.cli.Result.Status.ERROR;
+import static org.apache.geode.management.cli.Result.Status.OK;
+import static org.apache.geode.management.internal.cli.i18n.CliStrings.GROUP;
+import static org.apache.geode.management.internal.cli.i18n.CliStrings.START_LOCATOR;
+import static org.apache.geode.management.internal.cli.i18n.CliStrings.START_LOCATOR__DIR;
+import static org.apache.geode.management.internal.cli.i18n.CliStrings.START_LOCATOR__J;
+import static org.apache.geode.management.internal.cli.i18n.CliStrings.START_LOCATOR__LOCATORS;
+import static org.apache.geode.management.internal.cli.i18n.CliStrings.START_LOCATOR__MEMBER_NAME;
+import static org.apache.geode.management.internal.cli.i18n.CliStrings.START_LOCATOR__PORT;
+import static org.apache.geode.management.internal.cli.i18n.CliStrings.STOP_LOCATOR;
+import static org.apache.geode.management.internal.cli.i18n.CliStrings.STOP_LOCATOR__DIR;
+import static org.apache.geode.management.internal.cli.i18n.CliStrings.STOP_LOCATOR__MEMBER;
+import static org.apache.geode.management.internal.cli.i18n.CliStrings.STOP_SERVICE__GFSH_NOT_CONNECTED_ERROR_MESSAGE;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Properties;
+import java.util.Set;
+
+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.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+import org.apache.geode.distributed.ConfigurationProperties;
+import org.apache.geode.internal.AvailablePortHelper;
+import org.apache.geode.internal.lang.ObjectUtils;
+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.rules.ClusterStartupRule;
+import org.apache.geode.test.dunit.rules.MemberVM;
+import org.apache.geode.test.junit.rules.GfshCommandRule;
+
+public class StopLocatorCommandDUnitTest {
+ private static MemberVM locator;
+ private static final String memberName = "locatorToStop";
+ private static final String groupName = "locatorGroup";
+ private static String locatorConnectionString;
+ private File workingDir;
+ private static Integer locatorPort, jmxPort, toStopJmxPort;
+
+ @Rule
+ public final TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+ @ClassRule
+ public static final GfshCommandRule gfsh = new GfshCommandRule();
+
+ @ClassRule
+ public static final ClusterStartupRule cluster = new ClusterStartupRule();
+
+ @BeforeClass
+ public static void beforeClass() throws Exception {
+ jmxPort = AvailablePortHelper.getRandomAvailableTCPPort();
+
+ Properties props = new Properties();
+ props.setProperty(ConfigurationProperties.JMX_MANAGER_PORT, jmxPort.toString());
+ props.setProperty(ConfigurationProperties.JMX_MANAGER_HOSTNAME_FOR_CLIENTS, "localhost");
+
+ locator = cluster.startLocatorVM(0, props);
+
+ locatorConnectionString = "localhost[" + locator.getPort() + "]";
+
+ gfsh.connectAndVerify(locator);
+ }
+
+ @AfterClass
+ public static void afterClass() throws Exception {
+ gfsh.connectAndVerify(locator);
+ gfsh.executeAndAssertThat("shutdown --include-locators").statusIsSuccess();
+ }
+
+ @Before
+ public void before() throws Exception {
+ workingDir = temporaryFolder.newFolder();
+ int[] availablePorts = AvailablePortHelper.getRandomAvailableTCPPorts(2);
+ locatorPort = availablePorts[0];
+ toStopJmxPort = availablePorts[1];
+
+ final String command = new CommandStringBuilder(START_LOCATOR)
+ .addOption(START_LOCATOR__MEMBER_NAME, memberName)
+ .addOption(START_LOCATOR__LOCATORS, locatorConnectionString)
+ .addOption(START_LOCATOR__PORT, locatorPort.toString())
+ .addOption(GROUP, groupName)
+ .addOption(START_LOCATOR__J,
+ "-D" + GEMFIRE_PREFIX + "jmx-manager-port=" + toStopJmxPort.toString())
+ .addOption(START_LOCATOR__J,
+ "-D" + GEMFIRE_PREFIX + "jmx-manager-hostname-for-clients=localhost")
+ .addOption(START_LOCATOR__DIR, workingDir.getCanonicalPath())
+ .getCommandString();
+
+ gfsh.connectAndVerify(locator);
+ gfsh.executeCommand(command);
+ }
+
+ @After
+ public void after() throws IOException {
+ gfsh.executeCommand("stop locator --dir=" + workingDir.getCanonicalPath());
+ }
+
+ @Test
+ public void testWithDisconnectedGfsh() throws Exception {
+ final String expectedError = CliStrings.format(STOP_SERVICE__GFSH_NOT_CONNECTED_ERROR_MESSAGE,
+ CliStrings.LOCATOR_TERM_NAME);
+ final String command = new CommandStringBuilder(STOP_LOCATOR)
+ .addOption(STOP_LOCATOR__MEMBER, memberName)
+ .getCommandString();
+
+ if (gfsh.isConnected()) {
+ gfsh.disconnect();
+ }
+
+ CommandResult result = gfsh.executeCommand(command);
+
+ gfsh.connectAndVerify(locator);
+
+ assertThat(result.getStatus()).isEqualTo(ERROR);
+ assertThat(result.getMessageFromContent()).contains(expectedError);
+ }
+
+ @Test
+ public void testWithMemberName() {
+ final String command = new CommandStringBuilder(STOP_LOCATOR)
+ .addOption(STOP_LOCATOR__MEMBER, memberName)
+ .getCommandString();
+
+ CommandResult result = gfsh.executeCommand(command);
+
+ assertThat(result.getStatus()).isEqualTo(OK);
+ gfsh.executeAndAssertThat("list members").doesNotContainOutput(memberName);
+ }
+
+ @Test
+ public void testWithMemberID() {
+ int port = jmxPort; // this assignment is needed to pass a local var into the invocation below
+ final String memberID = locator.invoke(() -> getMemberId(port));
+
+ final String command = new CommandStringBuilder(STOP_LOCATOR)
+ .addOption(STOP_LOCATOR__MEMBER, memberID)
+ .getCommandString();
+
+ CommandResult result = gfsh.executeCommand(command);
+
+ assertThat(result.getStatus()).isEqualTo(OK);
+ gfsh.executeAndAssertThat("list members").doesNotContainOutput(memberName);
+ }
+
+ @Test
+ public void testWithDirOnline() throws IOException {
+ final String command = new CommandStringBuilder(STOP_LOCATOR)
+ .addOption(STOP_LOCATOR__DIR, workingDir.getCanonicalPath())
+ .getCommandString();
+
+ CommandResult result = gfsh.executeCommand(command);
+
+ assertThat(result.getStatus()).isEqualTo(OK);
+ gfsh.executeAndAssertThat("list members").doesNotContainOutput(memberName);
+ }
+
+ @Test
+ public void testWithDirOffline() throws Exception {
+ if (gfsh.isConnected()) {
+ gfsh.disconnect();
+ }
+
+ final String command = new CommandStringBuilder(STOP_LOCATOR)
+ .addOption(STOP_LOCATOR__DIR, workingDir.getCanonicalPath())
+ .getCommandString();
+
+ CommandResult result = gfsh.executeCommand(command);
+
+ gfsh.connect(locator);
+
+ assertThat(result.getStatus()).isEqualTo(OK);
+ gfsh.executeAndAssertThat("list members").doesNotContainOutput(memberName);
+ }
+
+ @Test
+ public void testWithInvalidMemberName() {
+ final String command = new CommandStringBuilder(STOP_LOCATOR)
+ .addOption(STOP_LOCATOR__MEMBER, "invalidMemberName")
+ .getCommandString();
+
+ CommandResult result = gfsh.executeCommand(command);
+
+ assertThat(result.getStatus()).isEqualTo(ERROR);
+ gfsh.executeAndAssertThat("list members").containsOutput(memberName);
+ }
+
+ @Test
+ public void testWithInvalidMemberID() {
+ final String command = new CommandStringBuilder(STOP_LOCATOR)
+ .addOption(STOP_LOCATOR__MEMBER, "42")
+ .getCommandString();
+
+ CommandResult result = gfsh.executeCommand(command);
+
+ assertThat(result.getStatus()).isEqualTo(ERROR);
+ gfsh.executeAndAssertThat("list members").containsOutput(memberName);
+ }
+
+ protected static String getMemberId(int port) throws Exception {
+ JMXConnector conn = null;
+
+ try {
+ final ObjectName objectNamePattern = ObjectName.getInstance("GemFire:type=Member,*");
+ final QueryExp query = Query.eq(Query.attr("Name"), Query.value(memberName));
+ final JMXServiceURL url =
+ new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:" + port + "/jmxrmi");
+ System.out.println(url.toString());
+
+ assertThat(url).isNotNull();
+ conn = JMXConnectorFactory.connect(url);
+ assertThat(conn).isInstanceOf(JMXConnector.class);
+
+ final MBeanServerConnection connection = conn.getMBeanServerConnection();
+ assertThat(connection).isInstanceOf(MBeanServerConnection.class);
+
+ final Set<ObjectName> objectNames = connection.queryNames(objectNamePattern, query);
+ assertThat(objectNames).isNotNull().isNotEmpty().hasSize(1);
+
+ final ObjectName objectName = objectNames.iterator().next();
+ final Object memberId = connection.getAttribute(objectName, "Id");
+
+ return ObjectUtils.toString(memberId);
+ } finally {
+ if (conn != null) {
+ conn.close();
+ }
+ }
+ }
+}
diff --git a/geode-junit/src/main/java/org/apache/geode/test/compiler/ClassBuilder.java b/geode-junit/src/main/java/org/apache/geode/test/compiler/ClassBuilder.java
index 58167ae..846abb7 100644
--- a/geode-junit/src/main/java/org/apache/geode/test/compiler/ClassBuilder.java
+++ b/geode-junit/src/main/java/org/apache/geode/test/compiler/ClassBuilder.java
@@ -18,6 +18,7 @@ import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.net.URI;
@@ -37,6 +38,8 @@ import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.ToolProvider;
+import org.apache.commons.io.IOUtils;
+
/**
* Test framework utility class to programmatically create classes, JARs and ClassLoaders that
* include the classes.
@@ -137,6 +140,15 @@ public class ClassBuilder implements Serializable {
*/
public void writeJarFromContent(final String className, final String content,
final OutputStream outStream) throws IOException {
+
+ byte[] bytes = compileClass(className, content);
+
+ createJar(className, outStream, bytes);
+ return;
+ }
+
+ private void createJar(String className, OutputStream outStream, byte[] bytes)
+ throws IOException {
JarOutputStream jarOutputStream = new JarOutputStream(outStream);
// Add the class file to the JAR file
@@ -148,12 +160,23 @@ public class ClassBuilder implements Serializable {
JarEntry entry = new JarEntry(formattedName);
entry.setTime(System.currentTimeMillis());
jarOutputStream.putNextEntry(entry);
- jarOutputStream.write(compileClass(className, content));
+ jarOutputStream.write(bytes);
jarOutputStream.closeEntry();
jarOutputStream.close();
}
+ public void writeJarFromClass(Class clazz, File jar) throws IOException {
+ String className = clazz.getName();
+ String classAsPath = className.replace('.', '/') + ".class";
+ InputStream stream = clazz.getClassLoader().getResourceAsStream(classAsPath);
+ byte[] bytes = IOUtils.toByteArray(stream);
+ try (FileOutputStream out = new FileOutputStream(jar)) {
+ createJar(classAsPath, out, bytes);
+ }
+
+ }
+
/**
* Creates a ClassLoader that contains an empty class with the given name using the given content.
* The className may have a package separated by /. For example: my/package/myclass
diff --git a/geode-junit/src/main/java/org/apache/geode/test/compiler/TestObject.java b/geode-junit/src/main/java/org/apache/geode/test/compiler/TestObject.java
new file mode 100644
index 0000000..5b01479
--- /dev/null
+++ b/geode-junit/src/main/java/org/apache/geode/test/compiler/TestObject.java
@@ -0,0 +1,21 @@
+/*
+ * 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.test.compiler;
+
+public class TestObject {
+ public void forClassBuilderTest() {
+ // this class is just for testing purposes
+ }
+}
diff --git a/geode-junit/src/test/java/org/apache/geode/test/compiler/ClassBuilderTest.java b/geode-junit/src/test/java/org/apache/geode/test/compiler/ClassBuilderTest.java
new file mode 100644
index 0000000..dbc70b7
--- /dev/null
+++ b/geode-junit/src/test/java/org/apache/geode/test/compiler/ClassBuilderTest.java
@@ -0,0 +1,62 @@
+/*
+ * 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.test.compiler;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLClassLoader;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+public class ClassBuilderTest {
+ @Rule
+ public TemporaryFolder tmpFolder = new TemporaryFolder();
+
+ @Test
+ public void writeJarFromClass() throws IOException, ClassNotFoundException {
+ File jar = tmpFolder.newFile("test.jar");
+ URL[] url = new URL[] {jar.toURI().toURL()};
+ ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
+
+ URLClassLoader classLoader = new URLClassLoader(url, systemClassLoader) {
+ @Override
+ public Class<?> loadClass(String name) throws ClassNotFoundException {
+ try {
+ return findClass(name);
+ } catch (ClassNotFoundException e) {
+ if (name.equals(Object.class.getName())) {
+ return super.loadClass(name);
+ }
+ }
+ return null;
+ }
+ };
+
+ // write class to jar
+ new ClassBuilder().writeJarFromClass(TestObject.class, jar);
+
+ // load class from the jar
+ Class clazz = classLoader.loadClass(TestObject.class.getName());
+
+ assertNotEquals(clazz, null);
+ assertEquals(clazz.getClassLoader(), classLoader);
+ }
+}