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 ca62b21  GEODE-4110: extend LocatorServerStartupRule to start a client 
VM. (#1175)
ca62b21 is described below

commit ca62b211aa809ef4d86db754af2f83acdd68391b
Author: jinmeiliao <jil...@pivotal.io>
AuthorDate: Wed Dec 20 09:20:01 2017 -0800

    GEODE-4110: extend LocatorServerStartupRule to start a client VM. (#1175)
    
    * created a new ClientCacheRule to create a client cache in current VM.
    * have lcoatorserverStartupRule to use that rule to start up a client VM.
---
 .../geode/cache/client/ClientCacheFactory.java     |   3 +-
 .../CreateDefinedIndexesCommandDUnitTest.java      |  15 ++-
 .../commands/DeployCommandRedeployDUnitTest.java   |   2 +-
 .../commands/DestroyRegionCommandDUnitTest.java    |   7 +-
 .../cli/commands/DiskStoreCommandsDUnitTest.java   |  20 ++-
 .../ImportClusterConfigDistributedTest.java        |   4 +-
 .../internal/security/MultiClientDUnitTest.java    | 110 +++++-----------
 .../apache/geode/security/ClientAuthDUnitTest.java |  31 ++---
 .../ClientDestroyInvalidateAuthDUnitTest.java      |  44 +++----
 .../apache/geode/test/dunit/rules/ClientVM.java    |  32 +++++
 .../test/dunit/rules/LocatorServerStartupRule.java | 144 +++++++++++----------
 .../apache/geode/test/dunit/rules/MemberVM.java    |  33 ++---
 .../geode/test/junit/rules/ClientCacheRule.java    |  70 ++++++++++
 .../apache/geode/test/junit/rules/VMProvider.java  |  55 ++++++++
 ...CreateDestroyGatewaySenderCommandDUnitTest.java |  27 ++--
 .../CreateGatewayReceiverCommandDUnitTest.java     |  39 +++---
 16 files changed, 368 insertions(+), 268 deletions(-)

diff --git 
a/geode-core/src/main/java/org/apache/geode/cache/client/ClientCacheFactory.java
 
b/geode-core/src/main/java/org/apache/geode/cache/client/ClientCacheFactory.java
index f6edc3e..5666cf7 100644
--- 
a/geode-core/src/main/java/org/apache/geode/cache/client/ClientCacheFactory.java
+++ 
b/geode-core/src/main/java/org/apache/geode/cache/client/ClientCacheFactory.java
@@ -14,7 +14,8 @@
  */
 package org.apache.geode.cache.client;
 
-import static org.apache.geode.distributed.ConfigurationProperties.*;
+import static org.apache.geode.distributed.ConfigurationProperties.LOCATORS;
+import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT;
 
 import java.util.Properties;
 
diff --git 
a/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/CreateDefinedIndexesCommandDUnitTest.java
 
b/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/CreateDefinedIndexesCommandDUnitTest.java
index 4206597..5262e79 100644
--- 
a/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/CreateDefinedIndexesCommandDUnitTest.java
+++ 
b/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/CreateDefinedIndexesCommandDUnitTest.java
@@ -36,6 +36,7 @@ import 
org.apache.geode.test.dunit.rules.LocatorServerStartupRule;
 import org.apache.geode.test.dunit.rules.MemberVM;
 import org.apache.geode.test.junit.categories.DistributedTest;
 import org.apache.geode.test.junit.rules.GfshCommandRule;
+import org.apache.geode.test.junit.rules.VMProvider;
 import org.apache.geode.test.junit.rules.serializable.SerializableTestName;
 
 @Category(DistributedTest.class)
@@ -78,7 +79,7 @@ public class CreateDefinedIndexesCommandDUnitTest {
   public void nonexistentRegion() {
     String regionName = testName.getMethodName();
 
-    MemberVM.invokeInEveryMember(() -> {
+    VMProvider.invokeInEveryMember(() -> {
       Cache cache = LocatorServerStartupRule.getCache();
       assertThat(cache.getRegion(regionName)).isNull();
     }, server1, server2, server3);
@@ -90,7 +91,7 @@ public class CreateDefinedIndexesCommandDUnitTest {
     gfsh.executeAndAssertThat("create defined indexes").statusIsError()
         .containsOutput("RegionNotFoundException");
 
-    MemberVM.invokeInEveryMember(() -> {
+    VMProvider.invokeInEveryMember(() -> {
       Cache cache = LocatorServerStartupRule.getCache();
       QueryService queryService = cache.getQueryService();
 
@@ -115,7 +116,7 @@ public class CreateDefinedIndexesCommandDUnitTest {
         .containsOutput("Region \"/" + region2Name + "\" created on 
\"server-2\"")
         .containsOutput("Region \"/" + region2Name + "\" created on 
\"server-3\"");
 
-    MemberVM.invokeInEveryMember(() -> {
+    VMProvider.invokeInEveryMember(() -> {
       Cache cache = LocatorServerStartupRule.getCache();
       assertThat(cache.getRegion(region1Name)).isNotNull();
       assertThat(cache.getRegion(region2Name)).isNotNull();
@@ -132,7 +133,7 @@ public class CreateDefinedIndexesCommandDUnitTest {
     gfsh.executeAndAssertThat("create defined indexes").statusIsSuccess()
         .containsOutput("Indexes successfully created");
 
-    MemberVM.invokeInEveryMember(() -> {
+    VMProvider.invokeInEveryMember(() -> {
       Cache cache = LocatorServerStartupRule.getCache();
       QueryService queryService = cache.getQueryService();
       Region region1 = cache.getRegion(region1Name);
@@ -171,13 +172,13 @@ public class CreateDefinedIndexesCommandDUnitTest {
         .statusIsSuccess()
         .containsOutput("Region \"/" + region2Name + "\" created on 
\"server-3\"");
 
-    MemberVM.invokeInEveryMember(() -> {
+    VMProvider.invokeInEveryMember(() -> {
       Cache cache = LocatorServerStartupRule.getCache();
       assertThat(cache.getRegion(region1Name)).isNull();
       assertThat(cache.getRegion(region2Name)).isNull();
     }, server1, server2);
 
-    MemberVM.invokeInEveryMember(() -> {
+    VMProvider.invokeInEveryMember(() -> {
       Cache cache = LocatorServerStartupRule.getCache();
       assertThat(cache.getRegion(region1Name)).isNotNull();
       assertThat(cache.getRegion(region2Name)).isNotNull();
@@ -194,7 +195,7 @@ public class CreateDefinedIndexesCommandDUnitTest {
     gfsh.executeAndAssertThat("create defined indexes 
--group=group1").statusIsSuccess()
         .containsOutput("Indexes successfully created");
 
-    MemberVM.invokeInEveryMember(() -> {
+    VMProvider.invokeInEveryMember(() -> {
       Cache cache = LocatorServerStartupRule.getCache();
       QueryService queryService = cache.getQueryService();
       Region region1 = cache.getRegion(region1Name);
diff --git 
a/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/DeployCommandRedeployDUnitTest.java
 
b/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/DeployCommandRedeployDUnitTest.java
index 4ce7323..45e832f 100644
--- 
a/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/DeployCommandRedeployDUnitTest.java
+++ 
b/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/DeployCommandRedeployDUnitTest.java
@@ -136,7 +136,7 @@ public class DeployCommandRedeployDUnitTest {
     server.invoke(() -> assertThatCanLoad(JAR_NAME_A, FUNCTION_A));
     server.invoke(() -> assertThatFunctionHasVersion(FUNCTION_A, VERSION2));
 
-    server.stopMember(false);
+    server.stopVM(false);
 
     lsRule.startServerVM(1, locator.getPort());
 
diff --git 
a/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/DestroyRegionCommandDUnitTest.java
 
b/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/DestroyRegionCommandDUnitTest.java
index 55dbff3..58b9d56 100644
--- 
a/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/DestroyRegionCommandDUnitTest.java
+++ 
b/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/DestroyRegionCommandDUnitTest.java
@@ -35,6 +35,7 @@ import 
org.apache.geode.test.dunit.rules.LocatorServerStartupRule;
 import org.apache.geode.test.dunit.rules.MemberVM;
 import org.apache.geode.test.junit.categories.DistributedTest;
 import org.apache.geode.test.junit.rules.GfshCommandRule;
+import org.apache.geode.test.junit.rules.VMProvider;
 
 @Category(DistributedTest.class)
 public class DestroyRegionCommandDUnitTest {
@@ -95,7 +96,7 @@ public class DestroyRegionCommandDUnitTest {
     gfsh.executeAndAssertThat("destroy region 
--name=region1").statusIsSuccess()
         .tableHasRowCount("Member", 3).containsOutput("destroyed 
successfully");
 
-    MemberVM.invokeInEveryMember(() -> {
+    VMProvider.invokeInEveryMember(() -> {
       Cache cache = LocatorServerStartupRule.getCache();
       assertThat(cache.getRegion("region1")).isNull();
     }, server1, server2, server3);
@@ -136,7 +137,7 @@ public class DestroyRegionCommandDUnitTest {
     });
 
     // verify that all regions are destroyed, no matter what the scope is
-    MemberVM.invokeInEveryMember(() -> {
+    VMProvider.invokeInEveryMember(() -> {
       Cache cache = LocatorServerStartupRule.getCache();
       assertThat(cache.getRegion("region1")).isNull();
     }, server1, server2, server3);
@@ -171,7 +172,7 @@ public class DestroyRegionCommandDUnitTest {
     lsRule.startServerVM(1, locator.getPort());
 
     // make sure region does not exist
-    MemberVM.invokeInEveryMember(() -> {
+    VMProvider.invokeInEveryMember(() -> {
       Cache cache = LocatorServerStartupRule.getCache();
       assertThat(cache.getRegion("Customer")).isNull();
     }, server1, server2, server3);
diff --git 
a/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/DiskStoreCommandsDUnitTest.java
 
b/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/DiskStoreCommandsDUnitTest.java
index 1695caa..9345b08 100644
--- 
a/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/DiskStoreCommandsDUnitTest.java
+++ 
b/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/DiskStoreCommandsDUnitTest.java
@@ -32,7 +32,6 @@ import org.junit.rules.TemporaryFolder;
 
 import org.apache.geode.cache.Cache;
 import org.apache.geode.cache.Region;
-import org.apache.geode.compression.SnappyCompressor;
 import org.apache.geode.distributed.Locator;
 import org.apache.geode.distributed.internal.ClusterConfigurationService;
 import org.apache.geode.distributed.internal.InternalLocator;
@@ -41,6 +40,7 @@ import 
org.apache.geode.test.dunit.rules.LocatorServerStartupRule;
 import org.apache.geode.test.dunit.rules.MemberVM;
 import org.apache.geode.test.junit.categories.DistributedTest;
 import org.apache.geode.test.junit.rules.GfshCommandRule;
+import org.apache.geode.test.junit.rules.ServerStarterRule;
 
 @Category(DistributedTest.class)
 public class DiskStoreCommandsDUnitTest {
@@ -96,7 +96,7 @@ public class DiskStoreCommandsDUnitTest {
     gfsh.executeAndAssertThat("show missing-disk-stores")
         .containsOutput("No missing disk store found");
 
-    server1.invoke(LocatorServerStartupRule::stopMemberInThisVM);
+    server1.stopVM(false);
 
     server2.invoke(() -> {
       Cache cache = LocatorServerStartupRule.getCache();
@@ -104,10 +104,16 @@ public class DiskStoreCommandsDUnitTest {
       r.put("A", "C");
     });
 
-    server2.invoke(LocatorServerStartupRule::stopMemberInThisVM);
+    server2.stopVM(false);
 
-    props.setProperty("log-file", "");
-    rule.startServerVMAsync(server1.getVM().getId(), props, locator.getPort());
+    int locatorPort = locator.getPort();
+    server1.invokeAsync(() -> {
+      // trying to restart the server asynchronously
+      ServerStarterRule serverRule = new 
ServerStarterRule().withProperties(props)
+          
.withName("server-1").withConnectionToLocator(locatorPort).withAutoStart();
+      LocatorServerStartupRule.memberStarter = serverRule;
+      serverRule.before();
+    });
 
     locator.waitTillDiskstoreIsReady(DISKSTORE, 1);
 
@@ -148,7 +154,7 @@ public class DiskStoreCommandsDUnitTest {
     gfsh.executeAndAssertThat("show missing-disk-stores")
         .containsOutput("No missing disk store found");
 
-    server1.invoke(LocatorServerStartupRule::stopMemberInThisVM);
+    server1.stopVM(false);
 
     String diskDirs = new File(server1.getWorkingDir(), 
DISKSTORE).getAbsolutePath();
     gfsh.executeAndAssertThat(
@@ -176,7 +182,7 @@ public class DiskStoreCommandsDUnitTest {
     gfsh.executeAndAssertThat("show missing-disk-stores")
         .containsOutput("No missing disk store found");
 
-    server1.invoke(LocatorServerStartupRule::stopMemberInThisVM);
+    server1.stopVM(false);
 
     String diskDirs = new File(server1.getWorkingDir(), 
DISKSTORE).getAbsolutePath();
     File exportDir = tempDir.newFolder();
diff --git 
a/geode-core/src/test/java/org/apache/geode/management/internal/configuration/ImportClusterConfigDistributedTest.java
 
b/geode-core/src/test/java/org/apache/geode/management/internal/configuration/ImportClusterConfigDistributedTest.java
index 11795f7..70c08a1 100644
--- 
a/geode-core/src/test/java/org/apache/geode/management/internal/configuration/ImportClusterConfigDistributedTest.java
+++ 
b/geode-core/src/test/java/org/apache/geode/management/internal/configuration/ImportClusterConfigDistributedTest.java
@@ -75,8 +75,8 @@ public class ImportClusterConfigDistributedTest {
         .statusIsSuccess();
 
     gfsh.disconnect();
-    locator.stopMember(true);
-    server.stopMember(true);
+    locator.stopVM(true);
+    server.stopVM(true);
 
     assertThat(this.exportedClusterConfig).exists();
     assertThat(this.exportedClusterConfig.length()).isGreaterThan(100);
diff --git 
a/geode-core/src/test/java/org/apache/geode/management/internal/security/MultiClientDUnitTest.java
 
b/geode-core/src/test/java/org/apache/geode/management/internal/security/MultiClientDUnitTest.java
index 46deac1..25ac551 100644
--- 
a/geode-core/src/test/java/org/apache/geode/management/internal/security/MultiClientDUnitTest.java
+++ 
b/geode-core/src/test/java/org/apache/geode/management/internal/security/MultiClientDUnitTest.java
@@ -15,9 +15,6 @@
 
 package org.apache.geode.management.internal.security;
 
-import static org.apache.geode.distributed.ConfigurationProperties.LOCATORS;
-import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT;
-import static 
org.apache.geode.distributed.ConfigurationProperties.SECURITY_CLIENT_AUTH_INIT;
 import static 
org.apache.geode.distributed.ConfigurationProperties.SECURITY_MANAGER;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
@@ -35,29 +32,27 @@ import org.apache.geode.cache.Cache;
 import org.apache.geode.cache.Region;
 import org.apache.geode.cache.RegionShortcut;
 import org.apache.geode.cache.client.ClientCache;
-import org.apache.geode.cache.client.ClientCacheFactory;
 import org.apache.geode.cache.client.ClientRegionShortcut;
 import org.apache.geode.cache.client.ServerOperationException;
 import org.apache.geode.examples.SimpleSecurityManager;
-import org.apache.geode.security.templates.UserPasswordAuthInit;
+import org.apache.geode.security.AuthenticationFailedException;
 import org.apache.geode.test.dunit.AsyncInvocation;
 import org.apache.geode.test.dunit.IgnoredException;
-import org.apache.geode.test.dunit.VM;
+import org.apache.geode.test.dunit.rules.ClientVM;
 import org.apache.geode.test.dunit.rules.LocatorServerStartupRule;
 import org.apache.geode.test.dunit.rules.MemberVM;
 import org.apache.geode.test.junit.categories.DistributedTest;
+import org.apache.geode.test.junit.rules.VMProvider;
 
 @Category(DistributedTest.class)
 public class MultiClientDUnitTest {
-
-  private static int SESSION_COUNT = 2;
   private static int KEY_COUNT = 20;
 
   @ClassRule
   public static LocatorServerStartupRule lsRule = new 
LocatorServerStartupRule();
 
   private static MemberVM locator, server1, server2;
-  private static VM client3, client4, client5, client6;
+  private static ClientVM client3, client4, client5, client6;
 
   @BeforeClass
   public static void beforeClass() throws Exception {
@@ -72,78 +67,60 @@ public class MultiClientDUnitTest {
     server1 = lsRule.startServerVM(1, serverProps, locator.getPort());
     server2 = lsRule.startServerVM(2, serverProps, locator.getPort());
 
-    MemberVM.invokeInEveryMember(() -> {
+    VMProvider.invokeInEveryMember(() -> {
       Cache cache = LocatorServerStartupRule.getCache();
       cache.createRegionFactory(RegionShortcut.PARTITION).create("region");
     }, server1, server2);
 
-    client3 = lsRule.getVM(3);
-    client4 = lsRule.getVM(4);
-    client5 = lsRule.getVM(5);
-    client6 = lsRule.getVM(6);
+    client3 = lsRule.startClientVM(3, "data", "data", false, 
server1.getPort(), server2.getPort());
+    client4 = lsRule.startClientVM(4, "stranger", "stranger", false, 
server1.getPort(),
+        server2.getPort());
+    client5 = lsRule.startClientVM(5, "data", "data", false, 
server1.getPort(), server2.getPort());
+    client6 = lsRule.startClientVM(6, "dataWithWrongPswd", "data", false, 
server1.getPort(),
+        server2.getPort());
   }
 
   @Test
   public void multiClient() throws ExecutionException, InterruptedException, 
TimeoutException {
-    int locatorPort = locator.getPort();
-    int server1Port = server1.getPort();
-    int server2Port = server2.getPort();
-
 
     // client 3 keeps logging in, do some successful put, and log out and keep 
doing it for multiple
     // times
     AsyncInvocation vm3Invoke = client3.invokeAsync("run as data", () -> {
-      for (int i = 0; i < SESSION_COUNT; i++) {
-        ClientCache cache = createClientCache("data", "data", server1Port, 
server2Port);
-        Region region =
-            
cache.createClientRegionFactory(ClientRegionShortcut.PROXY).create("region");
-        for (int j = 0; j < KEY_COUNT; j++) {
-          region.put(i + "" + j, i + "" + j);
-        }
-        cache.close();
+      ClientCache cache = LocatorServerStartupRule.getClientCache();
+      Region region = 
cache.createClientRegionFactory(ClientRegionShortcut.PROXY).create("region");
+      for (int j = 0; j < KEY_COUNT; j++) {
+        region.put(j + "", j + "");
       }
     });
 
     // client 4 keeps logging in, do an unauthorized put, and log out
     AsyncInvocation vm4Invoke = client4.invokeAsync("run as stranger", () -> {
-      for (int i = 0; i < SESSION_COUNT; i++) {
-        ClientCache cache = createClientCache("stranger", "stranger", 
server1Port, server2Port);
-        Region region =
-            
cache.createClientRegionFactory(ClientRegionShortcut.PROXY).create("region");
-        for (int j = 0; j < KEY_COUNT; j++) {
-          String value = i + "" + j;
-          assertThatThrownBy(() -> region.put(value, value))
-              .isInstanceOf(ServerOperationException.class);
-        }
-        cache.close();
+      ClientCache cache = LocatorServerStartupRule.getClientCache();
+      Region region = 
cache.createClientRegionFactory(ClientRegionShortcut.PROXY).create("region");
+      for (int j = 0; j < KEY_COUNT; j++) {
+        String value = "" + j;
+        assertThatThrownBy(() -> region.put(value, value))
+            .isInstanceOf(ServerOperationException.class);
       }
     });
 
     // client 5 keeps logging in, do some successful get, and log out
     AsyncInvocation vm5Invoke = client5.invokeAsync("run as data", () -> {
-      for (int i = 0; i < SESSION_COUNT; i++) {
-        ClientCache cache = createClientCache("data", "data", server1Port, 
server2Port);
-        Region region =
-            
cache.createClientRegionFactory(ClientRegionShortcut.PROXY).create("region");
-        for (int j = 0; j < KEY_COUNT; j++) {
-          region.get(i + "" + j);
-        }
-        cache.close();
+      ClientCache cache = LocatorServerStartupRule.getClientCache();
+      Region region = 
cache.createClientRegionFactory(ClientRegionShortcut.PROXY).create("region");
+      for (int j = 0; j < KEY_COUNT; j++) {
+        region.get("" + j);
       }
     });
 
     // // client 6 keeps logging in with incorrect
     AsyncInvocation vm6Invoke = client6.invokeAsync("run as invalid user", () 
-> {
-      for (int i = 0; i < SESSION_COUNT; i++) {
-        ClientCache cache =
-            createClientCache("dataWithWrongPswd", "password", server1Port, 
server2Port);
-        Region region =
-            
cache.createClientRegionFactory(ClientRegionShortcut.PROXY).create("region");
-        for (int j = 0; j < 1; j++) {
-          String key = i + "" + j;
-          assertThatThrownBy(() -> 
region.get(key)).isInstanceOf(ServerOperationException.class);
-        }
-        cache.close();
+      ClientCache cache = LocatorServerStartupRule.getClientCache();
+      Region region = 
cache.createClientRegionFactory(ClientRegionShortcut.PROXY).create("region");
+      for (int j = 0; j < 1; j++) {
+        String key = "" + j;
+        assertThatThrownBy(() -> 
region.get(key)).isInstanceOf(ServerOperationException.class)
+            .hasRootCauseInstanceOf(AuthenticationFailedException.class);
       }
     });
 
@@ -152,29 +129,4 @@ public class MultiClientDUnitTest {
     vm5Invoke.await(60, TimeUnit.MINUTES);
     vm6Invoke.await(60, TimeUnit.MINUTES);
   }
-
-  private static ClientCache createClientCache(String username, String 
password, int locatorPort) {
-    ClientCache cache = new 
ClientCacheFactory(getClientCacheProperties(username, password))
-        .setPoolSubscriptionEnabled(false).addPoolLocator("localhost", 
locatorPort).create();
-    return cache;
-  }
-
-  private static ClientCache createClientCache(String username, String 
password, int server1Port,
-      int server2Port) {
-    ClientCache cache = new 
ClientCacheFactory(getClientCacheProperties(username, password))
-        .setPoolSubscriptionEnabled(false).addPoolServer("localhost", 
server1Port)
-        .addPoolServer("localhost", server2Port).create();
-    return cache;
-  }
-
-  private static Properties getClientCacheProperties(String username, String 
password) {
-    Properties props = new Properties();
-    props.setProperty(UserPasswordAuthInit.USER_NAME, username);
-    props.setProperty(UserPasswordAuthInit.PASSWORD, password);
-    props.setProperty(SECURITY_CLIENT_AUTH_INIT, 
UserPasswordAuthInit.class.getName());
-    props.setProperty(LOCATORS, "");
-    props.setProperty(MCAST_PORT, "0");
-    return props;
-  }
-
 }
diff --git 
a/geode-core/src/test/java/org/apache/geode/security/ClientAuthDUnitTest.java 
b/geode-core/src/test/java/org/apache/geode/security/ClientAuthDUnitTest.java
index 0035750..30c813e 100644
--- 
a/geode-core/src/test/java/org/apache/geode/security/ClientAuthDUnitTest.java
+++ 
b/geode-core/src/test/java/org/apache/geode/security/ClientAuthDUnitTest.java
@@ -21,41 +21,32 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
-import org.apache.geode.test.dunit.Host;
 import org.apache.geode.test.dunit.IgnoredException;
-import org.apache.geode.test.dunit.VM;
-import org.apache.geode.test.dunit.internal.JUnit4DistributedTestCase;
+import org.apache.geode.test.dunit.rules.LocatorServerStartupRule;
 import org.apache.geode.test.junit.categories.DistributedTest;
-import org.apache.geode.test.junit.categories.FlakyTest;
 import org.apache.geode.test.junit.categories.SecurityTest;
 import org.apache.geode.test.junit.rules.ServerStarterRule;
 
 @Category({DistributedTest.class, SecurityTest.class})
-public class ClientAuthDUnitTest extends JUnit4DistributedTestCase {
-
-  final Host host = Host.getHost(0);
-  final VM client1 = host.getVM(1);
-  final VM client2 = host.getVM(2);
+public class ClientAuthDUnitTest {
+  @Rule
+  public LocatorServerStartupRule lsRule = new LocatorServerStartupRule();
 
   @Rule
   public ServerStarterRule server = new ServerStarterRule()
       .withProperty(SECURITY_MANAGER, 
SimpleTestSecurityManager.class.getName()).withAutoStart();
 
-  @Category(FlakyTest.class) // GEODE-3692 - Intermittent test failure on 
nightly builds
   @Test
-  public void authWithCorrectPasswordShouldPass() {
-    client1.invoke("logging in super-user with correct password", () -> {
-      SecurityTestUtil.createClientCache("test", "test", server.getPort());
-    });
+  public void authWithCorrectPasswordShouldPass() throws Exception {
+    lsRule.startClientVM(0, "test", "test", true, server.getPort());
   }
 
   @Test
-  public void authWithIncorrectPasswordShouldFail() {
+  public void authWithIncorrectPasswordShouldFail() throws Exception {
     
IgnoredException.addIgnoredException(AuthenticationFailedException.class.getName());
-    client2.invoke("logging in super-user with wrong password", () -> {
-      assertThatThrownBy(
-          () -> SecurityTestUtil.createClientCache("test", "wrong", 
server.getPort()))
-              .isInstanceOf(AuthenticationFailedException.class);
-    });
+
+    assertThatThrownBy(
+        () -> lsRule.startClientVM(0, "test", "invalidPassword", true, 
server.getPort()))
+            .isInstanceOf(AuthenticationFailedException.class);
   }
 }
diff --git 
a/geode-core/src/test/java/org/apache/geode/security/ClientDestroyInvalidateAuthDUnitTest.java
 
b/geode-core/src/test/java/org/apache/geode/security/ClientDestroyInvalidateAuthDUnitTest.java
index e83aa4a..107ac05 100644
--- 
a/geode-core/src/test/java/org/apache/geode/security/ClientDestroyInvalidateAuthDUnitTest.java
+++ 
b/geode-core/src/test/java/org/apache/geode/security/ClientDestroyInvalidateAuthDUnitTest.java
@@ -15,7 +15,10 @@
 package org.apache.geode.security;
 
 import static 
org.apache.geode.distributed.ConfigurationProperties.SECURITY_MANAGER;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
 
 import org.junit.Before;
 import org.junit.Rule;
@@ -26,28 +29,23 @@ import org.apache.geode.cache.Region;
 import org.apache.geode.cache.RegionShortcut;
 import org.apache.geode.cache.client.ClientCache;
 import org.apache.geode.cache.client.ClientRegionShortcut;
-import org.apache.geode.test.dunit.AsyncInvocation;
-import org.apache.geode.test.dunit.Host;
-import org.apache.geode.test.dunit.VM;
-import org.apache.geode.test.dunit.internal.JUnit4DistributedTestCase;
+import org.apache.geode.test.dunit.rules.ClientVM;
+import org.apache.geode.test.dunit.rules.LocatorServerStartupRule;
 import org.apache.geode.test.junit.categories.DistributedTest;
 import org.apache.geode.test.junit.categories.SecurityTest;
 import org.apache.geode.test.junit.rules.ServerStarterRule;
 
 @Category({DistributedTest.class, SecurityTest.class})
-public class ClientDestroyInvalidateAuthDUnitTest extends 
JUnit4DistributedTestCase {
+public class ClientDestroyInvalidateAuthDUnitTest {
   private static String REGION_NAME = "AuthRegion";
 
-  final Host host = Host.getHost(0);
-  final VM client1 = host.getVM(1);
-  final VM client2 = host.getVM(2);
-
+  private ClientVM client1, client2;
+  @Rule
+  public LocatorServerStartupRule lsRule = new LocatorServerStartupRule();
   @Rule
   public ServerStarterRule server =
       new ServerStarterRule().withProperty(SECURITY_MANAGER, 
TestSecurityManager.class.getName())
-          .withProperty(TestSecurityManager.SECURITY_JSON,
-              
"org/apache/geode/management/internal/security/clientServer.json")
-          .withAutoStart();
+          
.withSecurityManager(SimpleTestSecurityManager.class).withAutoStart();
 
   @Before
   public void before() throws Exception {
@@ -60,12 +58,10 @@ public class ClientDestroyInvalidateAuthDUnitTest extends 
JUnit4DistributedTestC
 
   @Test
   public void testDestroyInvalidate() throws Exception {
-
+    client1 = lsRule.startClientVM(1, "data", "data", true, server.getPort());
     // Delete one key and invalidate another key with an authorized user.
-    AsyncInvocation ai1 = client1.invokeAsync(() -> {
-      ClientCache cache =
-          SecurityTestUtil.createClientCache("dataUser", "1234567", 
server.getPort());
-
+    client1.invoke(() -> {
+      ClientCache cache = LocatorServerStartupRule.getClientCache();
       Region region =
           
cache.createClientRegionFactory(ClientRegionShortcut.PROXY).create(REGION_NAME);
       assertTrue(region.containsKeyOnServer("key1"));
@@ -78,13 +74,13 @@ public class ClientDestroyInvalidateAuthDUnitTest extends 
JUnit4DistributedTestC
       assertNotNull("Value of key2 should not be null", region.get("key2"));
       region.invalidate("key2");
       assertNull("Value of key2 should have been null", region.get("key2"));
-
+      cache.close();
     });
 
+    client2 = lsRule.startClientVM(2, "dataRead", "dataRead", true, 
server.getPort());
     // Delete one key and invalidate another key with an unauthorized user.
-    AsyncInvocation ai2 = client2.invokeAsync(() -> {
-      ClientCache cache =
-          SecurityTestUtil.createClientCache("authRegionReader", "1234567", 
server.getPort());
+    client2.invoke(() -> {
+      ClientCache cache = LocatorServerStartupRule.getClientCache();
 
       Region region =
           
cache.createClientRegionFactory(ClientRegionShortcut.PROXY).create(REGION_NAME);
@@ -100,10 +96,8 @@ public class ClientDestroyInvalidateAuthDUnitTest extends 
JUnit4DistributedTestC
       SecurityTestUtil.assertNotAuthorized(() -> region.invalidate("key4"),
           "DATA:WRITE:AuthRegion");
       assertNotNull("Value of key4 should not be null", region.get("key4"));
+      cache.close();
     });
-
-    ai1.await();
-    ai2.await();
   }
 
 }
diff --git 
a/geode-core/src/test/java/org/apache/geode/test/dunit/rules/ClientVM.java 
b/geode-core/src/test/java/org/apache/geode/test/dunit/rules/ClientVM.java
new file mode 100644
index 0000000..305c296
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/rules/ClientVM.java
@@ -0,0 +1,32 @@
+/*
+ * 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.dunit.rules;
+
+import org.apache.geode.test.dunit.VM;
+import org.apache.geode.test.junit.rules.VMProvider;
+
+public class ClientVM extends VMProvider {
+  private VM vm;
+
+  public ClientVM(VM vm) {
+    this.vm = vm;
+  }
+
+  @Override
+  public VM getVM() {
+    return vm;
+  }
+}
diff --git 
a/geode-core/src/test/java/org/apache/geode/test/dunit/rules/LocatorServerStartupRule.java
 
b/geode-core/src/test/java/org/apache/geode/test/dunit/rules/LocatorServerStartupRule.java
index 1399e2b..359786f 100644
--- 
a/geode-core/src/test/java/org/apache/geode/test/dunit/rules/LocatorServerStartupRule.java
+++ 
b/geode-core/src/test/java/org/apache/geode/test/dunit/rules/LocatorServerStartupRule.java
@@ -20,32 +20,39 @@ import static 
org.apache.geode.distributed.ConfigurationProperties.GROUPS;
 import static 
org.apache.geode.distributed.ConfigurationProperties.JMX_MANAGER_PORT;
 import static org.apache.geode.distributed.ConfigurationProperties.LOCATORS;
 import static org.apache.geode.distributed.ConfigurationProperties.NAME;
+import static 
org.apache.geode.distributed.ConfigurationProperties.SECURITY_CLIENT_AUTH_INIT;
 import static org.apache.geode.test.dunit.Host.getHost;
 
 import java.io.File;
 import java.io.IOException;
 import java.io.Serializable;
-import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
 import java.util.Properties;
+import java.util.function.Consumer;
 import java.util.stream.Collectors;
-import java.util.stream.IntStream;
 
 import org.junit.rules.ExternalResource;
 import org.junit.rules.TemporaryFolder;
 
+import org.apache.geode.cache.client.ClientCache;
+import org.apache.geode.cache.client.ClientCacheFactory;
 import org.apache.geode.cache.server.CacheServer;
 import org.apache.geode.distributed.internal.InternalLocator;
 import org.apache.geode.internal.AvailablePortHelper;
 import org.apache.geode.internal.cache.InternalCache;
+import org.apache.geode.security.templates.UserPasswordAuthInit;
 import org.apache.geode.test.dunit.VM;
 import org.apache.geode.test.dunit.standalone.DUnitLauncher;
+import org.apache.geode.test.junit.rules.ClientCacheRule;
 import org.apache.geode.test.junit.rules.Locator;
 import org.apache.geode.test.junit.rules.LocatorStarterRule;
 import org.apache.geode.test.junit.rules.Member;
 import org.apache.geode.test.junit.rules.MemberStarterRule;
 import org.apache.geode.test.junit.rules.Server;
 import org.apache.geode.test.junit.rules.ServerStarterRule;
+import org.apache.geode.test.junit.rules.VMProvider;
 import 
org.apache.geode.test.junit.rules.serializable.SerializableTemporaryFolder;
 
 
@@ -60,6 +67,7 @@ public class LocatorServerStartupRule extends 
ExternalResource implements Serial
    * This is only available in each Locator/Server VM, not in the controller 
(test) VM.
    */
   public static MemberStarterRule memberStarter;
+  public static ClientCacheRule clientCacheRule;
 
   public static InternalCache getCache() {
     return memberStarter.getCache();
@@ -77,7 +85,7 @@ public class LocatorServerStartupRule extends 
ExternalResource implements Serial
       new DistributedRestoreSystemProperties();
 
   private TemporaryFolder tempWorkingDir;
-  private ArrayList<MemberVM> members;
+  private Map<Integer, VMProvider> occupiedVMs;
 
   private boolean logFile = false;
 
@@ -85,6 +93,10 @@ public class LocatorServerStartupRule extends 
ExternalResource implements Serial
     DUnitLauncher.launchIfNeeded();
   }
 
+  public static ClientCache getClientCache() {
+    return clientCacheRule.getCache();
+  }
+
   /**
    * This will use a temporary folder to hold all the vm directories instead 
of using dunit folder.
    * It will set each VM's working dir to its respective sub-directories.
@@ -117,7 +129,7 @@ public class LocatorServerStartupRule extends 
ExternalResource implements Serial
     if (useTempWorkingDir()) {
       tempWorkingDir.create();
     }
-    members = new ArrayList<>();
+    occupiedVMs = new HashMap<>();
   }
 
   @Override
@@ -126,7 +138,9 @@ public class LocatorServerStartupRule extends 
ExternalResource implements Serial
       DUnitLauncher.closeAndCheckForSuspects();
     } finally {
       MemberStarterRule.disconnectDSIfAny();
-      IntStream.range(0, members.size()).forEach(this::stopVM);
+
+      // stop all the clientsVM before stop all the memberVM
+      occupiedVMs.values().stream().forEach(x -> x.stopVM(true));
 
       if (useTempWorkingDir()) {
         tempWorkingDir.delete();
@@ -176,16 +190,9 @@ public class LocatorServerStartupRule extends 
ExternalResource implements Serial
       locatorStarter.before();
       return locatorStarter;
     });
-
-    return setMember(index, new MemberVM(locator, locatorVM, 
useTempWorkingDir()));
-  }
-
-  private MemberVM setMember(int index, MemberVM element) {
-    while (members.size() <= index) {
-      members.add(null);
-    }
-    members.set(index, element);
-    return members.get(index);
+    MemberVM memberVM = new MemberVM(locator, locatorVM, useTempWorkingDir());
+    occupiedVMs.put(index, memberVM);
+    return memberVM;
   }
 
   public MemberVM startServerVM(int index) throws IOException {
@@ -233,41 +240,10 @@ public class LocatorServerStartupRule extends 
ExternalResource implements Serial
       serverStarter.before();
       return serverStarter;
     });
-    return setMember(index, new MemberVM(server, serverVM, 
useTempWorkingDir()));
-  }
 
-  public void startServerVMAsync(int index) {
-    startServerVMAsync(index, new Properties(), -1);
-  }
-
-  public void startServerVMAsync(int index, int locatorPort) {
-    startServerVMAsync(index, new Properties(), locatorPort);
-  }
-
-  public void startServerVMAsync(int index, Properties specifiedProperties, 
int locatorPort) {
-    assert members.get(index) != null;
-
-    Properties properties = new Properties();
-    properties.putAll(specifiedProperties);
-
-    String defaultName = "server-" + index;
-    properties.putIfAbsent(NAME, defaultName);
-    String name = properties.getProperty(NAME);
-
-    VM serverVM = getVM(index);
-    serverVM.invokeAsync(() -> {
-      memberStarter = new ServerStarterRule();
-      ServerStarterRule serverStarter = (ServerStarterRule) memberStarter;
-      if (useTempWorkingDir()) {
-        File workingDirFile = createWorkingDirForMember(name);
-        serverStarter.withWorkingDir(workingDirFile);
-      }
-      if (logFile) {
-        serverStarter.withLogFile();
-      }
-      
serverStarter.withProperties(properties).withConnectionToLocator(locatorPort).withAutoStart();
-      serverStarter.before();
-    });
+    MemberVM memberVM = new MemberVM(server, serverVM, useTempWorkingDir());
+    occupiedVMs.put(index, memberVM);
+    return memberVM;
   }
 
   public MemberVM startServerAsJmxManager(int index) throws IOException {
@@ -279,12 +255,6 @@ public class LocatorServerStartupRule extends 
ExternalResource implements Serial
     return startServerVM(index, properties, -1);
   }
 
-  public MemberVM startServerAsJmxManager(int index, Properties properties, 
int locatorPort)
-      throws IOException {
-    properties.setProperty(JMX_MANAGER_PORT, 
AvailablePortHelper.getRandomAvailableTCPPort() + "");
-    return startServerVM(index, properties, locatorPort);
-  }
-
   public MemberVM startServerAsEmbededLocator(int index) throws IOException {
     return startServerAsEmbededLocator(index, new Properties());
   }
@@ -308,7 +278,10 @@ public class LocatorServerStartupRule extends 
ExternalResource implements Serial
       serverStarter.before();
       return serverStarter;
     });
-    return setMember(index, new MemberVM(server, serverVM, 
useTempWorkingDir()));
+
+    MemberVM memberVM = new MemberVM(server, serverVM, useTempWorkingDir());
+    occupiedVMs.put(index, memberVM);
+    return memberVM;
   }
 
   public void stopVM(int index) {
@@ -316,22 +289,57 @@ public class LocatorServerStartupRule extends 
ExternalResource implements Serial
   }
 
   public void stopVM(int index, boolean cleanWorkingDir) {
-    MemberVM member = members.get(index);
-    // user has started a server/locator in this VM
-    if (member != null) {
-      member.stopMember(cleanWorkingDir);
-    }
-    // user may have used this VM as a client VM
-    else {
-      getVM(index).invoke(() -> MemberStarterRule.disconnectDSIfAny());
+    VMProvider member = occupiedVMs.get(index);
+
+    if (member == null)
+      return;
+
+    member.stopVM(cleanWorkingDir);
+  }
+
+  public ClientVM startClientVM(int index, String username, String password,
+      boolean subscriptionEnabled, int... serverPorts) throws Exception {
+    Properties props = new Properties();
+    props.setProperty(UserPasswordAuthInit.USER_NAME, username);
+    props.setProperty(UserPasswordAuthInit.PASSWORD, password);
+    props.setProperty(SECURITY_CLIENT_AUTH_INIT, 
UserPasswordAuthInit.class.getName());
+
+    Consumer<ClientCacheFactory> consumer =
+        (Serializable & Consumer<ClientCacheFactory>) ((cacheFactory) -> {
+          cacheFactory.setPoolSubscriptionEnabled(subscriptionEnabled);
+          for (int serverPort : serverPorts) {
+            cacheFactory.addPoolServer("localhost", serverPort);
+          }
+        });
+    return startClientVM(index, props, consumer);
+  }
+
+  public ClientVM startClientVM(int index, Properties properties,
+      Consumer<ClientCacheFactory> cacheFactorySetup) throws Exception {
+    VM client = getVM(index);
+    Exception error = client.invoke(() -> {
+      clientCacheRule =
+          new 
ClientCacheRule().withProperties(properties).withCacheSetup(cacheFactorySetup);
+      try {
+        clientCacheRule.before();
+        return null;
+      } catch (Exception e) {
+        return e;
+      }
+    });
+    if (error != null) {
+      throw error;
     }
+    ClientVM clientVM = new ClientVM(client);
+    occupiedVMs.put(index, clientVM);
+    return clientVM;
   }
 
   /**
    * Returns the {@link Member} running inside the VM with the specified 
{@code index}
    */
   public MemberVM getMember(int index) {
-    return members.get(index);
+    return (MemberVM) occupiedVMs.get(index);
   }
 
   public VM getVM(int index) {
@@ -350,11 +358,15 @@ public class LocatorServerStartupRule extends 
ExternalResource implements Serial
     return new File(DUnitLauncher.DUNIT_DIR);
   }
 
-  public static void stopMemberInThisVM() {
+  public static void stopElementInsideVM() {
     if (memberStarter != null) {
       memberStarter.after();
       memberStarter = null;
     }
+    if (clientCacheRule != null) {
+      clientCacheRule.after();
+      clientCacheRule = null;
+    }
   }
 
   private File createWorkingDirForMember(String dirName) throws IOException {
diff --git 
a/geode-core/src/test/java/org/apache/geode/test/dunit/rules/MemberVM.java 
b/geode-core/src/test/java/org/apache/geode/test/dunit/rules/MemberVM.java
index 71b3396..a5caf3b 100644
--- a/geode-core/src/test/java/org/apache/geode/test/dunit/rules/MemberVM.java
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/rules/MemberVM.java
@@ -20,18 +20,16 @@ import java.util.Arrays;
 
 import org.apache.commons.io.FileUtils;
 
-import org.apache.geode.test.dunit.AsyncInvocation;
-import org.apache.geode.test.dunit.SerializableCallableIF;
-import org.apache.geode.test.dunit.SerializableRunnableIF;
 import org.apache.geode.test.dunit.VM;
 import org.apache.geode.test.junit.rules.Locator;
 import org.apache.geode.test.junit.rules.Member;
 import org.apache.geode.test.junit.rules.Server;
+import org.apache.geode.test.junit.rules.VMProvider;
 
-public class MemberVM implements Member {
-  private Member member;
-  private VM vm;
-  private boolean tempWorkingDir;
+public class MemberVM extends VMProvider implements Member {
+  protected Member member;
+  protected VM vm;
+  protected boolean tempWorkingDir;
 
   public MemberVM(Member member, VM vm) {
     this(member, vm, false);
@@ -51,18 +49,6 @@ public class MemberVM implements Member {
     return vm;
   }
 
-  public void invoke(final SerializableRunnableIF runnable) {
-    vm.invoke(runnable);
-  }
-
-  public <T> T invoke(final SerializableCallableIF<T> callable) {
-    return vm.invoke(callable);
-  }
-
-  public AsyncInvocation invokeAsync(final SerializableRunnableIF runnable) {
-    return vm.invokeAsync(runnable);
-  }
-
   public Member getMember() {
     return member;
   }
@@ -101,8 +87,9 @@ public class MemberVM implements Member {
     return ((Server) member).getEmbeddedLocatorPort();
   }
 
-  public void stopMember(boolean cleanWorkingDir) {
-    this.invoke(LocatorServerStartupRule::stopMemberInThisVM);
+  public void stopVM(boolean cleanWorkingDir) {
+    super.stopVM(cleanWorkingDir);
+
     if (!cleanWorkingDir) {
       return;
     }
@@ -122,10 +109,6 @@ public class MemberVM implements Member {
           .forEach(FileUtils::deleteQuietly);
   }
 
-  public static void invokeInEveryMember(SerializableRunnableIF runnableIF, 
MemberVM... members) {
-    Arrays.stream(members).forEach(member -> member.invoke(runnableIF));
-  }
-
   /**
    * this should called on a locatorVM or a serverVM with jmxManager enabled
    */
diff --git 
a/geode-core/src/test/java/org/apache/geode/test/junit/rules/ClientCacheRule.java
 
b/geode-core/src/test/java/org/apache/geode/test/junit/rules/ClientCacheRule.java
new file mode 100644
index 0000000..a855a29
--- /dev/null
+++ 
b/geode-core/src/test/java/org/apache/geode/test/junit/rules/ClientCacheRule.java
@@ -0,0 +1,70 @@
+/*
+ * 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.junit.rules;
+
+import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT;
+
+import java.util.Properties;
+import java.util.function.Consumer;
+
+import org.apache.geode.cache.client.ClientCache;
+import org.apache.geode.cache.client.ClientCacheFactory;
+import 
org.apache.geode.test.junit.rules.serializable.SerializableExternalResource;
+
+public class ClientCacheRule extends SerializableExternalResource {
+  private ClientCache cache;
+  private ClientCacheFactory cacheFactory;
+  private Consumer<ClientCacheFactory> cacheSetup;
+  private Properties properties;
+
+  public ClientCacheRule() {
+    properties = new Properties();
+    properties.setProperty(MCAST_PORT, "0");
+  }
+
+  public ClientCacheRule withProperties(Properties properties) {
+    this.properties.putAll(properties);
+    return this;
+  }
+
+  public ClientCacheRule withProperty(String key, String value) {
+    properties.put(key, value);
+    return this;
+  }
+
+  public ClientCacheRule withCacheSetup(Consumer<ClientCacheFactory> setup) {
+    cacheSetup = setup;
+    return this;
+  }
+
+  @Override
+  public void before() throws Exception {
+    cacheFactory = new ClientCacheFactory(properties);
+    cacheSetup.accept(cacheFactory);
+    cache = cacheFactory.create();
+  }
+
+  @Override
+  public void after() {
+    if (cache != null) {
+      cache.close();
+    }
+  }
+
+  public ClientCache getCache() {
+    return cache;
+  }
+}
diff --git 
a/geode-core/src/test/java/org/apache/geode/test/junit/rules/VMProvider.java 
b/geode-core/src/test/java/org/apache/geode/test/junit/rules/VMProvider.java
new file mode 100644
index 0000000..47082b4
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/test/junit/rules/VMProvider.java
@@ -0,0 +1,55 @@
+/*
+ * 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.junit.rules;
+
+import java.util.Arrays;
+
+import org.apache.geode.test.dunit.AsyncInvocation;
+import org.apache.geode.test.dunit.SerializableCallableIF;
+import org.apache.geode.test.dunit.SerializableRunnableIF;
+import org.apache.geode.test.dunit.VM;
+import org.apache.geode.test.dunit.rules.LocatorServerStartupRule;
+
+public abstract class VMProvider {
+  public static void invokeInEveryMember(SerializableRunnableIF runnableIF, 
VMProvider... members) {
+    Arrays.stream(members).forEach(member -> member.invoke(runnableIF));
+  }
+
+  public abstract VM getVM();
+
+  public void stopVM(boolean cleanWorkingDir) {
+    getVM().invoke(() -> {
+      LocatorServerStartupRule.stopElementInsideVM();
+      MemberStarterRule.disconnectDSIfAny();
+    });
+  };
+
+  public void invoke(final SerializableRunnableIF runnable) {
+    getVM().invoke(runnable);
+  }
+
+  public <T> T invoke(final SerializableCallableIF<T> callable) {
+    return getVM().invoke(callable);
+  }
+
+  public AsyncInvocation invokeAsync(final SerializableRunnableIF runnable) {
+    return getVM().invokeAsync(runnable);
+  }
+
+  public AsyncInvocation invokeAsync(String name, final SerializableRunnableIF 
runnable) {
+    return getVM().invokeAsync(name, runnable);
+  }
+}
diff --git 
a/geode-wan/src/test/java/org/apache/geode/internal/cache/wan/wancommand/CreateDestroyGatewaySenderCommandDUnitTest.java
 
b/geode-wan/src/test/java/org/apache/geode/internal/cache/wan/wancommand/CreateDestroyGatewaySenderCommandDUnitTest.java
index 5fa4e23..014a09f 100644
--- 
a/geode-wan/src/test/java/org/apache/geode/internal/cache/wan/wancommand/CreateDestroyGatewaySenderCommandDUnitTest.java
+++ 
b/geode-wan/src/test/java/org/apache/geode/internal/cache/wan/wancommand/CreateDestroyGatewaySenderCommandDUnitTest.java
@@ -39,6 +39,7 @@ import 
org.apache.geode.test.dunit.rules.LocatorServerStartupRule;
 import org.apache.geode.test.dunit.rules.MemberVM;
 import org.apache.geode.test.junit.categories.DistributedTest;
 import org.apache.geode.test.junit.rules.GfshCommandRule;
+import org.apache.geode.test.junit.rules.VMProvider;
 
 @Category(DistributedTest.class)
 public class CreateDestroyGatewaySenderCommandDUnitTest {
@@ -93,7 +94,7 @@ public class CreateDestroyGatewaySenderCommandDUnitTest {
         "GatewaySender \"ln\" created on \"server-4\"",
         "GatewaySender \"ln\" created on \"server-5\"");
 
-    MemberVM.invokeInEveryMember(() -> verifySenderState("ln", true, false), 
server1, server2,
+    VMProvider.invokeInEveryMember(() -> verifySenderState("ln", true, false), 
server1, server2,
         server3);
 
     locatorSite1.invoke(() -> {
@@ -108,7 +109,7 @@ public class CreateDestroyGatewaySenderCommandDUnitTest {
         "GatewaySender \"ln\" destroyed on \"server-4\"",
         "GatewaySender \"ln\" destroyed on \"server-5\"");
 
-    MemberVM.invokeInEveryMember(() -> verifySenderDoesNotExist("ln", false), 
server1, server2,
+    VMProvider.invokeInEveryMember(() -> verifySenderDoesNotExist("ln", 
false), server1, server2,
         server3);
 
     locatorSite1.invoke(() -> {
@@ -146,7 +147,7 @@ public class CreateDestroyGatewaySenderCommandDUnitTest {
         "GatewaySender \"ln\" created on \"server-5\"");
 
 
-    MemberVM.invokeInEveryMember(() -> {
+    VMProvider.invokeInEveryMember(() -> {
       verifySenderState("ln", false, false);
       verifySenderAttributes("ln", 2, false, true, 1000, socketReadTimeout, 
true, 1000, 5000, true,
           false, 1000, 100, 2, GatewaySender.OrderPolicy.THREAD, null, null);
@@ -158,7 +159,7 @@ public class CreateDestroyGatewaySenderCommandDUnitTest {
         "GatewaySender \"ln\" destroyed on \"server-4\"",
         "GatewaySender \"ln\" destroyed on \"server-5\"");
 
-    MemberVM.invokeInEveryMember(() -> verifySenderDoesNotExist("ln", false), 
server1, server2,
+    VMProvider.invokeInEveryMember(() -> verifySenderDoesNotExist("ln", 
false), server1, server2,
         server3);
   }
 
@@ -195,7 +196,7 @@ public class CreateDestroyGatewaySenderCommandDUnitTest {
     eventFilters.add("org.apache.geode.cache30.MyGatewayEventFilter1");
     eventFilters.add("org.apache.geode.cache30.MyGatewayEventFilter2");
 
-    MemberVM.invokeInEveryMember(() -> {
+    VMProvider.invokeInEveryMember(() -> {
       verifySenderState("ln", false, false);
       verifySenderAttributes("ln", 2, false, true, 1000, socketReadTimeout, 
true, 1000, 5000, true,
           false, 1000, 100, 2, GatewaySender.OrderPolicy.THREAD, eventFilters, 
null);
@@ -208,7 +209,7 @@ public class CreateDestroyGatewaySenderCommandDUnitTest {
         "GatewaySender \"ln\" destroyed on \"server-4\"",
         "GatewaySender \"ln\" destroyed on \"server-5\"");
 
-    MemberVM.invokeInEveryMember(() -> verifySenderDoesNotExist("ln", false), 
server1, server2,
+    VMProvider.invokeInEveryMember(() -> verifySenderDoesNotExist("ln", 
false), server1, server2,
         server3);
   }
 
@@ -243,7 +244,7 @@ public class CreateDestroyGatewaySenderCommandDUnitTest {
     List<String> transportFilters = new ArrayList<String>();
     transportFilters.add("org.apache.geode.cache30.MyGatewayTransportFilter1");
 
-    MemberVM.invokeInEveryMember(() -> {
+    VMProvider.invokeInEveryMember(() -> {
       verifySenderState("ln", false, false);
       verifySenderAttributes("ln", 2, false, true, 1000, socketReadTimeout, 
true, 1000, 5000, true,
           false, 1000, 100, 2, GatewaySender.OrderPolicy.THREAD, null, 
transportFilters);
@@ -256,7 +257,7 @@ public class CreateDestroyGatewaySenderCommandDUnitTest {
         "GatewaySender \"ln\" destroyed on \"server-4\"",
         "GatewaySender \"ln\" destroyed on \"server-5\"");
 
-    MemberVM.invokeInEveryMember(() -> verifySenderDoesNotExist("ln", false), 
server1, server2,
+    VMProvider.invokeInEveryMember(() -> verifySenderDoesNotExist("ln", 
false), server1, server2,
         server3);
   }
 
@@ -273,13 +274,13 @@ public class CreateDestroyGatewaySenderCommandDUnitTest {
       verifySenderState("ln", true, false);
     });
 
-    MemberVM.invokeInEveryMember(() -> verifySenderDoesNotExist("ln", false), 
server2, server3);
+    VMProvider.invokeInEveryMember(() -> verifySenderDoesNotExist("ln", 
false), server2, server3);
 
     gfsh.executeAndAssertThat(DESTROY + " --member=" + 
server1.getName()).statusIsSuccess()
         .tableHasColumnWithExactValuesInAnyOrder("Status",
             "GatewaySender \"ln\" destroyed on \"server-3\"");
 
-    MemberVM.invokeInEveryMember(() -> verifySenderDoesNotExist("ln", false), 
server1);
+    VMProvider.invokeInEveryMember(() -> verifySenderDoesNotExist("ln", 
false), server1);
   }
 
   /**
@@ -295,13 +296,13 @@ public class CreateDestroyGatewaySenderCommandDUnitTest {
       verifySenderState("ln", true, false);
     });
 
-    MemberVM.invokeInEveryMember(() -> verifySenderDoesNotExist("ln", false), 
server2, server3);
+    VMProvider.invokeInEveryMember(() -> verifySenderDoesNotExist("ln", 
false), server2, server3);
 
     gfsh.executeAndAssertThat(DESTROY + " 
--group=senderGroup1").statusIsSuccess()
         .tableHasColumnWithExactValuesInAnyOrder("Status",
             "GatewaySender \"ln\" destroyed on \"server-3\"");
 
-    MemberVM.invokeInEveryMember(() -> verifySenderDoesNotExist("ln", false), 
server1);
+    VMProvider.invokeInEveryMember(() -> verifySenderDoesNotExist("ln", 
false), server1);
   }
 
   /**
@@ -321,7 +322,7 @@ public class CreateDestroyGatewaySenderCommandDUnitTest {
         "GatewaySender \"ln\" destroyed on \"server-4\"",
         "GatewaySender \"ln\" destroyed on \"server-5\"");
 
-    MemberVM.invokeInEveryMember(() -> verifySenderDoesNotExist("ln", false), 
server1, server2,
+    VMProvider.invokeInEveryMember(() -> verifySenderDoesNotExist("ln", 
false), server1, server2,
         server3);
   }
 }
diff --git 
a/geode-wan/src/test/java/org/apache/geode/internal/cache/wan/wancommand/CreateGatewayReceiverCommandDUnitTest.java
 
b/geode-wan/src/test/java/org/apache/geode/internal/cache/wan/wancommand/CreateGatewayReceiverCommandDUnitTest.java
index ad6ecca..76aa0cb 100644
--- 
a/geode-wan/src/test/java/org/apache/geode/internal/cache/wan/wancommand/CreateGatewayReceiverCommandDUnitTest.java
+++ 
b/geode-wan/src/test/java/org/apache/geode/internal/cache/wan/wancommand/CreateGatewayReceiverCommandDUnitTest.java
@@ -44,6 +44,7 @@ import 
org.apache.geode.test.dunit.rules.LocatorServerStartupRule;
 import org.apache.geode.test.dunit.rules.MemberVM;
 import org.apache.geode.test.junit.categories.DistributedTest;
 import org.apache.geode.test.junit.rules.GfshCommandRule;
+import org.apache.geode.test.junit.rules.VMProvider;
 
 /**
  * DUnit tests for 'create gateway-receiver' command.
@@ -108,7 +109,7 @@ public class CreateGatewayReceiverCommandDUnitTest {
             "GatewayReceiver created on member \"server-4\"",
             "GatewayReceiver created on member \"server-5\"");
 
-    MemberVM.invokeInEveryMember(() -> {
+    VMProvider.invokeInEveryMember(() -> {
       
verifyReceiverCreationWithAttributes(!GatewayReceiver.DEFAULT_MANUAL_START, 
10000, 11000,
           "localhost", 100000, 512000, null, 
GatewayReceiver.DEFAULT_HOSTNAME_FOR_SENDERS);
     }, server1, server2, server3);
@@ -146,7 +147,7 @@ public class CreateGatewayReceiverCommandDUnitTest {
     // when the Profile (and ServerLocation) are created
     String hostname = getHostName();
 
-    MemberVM.invokeInEveryMember(() -> {
+    VMProvider.invokeInEveryMember(() -> {
       verifyGatewayReceiverProfile(hostname);
       verifyGatewayReceiverServerLocations(locator1Port, hostname);
       
verifyReceiverCreationWithAttributes(!GatewayReceiver.DEFAULT_MANUAL_START,
@@ -181,7 +182,7 @@ public class CreateGatewayReceiverCommandDUnitTest {
             "GatewayReceiver created on member \"server-4\"",
             "GatewayReceiver created on member \"server-5\"");
 
-    MemberVM.invokeInEveryMember(() -> {
+    VMProvider.invokeInEveryMember(() -> {
       verifyReceiverCreationWithAttributes(false, 10000, 11000, "localhost", 
100000, 512000, null,
           GatewayReceiver.DEFAULT_HOSTNAME_FOR_SENDERS);
     }, server1, server2, server3);
@@ -212,7 +213,7 @@ public class CreateGatewayReceiverCommandDUnitTest {
             "GatewayReceiver created on member \"server-4\"",
             "GatewayReceiver created on member \"server-5\"");
 
-    MemberVM.invokeInEveryMember(() -> {
+    VMProvider.invokeInEveryMember(() -> {
       // verify hostname-for-senders is used when configured
       verifyGatewayReceiverProfile(hostnameForSenders);
       verifyGatewayReceiverServerLocations(locator1Port, hostnameForSenders);
@@ -246,7 +247,7 @@ public class CreateGatewayReceiverCommandDUnitTest {
             "GatewayReceiver created on member \"server-4\"",
             "GatewayReceiver created on member \"server-5\"");
 
-    MemberVM.invokeInEveryMember(() -> {
+    VMProvider.invokeInEveryMember(() -> {
       // verify bind-address used when provided as a gemfire property
       verifyGatewayReceiverProfile(expectedBindAddress);
       verifyGatewayReceiverServerLocations(locator1Port, expectedBindAddress);
@@ -283,7 +284,7 @@ public class CreateGatewayReceiverCommandDUnitTest {
             "GatewayReceiver created on member \"server-4\"",
             "GatewayReceiver created on member \"server-5\"");
 
-    MemberVM.invokeInEveryMember(() -> {
+    VMProvider.invokeInEveryMember(() -> {
       // verify server-bind-address used if provided as a gemfire property
       verifyGatewayReceiverProfile(expectedBindAddress);
       verifyGatewayReceiverServerLocations(locator1Port, expectedBindAddress);
@@ -323,7 +324,7 @@ public class CreateGatewayReceiverCommandDUnitTest {
             "GatewayReceiver created on member \"server-4\"",
             "GatewayReceiver created on member \"server-5\"");
 
-    MemberVM.invokeInEveryMember(() -> {
+    VMProvider.invokeInEveryMember(() -> {
       // verify server-bind-address used if provided as a gemfire property
       verifyGatewayReceiverProfile(expectedBindAddress);
       verifyGatewayReceiverServerLocations(locator1Port, expectedBindAddress);
@@ -369,7 +370,7 @@ public class CreateGatewayReceiverCommandDUnitTest {
             "GatewayReceiver created on member \"server-4\"",
             "GatewayReceiver created on member \"server-5\"");
 
-    MemberVM.invokeInEveryMember(() -> {
+    VMProvider.invokeInEveryMember(() -> {
       // verify server-bind-address takes precedence over hostname-for-senders
       verifyGatewayReceiverProfile(hostnameForSenders);
       verifyGatewayReceiverServerLocations(locator1Port, hostnameForSenders);
@@ -412,7 +413,7 @@ public class CreateGatewayReceiverCommandDUnitTest {
             "GatewayReceiver created on member \"server-4\"",
             "GatewayReceiver created on member \"server-5\"");
 
-    MemberVM.invokeInEveryMember(() -> {
+    VMProvider.invokeInEveryMember(() -> {
       verifyGatewayReceiverProfile(hostnameForSenders);
       verifyGatewayReceiverServerLocations(locator1Port, hostnameForSenders);
       verifyReceiverCreationWithAttributes(true, 10000, 11000, "", 100000, 
512000, null,
@@ -448,7 +449,7 @@ public class CreateGatewayReceiverCommandDUnitTest {
 
     List<String> transportFilters = new ArrayList<>();
     transportFilters.add("org.apache.geode.cache30.MyGatewayTransportFilter1");
-    MemberVM.invokeInEveryMember(() -> {
+    VMProvider.invokeInEveryMember(() -> {
       verifyReceiverCreationWithAttributes(true, 10000, 11000, "localhost", 
100000, 512000,
           transportFilters, GatewayReceiver.DEFAULT_HOSTNAME_FOR_SENDERS);
     }, server1, server2, server3);
@@ -483,7 +484,7 @@ public class CreateGatewayReceiverCommandDUnitTest {
     transportFilters.add("org.apache.geode.cache30.MyGatewayTransportFilter1");
     transportFilters.add("org.apache.geode.cache30.MyGatewayTransportFilter2");
 
-    MemberVM.invokeInEveryMember(() -> {
+    VMProvider.invokeInEveryMember(() -> {
       
verifyReceiverCreationWithAttributes(!GatewayReceiver.DEFAULT_MANUAL_START, 
10000, 11000,
           "localhost", 100000, 512000, transportFilters,
           GatewayReceiver.DEFAULT_HOSTNAME_FOR_SENDERS);
@@ -514,12 +515,12 @@ public class CreateGatewayReceiverCommandDUnitTest {
         .tableHasColumnWithValuesContaining("Status",
             "GatewayReceiver created on member \"server-3\"");
 
-    MemberVM.invokeInEveryMember(() -> {
+    VMProvider.invokeInEveryMember(() -> {
       verifyReceiverCreationWithAttributes(false, 10000, 11000, "localhost", 
100000, 512000, null,
           GatewayReceiver.DEFAULT_HOSTNAME_FOR_SENDERS);
     }, server1);
 
-    MemberVM.invokeInEveryMember(() -> {
+    VMProvider.invokeInEveryMember(() -> {
       Cache cache = LocatorServerStartupRule.getCache();
       assertThat(cache.getGatewayReceivers()).isEmpty();
     }, server2, server3);
@@ -551,12 +552,12 @@ public class CreateGatewayReceiverCommandDUnitTest {
             "GatewayReceiver created on member \"server-3\"",
             "GatewayReceiver created on member \"server-4\"");
 
-    MemberVM.invokeInEveryMember(() -> {
+    VMProvider.invokeInEveryMember(() -> {
       verifyReceiverCreationWithAttributes(false, 10000, 11000, "localhost", 
100000, 512000, null,
           GatewayReceiver.DEFAULT_HOSTNAME_FOR_SENDERS);
     }, server1, server2);
 
-    MemberVM.invokeInEveryMember(() -> {
+    VMProvider.invokeInEveryMember(() -> {
       Cache cache = LocatorServerStartupRule.getCache();
       assertThat(cache.getGatewayReceivers()).isEmpty();
     }, server3);
@@ -588,7 +589,7 @@ public class CreateGatewayReceiverCommandDUnitTest {
             "GatewayReceiver created on member \"server-4\"",
             "GatewayReceiver created on member \"server-5\"");
 
-    MemberVM.invokeInEveryMember(() -> {
+    VMProvider.invokeInEveryMember(() -> {
       verifyReceiverCreationWithAttributes(false, 10000, 11000, "localhost", 
100000, 512000, null,
           GatewayReceiver.DEFAULT_HOSTNAME_FOR_SENDERS);
     }, server1, server2, server3);
@@ -621,12 +622,12 @@ public class CreateGatewayReceiverCommandDUnitTest {
             "GatewayReceiver created on member \"server-3\"",
             "GatewayReceiver created on member \"server-4\"");
 
-    MemberVM.invokeInEveryMember(() -> {
+    VMProvider.invokeInEveryMember(() -> {
       verifyReceiverCreationWithAttributes(false, 10000, 11000, "localhost", 
100000, 512000, null,
           GatewayReceiver.DEFAULT_HOSTNAME_FOR_SENDERS);
     }, server1, server2);
 
-    MemberVM.invokeInEveryMember(() -> {
+    VMProvider.invokeInEveryMember(() -> {
       Cache cache = LocatorServerStartupRule.getCache();
       assertThat(cache.getGatewayReceivers()).isEmpty();
     }, server3);
@@ -657,7 +658,7 @@ public class CreateGatewayReceiverCommandDUnitTest {
             "GatewayReceiver created on member \"server-4\"",
             "GatewayReceiver created on member \"server-5\"");
 
-    MemberVM.invokeInEveryMember(() -> {
+    VMProvider.invokeInEveryMember(() -> {
       verifyReceiverCreationWithAttributes(false, 10000, 11000, "localhost", 
100000, 512000, null,
           GatewayReceiver.DEFAULT_HOSTNAME_FOR_SENDERS);
     }, server1, server2, server3);

-- 
To stop receiving notification emails like this one, please contact
['"commits@geode.apache.org" <commits@geode.apache.org>'].

Reply via email to