You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by nn...@apache.org on 2020/07/09 18:59:52 UTC
[geode] 07/13: GEODE-7667: Add a 'clear' gfsh command for PR and RR
clear (#4818)
This is an automated email from the ASF dual-hosted git repository.
nnag pushed a commit to branch feature/GEODE-7665
in repository https://gitbox.apache.org/repos/asf/geode.git
commit 9bf176cc7822f7328fef80e9f0797293d6f4e98e
Author: BenjaminPerryRoss <39...@users.noreply.github.com>
AuthorDate: Tue May 5 11:40:34 2020 -0700
GEODE-7667: Add a 'clear' gfsh command for PR and RR clear (#4818)
* Added clear command and modified remove functionality to clear PR
Authored-by: Benjamin Ross <br...@pivotal.io>
---
.../geode/management/internal/i18n/CliStrings.java | 14 ++-
.../cli/commands/ClearCommandDUnitTest.java | 120 +++++++++++++++++++++
.../cli/commands/RemoveCommandDUnitTest.java | 13 ++-
.../{RemoveCommand.java => ClearCommand.java} | 53 ++++-----
.../cli/commands/CommandAvailabilityIndicator.java | 1 +
.../internal/cli/commands/RemoveCommand.java | 9 +-
.../internal/cli/domain/DataCommandResult.java | 12 +++
.../cli/functions/DataCommandFunction.java | 23 ++--
.../internal/cli/commands/ClearCommandTest.java | 115 ++++++++++++++++++++
9 files changed, 309 insertions(+), 51 deletions(-)
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/i18n/CliStrings.java b/geode-core/src/main/java/org/apache/geode/management/internal/i18n/CliStrings.java
index c354d030..6df013e 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/i18n/CliStrings.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/i18n/CliStrings.java
@@ -811,6 +811,14 @@ public class CliStrings {
public static final String CLEAR_DEFINED_INDEX__SUCCESS__MSG =
"Index definitions successfully cleared";
+ /* clear region */
+ public static final String CLEAR_REGION = "clear region";
+ public static final String CLEAR_REGION_HELP =
+ "Clears/Removes all keys from the specified region.";
+ public static final String CLEAR_REGION_REGION_NAME = "name";
+ public static final String CLEAR_REGION_REGION_NAME_HELP = "Region to clear keys from.";
+ public static final String CLEAR_REGION_CLEARED_ALL_KEYS = "Cleared all keys in the region";
+
/* create region */
public static final String CREATE_REGION = "create region";
public static final String CREATE_REGION__HELP =
@@ -1930,9 +1938,9 @@ public class CliStrings {
public static final String REMOVE__MSG__KEY_EMPTY = "Key is Null";
public static final String REMOVE__MSG__REGION_NOT_FOUND = "Region <{0}> Not Found";
public static final String REMOVE__MSG__KEY_NOT_FOUND_REGION = "Key is not present in the region";
- public static final String REMOVE__MSG__CLEARED_ALL_CLEARS = "Cleared all keys in the region";
- public static final String REMOVE__MSG__CLEARALL_NOT_SUPPORTED_FOR_PARTITIONREGION =
- "Option --" + REMOVE__ALL + " is not supported on partitioned region";
+ public static final String REMOVE__MSG__CLEARALL_DEPRECATION_WARNING =
+ "Warning: The --all option for the 'remove' command is deprecated. Please"
+ + " use the 'clear' command instead.";
/* resume gateway-sender */
public static final String RESUME_GATEWAYSENDER = "resume gateway-sender";
diff --git a/geode-gfsh/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/ClearCommandDUnitTest.java b/geode-gfsh/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/ClearCommandDUnitTest.java
new file mode 100644
index 0000000..e51fc0f
--- /dev/null
+++ b/geode-gfsh/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/ClearCommandDUnitTest.java
@@ -0,0 +1,120 @@
+/*
+ * 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.commands.RemoveCommand.REGION_NOT_FOUND;
+import static org.apache.geode.management.internal.i18n.CliStrings.CLEAR_REGION_CLEARED_ALL_KEYS;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import junitparams.JUnitParamsRunner;
+import junitparams.Parameters;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.apache.geode.cache.Cache;
+import org.apache.geode.cache.CacheFactory;
+import org.apache.geode.cache.Region;
+import org.apache.geode.management.internal.cli.util.CommandStringBuilder;
+import org.apache.geode.management.internal.i18n.CliStrings;
+import org.apache.geode.test.dunit.rules.ClusterStartupRule;
+import org.apache.geode.test.dunit.rules.MemberVM;
+import org.apache.geode.test.junit.rules.GfshCommandRule;
+import org.apache.geode.test.junit.rules.VMProvider;
+
+@RunWith(JUnitParamsRunner.class)
+public class ClearCommandDUnitTest {
+ private static final String REPLICATE_REGION_NAME = "replicateRegion";
+ private static final String PARTITIONED_REGION_NAME = "partitionedRegion";
+ private static final String EMPTY_STRING = "";
+ private static final int NUM_ENTRIES = 200;
+
+ @Rule
+ public ClusterStartupRule clusterStartupRule = new ClusterStartupRule();
+
+ @Rule
+ public GfshCommandRule gfsh = new GfshCommandRule();
+
+ private MemberVM locator;
+ private MemberVM server1;
+ private MemberVM server2;
+
+ @Before
+ public void setup() throws Exception {
+ locator = clusterStartupRule.startLocatorVM(0);
+ server1 = clusterStartupRule.startServerVM(1, locator.getPort());
+ server2 = clusterStartupRule.startServerVM(2, locator.getPort());
+
+ gfsh.connectAndVerify(locator);
+ gfsh.executeAndAssertThat("create region --name=" + REPLICATE_REGION_NAME + " --type=REPLICATE")
+ .statusIsSuccess();
+ gfsh.executeAndAssertThat(
+ "create region --name=" + PARTITIONED_REGION_NAME + " --type=PARTITION").statusIsSuccess();
+
+ locator.waitUntilRegionIsReadyOnExactlyThisManyServers("/" + REPLICATE_REGION_NAME, 2);
+ locator.waitUntilRegionIsReadyOnExactlyThisManyServers("/" + PARTITIONED_REGION_NAME, 2);
+
+ VMProvider.invokeInEveryMember(ClearCommandDUnitTest::populateTestRegions, server1, server2);
+ }
+
+ private static void populateTestRegions() {
+ Cache cache = CacheFactory.getAnyInstance();
+
+ Region<String, String> replicateRegion = cache.getRegion(REPLICATE_REGION_NAME);
+ replicateRegion.put(EMPTY_STRING, "valueForEmptyKey");
+ for (int i = 0; i < NUM_ENTRIES; i++) {
+ replicateRegion.put("key" + i, "value" + i);
+ }
+
+ Region<String, String> partitionedRegion = cache.getRegion(PARTITIONED_REGION_NAME);
+ replicateRegion.put(EMPTY_STRING, "valueForEmptyKey");
+ for (int i = 0; i < NUM_ENTRIES; i++) {
+ partitionedRegion.put("key" + i, "value" + i);
+ }
+ }
+
+ @Test
+ public void clearFailsWhenRegionIsNotFound() {
+ String invalidRegionName = "NotAValidRegion";
+ String command = new CommandStringBuilder(CliStrings.CLEAR_REGION)
+ .addOption(CliStrings.CLEAR_REGION_REGION_NAME, invalidRegionName).getCommandString();
+ gfsh.executeAndAssertThat(command).statusIsError()
+ .containsOutput(String.format(REGION_NOT_FOUND, "/" + invalidRegionName));
+ }
+
+ @Test
+ @Parameters({REPLICATE_REGION_NAME, PARTITIONED_REGION_NAME})
+ public void clearSucceedsWithValidRegion(String regionName) {
+ String command = new CommandStringBuilder(CliStrings.CLEAR_REGION)
+ .addOption(CliStrings.CLEAR_REGION_REGION_NAME, regionName).getCommandString();
+
+ gfsh.executeAndAssertThat(command).statusIsSuccess();
+
+ assertThat(gfsh.getGfshOutput()).contains(CLEAR_REGION_CLEARED_ALL_KEYS);
+
+ server1.invoke(() -> verifyAllKeysAreRemoved(regionName));
+ server2.invoke(() -> verifyAllKeysAreRemoved(regionName));
+ }
+
+ private static void verifyAllKeysAreRemoved(String regionName) {
+ Region region = getRegion(regionName);
+ assertThat(region.size()).isEqualTo(0);
+ }
+
+ private static Region getRegion(String regionName) {
+ return CacheFactory.getAnyInstance().getRegion(regionName);
+ }
+}
diff --git a/geode-gfsh/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/RemoveCommandDUnitTest.java b/geode-gfsh/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/RemoveCommandDUnitTest.java
index 92a65ec..2a88d64 100644
--- a/geode-gfsh/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/RemoveCommandDUnitTest.java
+++ b/geode-gfsh/src/distributedTest/java/org/apache/geode/management/internal/cli/commands/RemoveCommandDUnitTest.java
@@ -16,6 +16,7 @@ package org.apache.geode.management.internal.cli.commands;
import static org.apache.geode.cache.Region.SEPARATOR;
import static org.apache.geode.management.internal.cli.commands.RemoveCommand.REGION_NOT_FOUND;
+import static org.apache.geode.management.internal.i18n.CliStrings.CLEAR_REGION_CLEARED_ALL_KEYS;
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.Before;
@@ -25,6 +26,7 @@ import org.junit.Test;
import org.apache.geode.cache.Cache;
import org.apache.geode.cache.CacheFactory;
import org.apache.geode.cache.Region;
+import org.apache.geode.management.internal.i18n.CliStrings;
import org.apache.geode.test.dunit.rules.ClusterStartupRule;
import org.apache.geode.test.dunit.rules.MemberVM;
import org.apache.geode.test.junit.rules.GfshCommandRule;
@@ -128,7 +130,8 @@ public class RemoveCommandDUnitTest {
gfsh.executeAndAssertThat("list regions").statusIsSuccess();
gfsh.executeAndAssertThat(command).statusIsSuccess();
- assertThat(gfsh.getGfshOutput()).contains("Cleared all keys in the region");
+ assertThat(gfsh.getGfshOutput()).contains(CLEAR_REGION_CLEARED_ALL_KEYS)
+ .contains(CliStrings.REMOVE__MSG__CLEARALL_DEPRECATION_WARNING);
server1.invoke(() -> verifyAllKeysAreRemoved(REPLICATE_REGION_NAME));
server2.invoke(() -> verifyAllKeysAreRemoved(REPLICATE_REGION_NAME));
@@ -139,11 +142,13 @@ public class RemoveCommandDUnitTest {
public void removeAllFromPartitionedRegion() {
String command = "remove --all --region=" + PARTITIONED_REGION_NAME;
- // Maybe this should return an "error" status, but the current behavior is status "OK"
gfsh.executeAndAssertThat(command).statusIsSuccess();
- assertThat(gfsh.getGfshOutput())
- .contains("Option --all is not supported on partitioned region");
+ assertThat(gfsh.getGfshOutput()).contains(CLEAR_REGION_CLEARED_ALL_KEYS)
+ .contains(CliStrings.REMOVE__MSG__CLEARALL_DEPRECATION_WARNING);;
+
+ server1.invoke(() -> verifyAllKeysAreRemoved(PARTITIONED_REGION_NAME));
+ server2.invoke(() -> verifyAllKeysAreRemoved(PARTITIONED_REGION_NAME));
}
/**
diff --git a/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/commands/RemoveCommand.java b/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/commands/ClearCommand.java
similarity index 63%
copy from geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/commands/RemoveCommand.java
copy to geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/commands/ClearCommand.java
index c15f01f..75ac720 100644
--- a/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/commands/RemoveCommand.java
+++ b/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/commands/ClearCommand.java
@@ -38,59 +38,52 @@ import org.apache.geode.management.internal.i18n.CliStrings;
import org.apache.geode.security.ResourcePermission.Operation;
import org.apache.geode.security.ResourcePermission.Resource;
-public class RemoveCommand extends GfshCommand {
+public class ClearCommand extends GfshCommand {
public static final String REGION_NOT_FOUND = "Region <%s> not found in any of the members";
@CliMetaData(relatedTopic = {CliStrings.TOPIC_GEODE_DATA, CliStrings.TOPIC_GEODE_REGION})
- @CliCommand(value = {CliStrings.REMOVE}, help = CliStrings.REMOVE__HELP)
- public ResultModel remove(
- @CliOption(key = {CliStrings.REMOVE__KEY}, help = CliStrings.REMOVE__KEY__HELP,
- specifiedDefaultValue = "") String key,
- @CliOption(key = {CliStrings.REMOVE__REGION}, mandatory = true,
- help = CliStrings.REMOVE__REGION__HELP,
- optionContext = ConverterHint.REGION_PATH) String regionPath,
- @CliOption(key = CliStrings.REMOVE__ALL, help = CliStrings.REMOVE__ALL__HELP,
- specifiedDefaultValue = "true", unspecifiedDefaultValue = "false") boolean removeAllKeys,
- @CliOption(key = {CliStrings.REMOVE__KEYCLASS},
- help = CliStrings.REMOVE__KEYCLASS__HELP) String keyClass) {
- Cache cache = getCache();
+ @CliCommand(value = {CliStrings.CLEAR_REGION}, help = CliStrings.CLEAR_REGION_HELP)
+ public ResultModel clear(
+ @CliOption(key = {CliStrings.CLEAR_REGION_REGION_NAME}, mandatory = true,
+ help = CliStrings.CLEAR_REGION_REGION_NAME_HELP,
+ optionContext = ConverterHint.REGION_PATH) String regionPath) {
- if (!removeAllKeys && (key == null)) {
- return new ResultModel().createError(CliStrings.REMOVE__MSG__KEY_EMPTY);
- }
+ Cache cache = getCache();
- if (removeAllKeys) {
- authorize(Resource.DATA, Operation.WRITE, regionPath);
- } else {
- authorize(Resource.DATA, Operation.WRITE, regionPath, key);
- }
+ authorize(Resource.DATA, Operation.WRITE, regionPath);
- key = DataCommandsUtils.makeBrokenJsonCompliant(key);
Region region = cache.getRegion(regionPath);
- DataCommandFunction removefn = new DataCommandFunction();
+ DataCommandFunction clearfn = createCommandFunction();
DataCommandResult dataResult;
if (region == null) {
Set<DistributedMember> memberList = findAnyMembersForRegion(regionPath);
if (CollectionUtils.isEmpty(memberList)) {
- return new ResultModel().createError(String.format(REGION_NOT_FOUND, regionPath));
+ return ResultModel.createError(String.format(REGION_NOT_FOUND, regionPath));
}
DataCommandRequest request = new DataCommandRequest();
request.setCommand(CliStrings.REMOVE);
- request.setKey(key);
- request.setKeyClass(keyClass);
- request.setRemoveAllKeys(removeAllKeys ? "ALL" : null);
+ request.setRemoveAllKeys("ALL");
request.setRegionName(regionPath);
- dataResult = callFunctionForRegion(request, removefn, memberList);
+ dataResult = callFunctionForRegion(request, clearfn, memberList);
} else {
- dataResult = removefn.remove(key, keyClass, regionPath, removeAllKeys ? "ALL" : null,
+ dataResult = clearfn.remove(null, null, regionPath, "ALL",
(InternalCache) cache);
}
- dataResult.setKeyClass(keyClass);
+ dataResult.setKeyClass(null);
return dataResult.toResultModel();
}
+
+ DataCommandResult callFunctionForRegion(DataCommandRequest request, DataCommandFunction clearfn,
+ Set<DistributedMember> memberList) {
+ return DataCommandsUtils.callFunctionForRegion(request, clearfn, memberList);
+ }
+
+ DataCommandFunction createCommandFunction() {
+ return new DataCommandFunction();
+ }
}
diff --git a/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/commands/CommandAvailabilityIndicator.java b/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/commands/CommandAvailabilityIndicator.java
index ae0b7c4..50f811d 100644
--- a/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/commands/CommandAvailabilityIndicator.java
+++ b/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/commands/CommandAvailabilityIndicator.java
@@ -26,6 +26,7 @@ public class CommandAvailabilityIndicator extends GfshCommand {
CliStrings.DESCRIBE_CONFIG, CliStrings.EXPORT_CONFIG, CliStrings.ALTER_RUNTIME_CONFIG,
CliStrings.ALTER_REGION, CliStrings.CREATE_REGION, CliStrings.DESTROY_REGION,
CliStrings.REBALANCE, CliStrings.GET, CliStrings.PUT, CliStrings.REMOVE,
+ CliStrings.CLEAR_REGION,
CliStrings.LOCATE_ENTRY, CliStrings.QUERY, CliStrings.IMPORT_DATA, CliStrings.EXPORT_DATA,
CliStrings.DEPLOY, CliStrings.UNDEPLOY, CliStrings.LIST_DEPLOYED,
CliStrings.BACKUP_DISK_STORE, CliStrings.COMPACT_DISK_STORE, CliStrings.DESCRIBE_DISK_STORE,
diff --git a/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/commands/RemoveCommand.java b/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/commands/RemoveCommand.java
index c15f01f..062428d 100644
--- a/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/commands/RemoveCommand.java
+++ b/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/commands/RemoveCommand.java
@@ -90,7 +90,14 @@ public class RemoveCommand extends GfshCommand {
}
dataResult.setKeyClass(keyClass);
+ ResultModel result;
- return dataResult.toResultModel();
+ if (removeAllKeys) {
+ result = dataResult.toResultModel(CliStrings.REMOVE__MSG__CLEARALL_DEPRECATION_WARNING);
+ } else {
+ result = dataResult.toResultModel();
+ }
+
+ return result;
}
}
diff --git a/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/domain/DataCommandResult.java b/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/domain/DataCommandResult.java
index 3f00a95..6bc91cb 100644
--- a/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/domain/DataCommandResult.java
+++ b/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/domain/DataCommandResult.java
@@ -33,6 +33,7 @@ import org.apache.geode.cache.query.internal.Undefined;
import org.apache.geode.management.cli.Result;
import org.apache.geode.management.internal.cli.GfshParser;
import org.apache.geode.management.internal.cli.result.model.DataResultModel;
+import org.apache.geode.management.internal.cli.result.model.InfoResultModel;
import org.apache.geode.management.internal.cli.result.model.ResultModel;
import org.apache.geode.management.internal.cli.result.model.TabularResultModel;
import org.apache.geode.management.internal.i18n.CliStrings;
@@ -49,6 +50,7 @@ public class DataCommandResult implements Serializable {
public static final Logger logger = LogManager.getLogger();
public static final String DATA_INFO_SECTION = "data-info";
+ public static final String WARNING_INFO_SECTION = "header-info";
public static final String QUERY_SECTION = "query";
public static final String LOCATION_SECTION = "location";
private String command;
@@ -372,6 +374,10 @@ public class DataCommandResult implements Serializable {
}
public ResultModel toResultModel() {
+ return toResultModel("");
+ }
+
+ public ResultModel toResultModel(String warningMessage) {
if (StringUtils.isEmpty(keyClass)) {
keyClass = "java.lang.String";
}
@@ -381,6 +387,12 @@ public class DataCommandResult implements Serializable {
}
ResultModel result = new ResultModel();
+
+ if (warningMessage != null && !warningMessage.isEmpty()) {
+ InfoResultModel info = result.addInfo(WARNING_INFO_SECTION);
+ info.addLine(warningMessage);
+ }
+
DataResultModel data = result.addData(DATA_INFO_SECTION);
if (errorString != null) {
diff --git a/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/functions/DataCommandFunction.java b/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/functions/DataCommandFunction.java
index 17cf20f..44c84b5 100644
--- a/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/functions/DataCommandFunction.java
+++ b/geode-gfsh/src/main/java/org/apache/geode/management/internal/cli/functions/DataCommandFunction.java
@@ -29,7 +29,6 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.Logger;
-import org.apache.geode.cache.DataPolicy;
import org.apache.geode.cache.Region;
import org.apache.geode.cache.execute.FunctionContext;
import org.apache.geode.cache.partition.PartitionRegionHelper;
@@ -315,22 +314,20 @@ public class DataCommandFunction implements InternalFunction<DataCommandRequest>
CliStrings.REMOVE__MSG__KEY_NOT_FOUND_REGION, false);
}
} else {
- DataPolicy policy = region.getAttributes().getDataPolicy();
- if (!policy.withPartitioning()) {
- region.clear();
- if (logger.isDebugEnabled()) {
- logger.debug("Cleared all keys in the region - {}", regionName);
- }
- return DataCommandResult.createRemoveInfoResult(key, null, null,
- CliStrings.format(CliStrings.REMOVE__MSG__CLEARED_ALL_CLEARS, regionName), true);
- } else {
- return DataCommandResult.createRemoveInfoResult(key, null, null,
- CliStrings.REMOVE__MSG__CLEARALL_NOT_SUPPORTED_FOR_PARTITIONREGION, false);
- }
+ return clear(region, regionName);
}
}
}
+ public DataCommandResult clear(Region region, String regionName) {
+ region.clear();
+ if (logger.isDebugEnabled()) {
+ logger.debug("Cleared all keys in the region - {}", regionName);
+ }
+ return DataCommandResult.createRemoveInfoResult(null, null, null,
+ CliStrings.format(CliStrings.CLEAR_REGION_CLEARED_ALL_KEYS, regionName), true);
+ }
+
@SuppressWarnings({"rawtypes"})
public DataCommandResult get(Object principal, String key, String keyClass, String valueClass,
String regionName, Boolean loadOnCacheMiss, InternalCache cache) {
diff --git a/geode-gfsh/src/test/java/org/apache/geode/management/internal/cli/commands/ClearCommandTest.java b/geode-gfsh/src/test/java/org/apache/geode/management/internal/cli/commands/ClearCommandTest.java
new file mode 100644
index 0000000..a716ef5
--- /dev/null
+++ b/geode-gfsh/src/test/java/org/apache/geode/management/internal/cli/commands/ClearCommandTest.java
@@ -0,0 +1,115 @@
+/*
+ * 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.commands.ClearCommand.REGION_NOT_FOUND;
+import static org.apache.geode.management.internal.i18n.CliStrings.CLEAR_REGION;
+import static org.apache.geode.management.internal.i18n.CliStrings.CLEAR_REGION_REGION_NAME;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+import org.apache.geode.cache.Region;
+import org.apache.geode.distributed.DistributedMember;
+import org.apache.geode.internal.cache.InternalCache;
+import org.apache.geode.management.internal.cli.domain.DataCommandResult;
+import org.apache.geode.management.internal.cli.functions.DataCommandFunction;
+import org.apache.geode.management.internal.cli.result.model.ResultModel;
+import org.apache.geode.test.junit.rules.GfshParserRule;
+
+public class ClearCommandTest {
+
+ @ClassRule
+ public static GfshParserRule gfsh = new GfshParserRule();
+
+ static final String regionName = "regionName";
+ static final String success = "SUCCESS";
+
+ InternalCache cache;
+ ClearCommand command;
+ Region<Object, Object> region;
+ Set<DistributedMember> membersList;
+ DistributedMember member;
+ DataCommandResult dataResult;
+
+ @SuppressWarnings("unchecked")
+ @Before
+ public void setup() {
+ cache = mock(InternalCache.class);
+ command = spy(new ClearCommand());
+ region = mock(Region.class);
+ dataResult = mock(DataCommandResult.class);
+
+ membersList = new HashSet<>();
+ membersList.add(member);
+
+ doNothing().when(command).authorize(any(), any(), anyString());
+ doReturn(cache).when(command).getCache();
+ doReturn(membersList).when(command).findAnyMembersForRegion(anyString());
+
+ ResultModel result = ResultModel.createInfo(success);
+ doReturn(result).when(dataResult).toResultModel();
+ }
+
+ @Test
+ public void commandReturnsErrorIfRegionIsNotFound() {
+ membersList.clear();
+
+ gfsh.executeAndAssertThat(command,
+ CLEAR_REGION + " --" + CLEAR_REGION_REGION_NAME + "=/" + regionName)
+ .statusIsError().containsOutput(String.format(REGION_NOT_FOUND, "/" + regionName));
+ }
+
+ @Test
+ public void commandReturnsSuccessfullyIfRegionIsFoundOnServersButNotLocator() {
+ doReturn(dataResult).when(command).callFunctionForRegion(any(), any(), any());
+
+ gfsh.executeAndAssertThat(command,
+ CLEAR_REGION + " --" + CLEAR_REGION_REGION_NAME + "=/" + regionName)
+ .statusIsSuccess().containsOutput(success);
+
+ verify(command).callFunctionForRegion(any(), any(), any());
+ }
+
+ @Test
+ public void commandReturnsSuccessfullyIfRegionIsFoundOnLocator() {
+ DataCommandFunction dataCommandFunction = mock(DataCommandFunction.class);
+ doReturn(dataCommandFunction).when(command).createCommandFunction();
+ when(cache.getRegion("/" + regionName)).thenReturn(region);
+
+ doReturn(dataResult).when(dataCommandFunction)
+ .remove(null, null, "/" + regionName, "ALL", cache);
+
+ gfsh.executeAndAssertThat(command,
+ CLEAR_REGION + " --" + CLEAR_REGION_REGION_NAME + "=/" + regionName)
+ .statusIsSuccess().containsOutput(success);
+
+ verify(dataCommandFunction).remove(null, null, "/" + regionName,
+ "ALL", cache);
+ }
+}