geode-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kl...@apache.org
Subject [11/17] geode git commit: Convert from ManagementTestCase to ManagementTestRule
Date Thu, 12 Jan 2017 23:25:43 GMT
http://git-wip-us.apache.org/repos/asf/geode/blob/c206d5b7/geode-core/src/test/java/org/apache/geode/management/bean/stats/DistributedSystemStatsDUnitTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/management/bean/stats/DistributedSystemStatsDUnitTest.java b/geode-core/src/test/java/org/apache/geode/management/bean/stats/DistributedSystemStatsDUnitTest.java
index d2e797e..5b71b1e 100644
--- a/geode-core/src/test/java/org/apache/geode/management/bean/stats/DistributedSystemStatsDUnitTest.java
+++ b/geode-core/src/test/java/org/apache/geode/management/bean/stats/DistributedSystemStatsDUnitTest.java
@@ -14,98 +14,70 @@
  */
 package org.apache.geode.management.bean.stats;
 
-import org.junit.experimental.categories.Category;
-import org.junit.Test;
-
+import static com.jayway.awaitility.Awaitility.*;
 import static org.junit.Assert.*;
 
-import org.apache.geode.test.dunit.cache.internal.JUnit4CacheTestCase;
-import org.apache.geode.test.dunit.internal.JUnit4DistributedTestCase;
-import org.apache.geode.test.junit.categories.DistributedTest;
-
+import java.lang.management.ManagementFactory;
 import java.util.Set;
+import java.util.concurrent.TimeUnit;
 
 import javax.management.ObjectName;
 
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
 import org.apache.geode.distributed.DistributedMember;
-import org.apache.geode.internal.cache.DiskStoreStats;
 import org.apache.geode.internal.cache.GemFireCacheImpl;
 import org.apache.geode.management.DistributedSystemMXBean;
-import org.apache.geode.management.ManagementTestBase;
+import org.apache.geode.management.ManagementService;
+import org.apache.geode.management.ManagementTestRule;
+import org.apache.geode.management.Manager;
+import org.apache.geode.management.Member;
 import org.apache.geode.management.MemberMXBean;
 import org.apache.geode.management.internal.SystemManagementService;
-import org.apache.geode.management.internal.beans.MemberMBean;
-import org.apache.geode.management.internal.beans.MemberMBeanBridge;
-import org.apache.geode.test.dunit.Assert;
-import org.apache.geode.test.dunit.SerializableRunnable;
 import org.apache.geode.test.dunit.VM;
+import org.apache.geode.test.junit.categories.DistributedTest;
 
-/**
- */
 @Category(DistributedTest.class)
-public class DistributedSystemStatsDUnitTest extends ManagementTestBase {
+@SuppressWarnings({"unused", "serial"})
+public class DistributedSystemStatsDUnitTest {
 
-  private static final long serialVersionUID = 1L;
+  @Manager
+  private VM manager;
 
-  public DistributedSystemStatsDUnitTest() {
-    super();
-  }
+  @Member
+  private VM[] members;
+
+  @Rule
+  public ManagementTestRule managementTestRule = ManagementTestRule.builder().start(true).build();
 
   @Test
   public void testDistributedSystemStats() throws Exception {
-    initManagement(true);
-
-    for (VM vm : managedNodeList) {
-      setDiskStats(vm);
-    }
-    verifyDiskStats(managingNode);
-  }
-
-  @SuppressWarnings("serial")
-  public void setDiskStats(VM vm1) throws Exception {
-    vm1.invoke(new SerializableRunnable("Set Member Stats") {
-      public void run() {
-        MemberMBean bean = (MemberMBean) managementService.getMemberMXBean();
-        MemberMBeanBridge bridge = bean.getBridge();
-        DiskStoreStats diskStoreStats = new DiskStoreStats(basicGetSystem(), "test");
-        bridge.addDiskStoreStats(diskStoreStats);
-        diskStoreStats.startRead();
-        diskStoreStats.startWrite();
-        diskStoreStats.startBackup();
-        diskStoreStats.startRecovery();
-        diskStoreStats.incWrittenBytes(20, true);
-        diskStoreStats.startFlush();
-        diskStoreStats.setQueueSize(10);
-      }
-    });
-  }
-
-  @SuppressWarnings("serial")
-  public void verifyDiskStats(VM vm1) throws Exception {
-    vm1.invoke(new SerializableRunnable("Set Member Stats") {
-      public void run() {
-        GemFireCacheImpl cache = GemFireCacheImpl.getInstance();
-
-        SystemManagementService service = (SystemManagementService) getManagementService();
-        DistributedSystemMXBean bean = service.getDistributedSystemMXBean();
-        assertNotNull(bean);
-        Set<DistributedMember> otherMemberSet =
-            cache.getDistributionManager().getOtherNormalDistributionManagerIds();
-
-        for (DistributedMember member : otherMemberSet) {
-          ObjectName memberMBeanName;
-          try {
-            memberMBeanName = service.getMemberMBeanName(member);
-            waitForProxy(memberMBeanName, MemberMXBean.class);
-            MemberMXBean memberBean = service.getMBeanProxy(memberMBeanName, MemberMXBean.class);
-            waitForRefresh(2, memberMBeanName);
-          } catch (NullPointerException e) {
-            Assert.fail("FAILED WITH EXCEPION", e);
-          } catch (Exception e) {
-            Assert.fail("FAILED WITH EXCEPION", e);
-          }
-        }
-
+    this.manager.invoke("verifyMBeans", () -> {
+      GemFireCacheImpl cache = GemFireCacheImpl.getInstance();
+      assertNotNull(cache);
+
+      SystemManagementService service =
+          (SystemManagementService) ManagementService.getManagementService(cache);
+      DistributedSystemMXBean distributedSystemMXBean = service.getDistributedSystemMXBean();
+      assertNotNull(distributedSystemMXBean);
+
+      Set<DistributedMember> otherMemberSet =
+          cache.getDistributionManager().getOtherNormalDistributionManagerIds();
+      assertEquals(3, otherMemberSet.size());
+
+      for (DistributedMember member : otherMemberSet) {
+        ObjectName memberMXBeanName = service.getMemberMBeanName(member);
+        await().atMost(2, TimeUnit.MINUTES).until(() -> assertTrue(
+            ManagementFactory.getPlatformMBeanServer().isRegistered(memberMXBeanName)));
+
+        MemberMXBean memberMXBean = service.getMBeanProxy(memberMXBeanName, MemberMXBean.class);
+        assertNotNull(memberMXBean);
+
+        final long lastRefreshTime = service.getLastUpdateTime(memberMXBeanName);
+        await().atMost(1, TimeUnit.MINUTES)
+            .until(() -> assertTrue(service.getLastUpdateTime(memberMXBeanName) > lastRefreshTime));
       }
     });
   }

http://git-wip-us.apache.org/repos/asf/geode/blob/c206d5b7/geode-core/src/test/java/org/apache/geode/management/internal/beans/QueryDataFunctionApplyLimitClauseTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/beans/QueryDataFunctionApplyLimitClauseTest.java b/geode-core/src/test/java/org/apache/geode/management/internal/beans/QueryDataFunctionApplyLimitClauseTest.java
index f4ca239..dcfd2bf 100644
--- a/geode-core/src/test/java/org/apache/geode/management/internal/beans/QueryDataFunctionApplyLimitClauseTest.java
+++ b/geode-core/src/test/java/org/apache/geode/management/internal/beans/QueryDataFunctionApplyLimitClauseTest.java
@@ -24,7 +24,6 @@ import org.junit.experimental.categories.Category;
 
 import org.apache.geode.test.junit.categories.UnitTest;
 
-
 @Category(UnitTest.class)
 public class QueryDataFunctionApplyLimitClauseTest {
 

http://git-wip-us.apache.org/repos/asf/geode/blob/c206d5b7/geode-core/src/test/java/org/apache/geode/management/internal/pulse/TestClientIdsDUnitTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/pulse/TestClientIdsDUnitTest.java b/geode-core/src/test/java/org/apache/geode/management/internal/pulse/TestClientIdsDUnitTest.java
index 9416616..a7940a4 100644
--- a/geode-core/src/test/java/org/apache/geode/management/internal/pulse/TestClientIdsDUnitTest.java
+++ b/geode-core/src/test/java/org/apache/geode/management/internal/pulse/TestClientIdsDUnitTest.java
@@ -14,11 +14,22 @@
  */
 package org.apache.geode.management.internal.pulse;
 
+import static java.util.concurrent.TimeUnit.MINUTES;
 import static org.apache.geode.distributed.ConfigurationProperties.*;
+import static org.apache.geode.test.dunit.NetworkUtils.getServerHostName;
+import static org.assertj.core.api.Assertions.assertThat;
 import static org.junit.Assert.*;
 
+import java.io.IOException;
+import java.io.Serializable;
 import java.util.Properties;
 
+import javax.management.ObjectName;
+
+import com.jayway.awaitility.Awaitility;
+import com.jayway.awaitility.core.ConditionFactory;
+import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
@@ -29,273 +40,141 @@ import org.apache.geode.cache.DataPolicy;
 import org.apache.geode.cache.Region;
 import org.apache.geode.cache.RegionAttributes;
 import org.apache.geode.cache.Scope;
+import org.apache.geode.cache.client.ClientCache;
+import org.apache.geode.cache.client.ClientRegionFactory;
+import org.apache.geode.cache.client.ClientRegionShortcut;
 import org.apache.geode.cache.client.PoolManager;
 import org.apache.geode.cache.client.internal.PoolImpl;
 import org.apache.geode.cache.server.CacheServer;
 import org.apache.geode.distributed.DistributedMember;
-import org.apache.geode.distributed.DistributedSystem;
-import org.apache.geode.internal.AvailablePort;
 import org.apache.geode.internal.cache.GemFireCacheImpl;
 import org.apache.geode.management.CacheServerMXBean;
-import org.apache.geode.management.MBeanUtil;
-import org.apache.geode.management.ManagementTestBase;
-import org.apache.geode.management.internal.cli.CliUtil;
+import org.apache.geode.management.ManagementTestRule;
+import org.apache.geode.management.Manager;
+import org.apache.geode.management.internal.SystemManagementService;
 import org.apache.geode.test.dunit.Assert;
 import org.apache.geode.test.dunit.Host;
-import org.apache.geode.test.dunit.LogWriterUtils;
-import org.apache.geode.test.dunit.NetworkUtils;
 import org.apache.geode.test.dunit.SerializableCallable;
 import org.apache.geode.test.dunit.SerializableRunnable;
 import org.apache.geode.test.dunit.VM;
-import org.apache.geode.test.dunit.Wait;
-import org.apache.geode.test.dunit.WaitCriterion;
-import org.apache.geode.test.dunit.internal.JUnit4DistributedTestCase;
 import org.apache.geode.test.junit.categories.DistributedTest;
 
 /**
  * This is for testing client IDs
  */
 @Category(DistributedTest.class)
-public class TestClientIdsDUnitTest extends JUnit4DistributedTestCase {
-
-  private static final String k1 = "k1";
-  private static final String k2 = "k2";
-
-  private static final String client_k1 = "client-k1";
-
-  private static final String client_k2 = "client-k2";
-
-  /** name of the test region */
-  private static final String REGION_NAME = "ClientHealthStatsDUnitTest_Region";
-
-  private static VM server = null;
-
-  private static VM client = null;
-
-  private static VM client2 = null;
-
-  private static VM managingNode = null;
-
-  private ManagementTestBase helper;
-
-  @Override
-  public final void preSetUp() throws Exception {
-    this.helper = new ManagementTestBase() {};
-  }
-
-  @Override
-  public final void postSetUp() throws Exception {
-    final Host host = Host.getHost(0);
-    managingNode = host.getVM(0);
-    server = host.getVM(1);
-    client = host.getVM(2);
-    client2 = host.getVM(3);
-  }
-
-  @Override
-  public final void preTearDown() throws Exception {
-    helper.closeCache(managingNode);
-    helper.closeCache(server);
-    helper.closeCache(client);
-    helper.closeCache(client2);
-
-    disconnectFromDS();
+@SuppressWarnings({"serial", "unused"})
+public class TestClientIdsDUnitTest implements Serializable {
+
+  private static final String KEY1 = "KEY1";
+  private static final String KEY2 = "KEY2";
+  private static final String VALUE1 = "client-KEY1";
+  private static final String VALUE2 = "client-KEY2";
+  private static final String REGION_NAME =
+      TestClientIdsDUnitTest.class.getSimpleName() + "_Region";
+
+  @Manager
+  private VM managerVM;
+
+  private VM serverVM;
+  private VM client1VM;
+  private VM client2VM;
+
+  @Rule
+  public ManagementTestRule managementTestRule = ManagementTestRule.builder().start(false).build();
+
+  @Before
+  public void before() throws Exception {
+    serverVM = Host.getHost(0).getVM(1);
+    client1VM = Host.getHost(0).getVM(2);
+    client2VM = Host.getHost(0).getVM(3);
   }
 
   @Test
   public void testClientIds() throws Exception {
-    helper.createManagementCache(managingNode);
-    helper.startManagingNode(managingNode);
-    int port = (Integer) createServerCache(server);
-    DistributedMember serverMember = helper.getMember(server);
-    createClientCache(client, NetworkUtils.getServerHostName(server.getHost()), port);
-    createClientCache(client2, NetworkUtils.getServerHostName(server.getHost()), port);
-    put(client);
-    put(client2);
-    verifyClientIds(managingNode, serverMember, port);
-    helper.stopManagingNode(managingNode);
-  }
+    this.managementTestRule.createManagers();
 
-  @SuppressWarnings("serial")
-  private Object createServerCache(VM vm) {
-    return vm.invoke(new SerializableCallable("Create Server Cache") {
-      public Object call() {
-        try {
-          return createServerCache();
-        } catch (Exception e) {
-          fail("Error while createServerCache " + e);
-        }
-        return null;
-      }
-    });
-  }
+    int port = this.serverVM.invoke(() -> createServerCache());
+
+    this.client1VM
+        .invoke(() -> createClientCache(getServerHostName(this.serverVM.getHost()), port));
+    this.client2VM
+        .invoke(() -> createClientCache(getServerHostName(this.serverVM.getHost()), port));
 
-  @SuppressWarnings("serial")
-  private void createClientCache(VM vm, final String host, final Integer port1) {
-    vm.invoke(new SerializableCallable("Create Client Cache") {
+    DistributedMember serverMember = this.managementTestRule.getDistributedMember(this.serverVM);
+    DistributedMember client1Member = this.managementTestRule.getDistributedMember(this.client1VM);
+    DistributedMember client2Member = this.managementTestRule.getDistributedMember(this.client2VM);
 
-      public Object call() {
+    // this.managerVM.invoke(() -> verifyClientIds(serverMember, port));
+    this.managerVM.invoke(() -> {
+      CacheServerMXBean cacheServerMXBean = awaitCacheServerMXBean(serverMember, port);
+      await().until(() -> {
         try {
-          createClientCache(host, port1);
+          assertThat(cacheServerMXBean.getClientIds()).hasSize(2);
         } catch (Exception e) {
-          fail("Error while createClientCache " + e);
+          throw new Error(e);
         }
-        return null;
-      }
+      });
+      assertThat(cacheServerMXBean.getClientIds()).hasSize(2); // TODO
     });
   }
 
-  private Cache createCache(Properties props) throws Exception {
-    DistributedSystem ds = getSystem(props);
-    ds.disconnect();
-    ds = getSystem(props);
-    assertNotNull(ds);
-    Cache cache = (GemFireCacheImpl) CacheFactory.create(ds);
-    assertNotNull(cache);
-    return cache;
-  }
+  private int createServerCache() throws IOException {
+    Cache cache = this.managementTestRule.getCache();
 
-  private Integer createServerCache(DataPolicy dataPolicy) throws Exception {
-    Cache cache = helper.createCache(false);
     AttributesFactory factory = new AttributesFactory();
     factory.setScope(Scope.DISTRIBUTED_ACK);
-    factory.setDataPolicy(dataPolicy);
+    factory.setDataPolicy(DataPolicy.REPLICATE);
+
     RegionAttributes attrs = factory.create();
     cache.createRegion(REGION_NAME, attrs);
-    int port = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
-    CacheServer server1 = cache.addCacheServer();
-    server1.setPort(port);
-    server1.setNotifyBySubscription(true);
-    server1.start();
-    return new Integer(server1.getPort());
-  }
 
-  public Integer createServerCache() throws Exception {
-    return createServerCache(DataPolicy.REPLICATE);
+    CacheServer cacheServer = cache.addCacheServer();
+    cacheServer.setPort(0);
+    cacheServer.setNotifyBySubscription(true);
+    cacheServer.start();
+    return cacheServer.getPort();
   }
 
-  public Cache createClientCache(String host, Integer port1) throws Exception {
+  private void createClientCache(final String host, final int serverPort) {
+    ClientCache cache = this.managementTestRule.getClientCache();
 
-    Properties props = new Properties();
-    props.setProperty(MCAST_PORT, "0");
-    props.setProperty(LOCATORS, "");
-    Cache cache = createCache(props);
-    PoolImpl p = (PoolImpl) PoolManager.createFactory().addServer(host, port1.intValue())
+    PoolImpl pool = (PoolImpl) PoolManager.createFactory().addServer(host, serverPort)
         .setSubscriptionEnabled(false).setThreadLocalConnections(true).setMinConnections(1)
         .setReadTimeout(20000).setPingInterval(10000).setRetryAttempts(1)
-        .setSubscriptionEnabled(true).setStatisticInterval(1000)
-        .create("CacheServerManagementDUnitTest");
-
-    AttributesFactory factory = new AttributesFactory();
-    factory.setScope(Scope.DISTRIBUTED_ACK);
-    factory.setPoolName(p.getName());
-
-    RegionAttributes attrs = factory.create();
-    Region region = cache.createRegion(REGION_NAME, attrs);
-    return cache;
+        .setSubscriptionEnabled(true).setStatisticInterval(1000).create(getClass().getSimpleName());
 
+    ClientRegionFactory factory =
+        cache.createClientRegionFactory(ClientRegionShortcut.CACHING_PROXY);
+    factory.setPoolName(pool.getName());
+    factory.create(REGION_NAME);
   }
 
-  /**
-   * get member id
-   */
-  @SuppressWarnings("serial")
-  protected static DistributedMember getMember() throws Exception {
-    GemFireCacheImpl cache = GemFireCacheImpl.getInstance();
-    return cache.getDistributedSystem().getDistributedMember();
+  private void verifyClientIds(final DistributedMember serverMember, final int serverPort)
+      throws Exception {
+    CacheServerMXBean cacheServerMXBean = awaitCacheServerMXBean(serverMember, serverPort);
+    await().until(() -> {
+      try {
+        assertThat(cacheServerMXBean.getClientIds()).hasSize(2);
+      } catch (Exception e) {
+        throw new Error(e);
+      }
+    });
+    assertThat(cacheServerMXBean.getClientIds()).hasSize(2); // TODO
   }
 
-  /**
-   * Verify the Cache Server details
-   * 
-   * @param vm
-   */
-  @SuppressWarnings("serial")
-  protected void verifyClientIds(final VM vm, final DistributedMember serverMember,
-      final int serverPort) {
-    SerializableRunnable verifyCacheServerRemote =
-        new SerializableRunnable("Verify Cache Server Remote") {
-          public void run() {
-            try {
-              final WaitCriterion waitCriteria = new WaitCriterion() {
-                @Override
-                public boolean done() {
-                  CacheServerMXBean bean = null;
-                  try {
-                    bean = MBeanUtil.getCacheServerMbeanProxy(serverMember, serverPort);
-                    if (bean != null) {
-                      if (bean.getClientIds().length > 0) {
-                        return true;
-                      }
-                    }
-                  } catch (Exception e) {
-                    LogWriterUtils.getLogWriter().info("exception occured " + e.getMessage()
-                        + CliUtil.stackTraceAsString((Throwable) e));
-                  }
-                  return false;
-                }
+  private CacheServerMXBean awaitCacheServerMXBean(final DistributedMember serverMember,
+      final int port) {
+    SystemManagementService service = this.managementTestRule.getSystemManagementService();
+    ObjectName objectName = service.getCacheServerMBeanName(port, serverMember);
 
-                @Override
-                public String description() {
-                  return "wait for getNumOfClients bean to complete and get results";
-                }
-              };
-              Wait.waitForCriterion(waitCriteria, 2 * 60 * 1000, 3000, true);
+    await().until(
+        () -> assertThat(service.getMBeanProxy(objectName, CacheServerMXBean.class)).isNotNull());
 
-              // Now it is sure that bean would be available
-              CacheServerMXBean bean = MBeanUtil.getCacheServerMbeanProxy(serverMember, serverPort);
-              LogWriterUtils.getLogWriter().info("verifyClientIds = " + bean.getClientIds().length);
-              assertEquals(true, bean.getClientIds().length > 0 ? true : false);
-            } catch (Exception e) {
-              fail("Error while verifying cache server from remote member " + e);
-            }
-          }
-        };
-    vm.invoke(verifyCacheServerRemote);
+    return service.getMBeanProxy(objectName, CacheServerMXBean.class);
   }
 
-  /**
-   * Verify the Cache Server details
-   * 
-   * @param vm
-   */
-  @SuppressWarnings("serial")
-  protected void put(final VM vm) {
-    SerializableRunnable put = new SerializableRunnable("put") {
-      public void run() {
-        try {
-          Cache cache = GemFireCacheImpl.getInstance();
-          Region<Object, Object> r1 = cache.getRegion(Region.SEPARATOR + REGION_NAME);
-          assertNotNull(r1);
-
-          r1.put(k1, client_k1);
-          assertEquals(r1.getEntry(k1).getValue(), client_k1);
-          r1.put(k2, client_k2);
-          assertEquals(r1.getEntry(k2).getValue(), client_k2);
-          try {
-            Thread.sleep(10000);
-          } catch (Exception e) {
-            // sleep
-          }
-          r1.clear();
-
-          r1.put(k1, client_k1);
-          assertEquals(r1.getEntry(k1).getValue(), client_k1);
-          r1.put(k2, client_k2);
-          assertEquals(r1.getEntry(k2).getValue(), client_k2);
-          try {
-            Thread.sleep(10000);
-          } catch (Exception e) {
-            // sleep
-          }
-          r1.clear();
-        } catch (Exception ex) {
-          Assert.fail("failed while put", ex);
-        }
-      }
-
-    };
-    vm.invoke(put);
+  private ConditionFactory await() {
+    return Awaitility.await().atMost(2, MINUTES);
   }
-
 }

http://git-wip-us.apache.org/repos/asf/geode/blob/c206d5b7/geode-core/src/test/java/org/apache/geode/management/internal/pulse/TestSubscriptionsDUnitTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/pulse/TestSubscriptionsDUnitTest.java b/geode-core/src/test/java/org/apache/geode/management/internal/pulse/TestSubscriptionsDUnitTest.java
index 7d96517..52c7b9c 100644
--- a/geode-core/src/test/java/org/apache/geode/management/internal/pulse/TestSubscriptionsDUnitTest.java
+++ b/geode-core/src/test/java/org/apache/geode/management/internal/pulse/TestSubscriptionsDUnitTest.java
@@ -15,6 +15,9 @@
 package org.apache.geode.management.internal.pulse;
 
 import static org.apache.geode.distributed.ConfigurationProperties.*;
+import static org.apache.geode.test.dunit.Host.*;
+import static org.apache.geode.test.dunit.NetworkUtils.*;
+import static org.apache.geode.test.dunit.Wait.*;
 import static org.junit.Assert.*;
 
 import java.util.Properties;
@@ -32,268 +35,173 @@ import org.apache.geode.cache.Scope;
 import org.apache.geode.cache.client.PoolManager;
 import org.apache.geode.cache.client.internal.PoolImpl;
 import org.apache.geode.cache.server.CacheServer;
-import org.apache.geode.distributed.DistributedMember;
 import org.apache.geode.distributed.DistributedSystem;
-import org.apache.geode.internal.AvailablePort;
 import org.apache.geode.internal.cache.GemFireCacheImpl;
 import org.apache.geode.management.DistributedSystemMXBean;
 import org.apache.geode.management.ManagementService;
 import org.apache.geode.management.ManagementTestBase;
-import org.apache.geode.test.dunit.Assert;
-import org.apache.geode.test.dunit.Host;
-import org.apache.geode.test.dunit.LogWriterUtils;
-import org.apache.geode.test.dunit.NetworkUtils;
-import org.apache.geode.test.dunit.SerializableCallable;
-import org.apache.geode.test.dunit.SerializableRunnable;
 import org.apache.geode.test.dunit.VM;
-import org.apache.geode.test.dunit.Wait;
 import org.apache.geode.test.dunit.WaitCriterion;
-import org.apache.geode.test.dunit.internal.JUnit4DistributedTestCase;
 import org.apache.geode.test.junit.categories.DistributedTest;
 
 /**
  * This is for testing subscriptions
  */
 @Category(DistributedTest.class)
-public class TestSubscriptionsDUnitTest extends JUnit4DistributedTestCase {
+@SuppressWarnings("serial")
+public class TestSubscriptionsDUnitTest extends ManagementTestBase {
 
-  private static final String k1 = "k1";
-  private static final String k2 = "k2";
-  private static final String client_k1 = "client-k1";
-
-  private static final String client_k2 = "client-k2";
   private static final String REGION_NAME =
       TestSubscriptionsDUnitTest.class.getSimpleName() + "_Region";
+
+  private static final String KEY1 = "k1";
+  private static final String KEY2 = "k2";
+  private static final String CLIENT_VALUE1 = "client-k1";
+  private static final String CLIENT_VALUE2 = "client-k2";
+
   private static VM server = null;
   private static VM client = null;
   private static VM client2 = null;
-  private static VM managingNode = null;
-  private ManagementTestBase helper;
-
-  @Override
-  public final void preSetUp() throws Exception {
-    this.helper = new ManagementTestBase() {};
-  }
 
   @Override
-  public final void postSetUp() throws Exception {
-    final Host host = Host.getHost(0);
-    managingNode = host.getVM(0);
-    server = host.getVM(1);
-    client = host.getVM(2);
-    client2 = host.getVM(3);
-  }
-
-  @Override
-  public final void preTearDown() throws Exception {
-    helper.closeCache(managingNode);
-    helper.closeCache(server);
-    helper.closeCache(client);
-    helper.closeCache(client2);
-    disconnectFromDS();
+  public final void postSetUpManagementTestBase() throws Exception {
+    server = getHost(0).getVM(1);
+    client = getHost(0).getVM(2);
+    client2 = getHost(0).getVM(3);
   }
 
   @Test
-  public void testNoOfSubscription() throws Exception {
+  public void testNumSubscriptions() throws Exception {
+    createManagementCache(managingNode);
+    startManagingNode(managingNode);
+
+    int port = createServerCache(server);
+    getMember(server);
 
-    helper.createManagementCache(managingNode);
-    helper.startManagingNode(managingNode);
+    createClientCache(client, getServerHostName(server.getHost()), port);
+    createClientCache(client2, getServerHostName(server.getHost()), port);
 
-    int port = (Integer) createServerCache(server);
-    DistributedMember serverMember = helper.getMember(server);
-    createClientCache(client, NetworkUtils.getServerHostName(server.getHost()), port);
-    createClientCache(client2, NetworkUtils.getServerHostName(server.getHost()), port);
     put(client);
     put(client2);
+
     registerInterest(client);
     registerInterest(client2);
-    verifyClientStats(managingNode, serverMember, port);
-    helper.stopManagingNode(managingNode);
-  }
 
-  @SuppressWarnings("serial")
-  private Object createServerCache(VM vm) {
-    return vm.invoke(new SerializableCallable("Create Server Cache in TestSubscriptionsDUnitTest") {
+    verifyNumSubscriptions(managingNode);
 
-      public Object call() {
-        try {
-          return createServerCache();
-        } catch (Exception e) {
-          fail("Error while createServerCache in TestSubscriptionsDUnitTest" + e);
-        }
-        return null;
-      }
-    });
+    stopManagingNode(managingNode);
   }
 
-  @SuppressWarnings("serial")
-  private void createClientCache(VM vm, final String host, final Integer port1) {
-    vm.invoke(new SerializableCallable("Create Client Cache in TestSubscriptionsDUnitTest") {
+  private int createServerCache(VM vm) {
+    return vm.invoke("Create Server Cache in TestSubscriptionsDUnitTest", () -> {
+      return createServerCache();
+    });
+  }
 
-      public Object call() {
-        try {
-          createClientCache(host, port1);
-        } catch (Exception e) {
-          fail("Error while createClientCache in TestSubscriptionsDUnitTest " + e);
-        }
-        return null;
-      }
+  private void createClientCache(VM vm, final String host, final int port1) {
+    vm.invoke("Create Client Cache in TestSubscriptionsDUnitTest", () -> {
+      createClientCache(host, port1);
     });
   }
 
   private Cache createCache(Properties props) throws Exception {
     DistributedSystem ds = getSystem(props);
-    ds.disconnect();
-    ds = getSystem(props);
-    assertNotNull(ds);
-    Cache cache = (GemFireCacheImpl) CacheFactory.create(ds);
-    assertNotNull(cache);
+    Cache cache = CacheFactory.create(ds);
     return cache;
   }
 
-  private Integer createServerCache(DataPolicy dataPolicy) throws Exception {
-    Cache cache = helper.createCache(false);
+  private int createServerCache(DataPolicy dataPolicy) throws Exception {
+    Cache cache = createCache(false);
+
     AttributesFactory factory = new AttributesFactory();
     factory.setScope(Scope.DISTRIBUTED_ACK);
     factory.setDataPolicy(dataPolicy);
-    RegionAttributes attrs = factory.create();
-    cache.createRegion(REGION_NAME, attrs);
-    int port = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
+
+    cache.createRegion(REGION_NAME, factory.create());
+
     CacheServer server1 = cache.addCacheServer();
-    server1.setPort(port);
+    server1.setPort(0);
     server1.setNotifyBySubscription(true);
     server1.start();
-    return new Integer(server1.getPort());
+
+    return server1.getPort();
   }
 
-  public Integer createServerCache() throws Exception {
+  private int createServerCache() throws Exception {
     return createServerCache(DataPolicy.REPLICATE);
   }
 
-  public Cache createClientCache(String host, Integer port1) throws Exception {
-
+  private Cache createClientCache(String host, int port1) throws Exception {
     Properties props = new Properties();
     props.setProperty(MCAST_PORT, "0");
     props.setProperty(LOCATORS, "");
+
     Cache cache = createCache(props);
-    PoolImpl p = (PoolImpl) PoolManager.createFactory().addServer(host, port1.intValue())
-        .setSubscriptionEnabled(true).setThreadLocalConnections(true).setMinConnections(1)
-        .setReadTimeout(20000).setPingInterval(10000).setRetryAttempts(1)
-        .setSubscriptionEnabled(true).setStatisticInterval(1000)
-        .create("TestSubscriptionsDUnitTest");
+
+    PoolImpl p =
+        (PoolImpl) PoolManager.createFactory().addServer(host, port1).setSubscriptionEnabled(true)
+            .setThreadLocalConnections(true).setMinConnections(1).setReadTimeout(20000)
+            .setPingInterval(10000).setRetryAttempts(1).setSubscriptionEnabled(true)
+            .setStatisticInterval(1000).create("TestSubscriptionsDUnitTest");
 
     AttributesFactory factory = new AttributesFactory();
     factory.setScope(Scope.DISTRIBUTED_ACK);
     factory.setPoolName(p.getName());
 
     RegionAttributes attrs = factory.create();
-    Region region = cache.createRegion(REGION_NAME, attrs);
-    return cache;
+    cache.createRegion(REGION_NAME, attrs);
 
+    return cache;
   }
 
-  /**
-   * get member id
-   */
-  @SuppressWarnings("serial")
-  protected static DistributedMember getMember() throws Exception {
-    GemFireCacheImpl cache = GemFireCacheImpl.getInstance();
-    return cache.getDistributedSystem().getDistributedMember();
-  }
+  private void verifyNumSubscriptions(final VM vm) {
+    vm.invoke("TestSubscriptionsDUnitTest Verify Cache Server Remote", () -> {
+      final GemFireCacheImpl cache = GemFireCacheImpl.getInstance();
+
+      waitForCriterion(new WaitCriterion() {
+        @Override
+        public boolean done() {
+          ManagementService service = ManagementService.getExistingManagementService(cache);
+          DistributedSystemMXBean distributedSystemMXBean = service.getDistributedSystemMXBean();
+          return distributedSystemMXBean != null
+              & distributedSystemMXBean.getNumSubscriptions() > 1;
+        }
 
-  /**
-   * Verify the Cache Server details
-   * 
-   * @param vm
-   */
-  @SuppressWarnings("serial")
-  protected void verifyClientStats(final VM vm, final DistributedMember serverMember,
-      final int serverPort) {
-    SerializableRunnable verifyCacheServerRemote =
-        new SerializableRunnable("TestSubscriptionsDUnitTest Verify Cache Server Remote") {
-          public void run() {
-            final GemFireCacheImpl cache = GemFireCacheImpl.getInstance();
-            try {
-              final WaitCriterion waitCriteria = new WaitCriterion() {
-                @Override
-                public boolean done() {
-                  ManagementService service = ManagementService.getExistingManagementService(cache);
-                  final DistributedSystemMXBean dsBean = service.getDistributedSystemMXBean();
-                  if (dsBean != null) {
-                    if (dsBean.getNumSubscriptions() > 1) {
-                      return true;
-                    }
-                  }
-                  return false;
-                }
-
-                @Override
-                public String description() {
-                  return "TestSubscriptionsDUnitTest wait for getDistributedSystemMXBean to complete and get results";
-                }
-              };
-              Wait.waitForCriterion(waitCriteria, 2 * 60 * 1000, 3000, true);
-              final DistributedSystemMXBean dsBean = ManagementService
-                  .getExistingManagementService(cache).getDistributedSystemMXBean();
-              assertNotNull(dsBean);
-              LogWriterUtils.getLogWriter()
-                  .info("TestSubscriptionsDUnitTest dsBean.getNumSubscriptions() ="
-                      + dsBean.getNumSubscriptions());
-              assertTrue(dsBean.getNumSubscriptions() == 2 ? true : false);
-            } catch (Exception e) {
-              fail("TestSubscriptionsDUnitTest Error while verifying subscription "
-                  + e.getMessage());
-            }
-
-          }
-        };
-    vm.invoke(verifyCacheServerRemote);
-  }
+        @Override
+        public String description() {
+          return "TestSubscriptionsDUnitTest wait for getDistributedSystemMXBean to complete and get results";
+        }
+      }, 2 * 60 * 1000, 3000, true);
 
-  /**
-   * Verify the Cache Server details
-   * 
-   * @param vm
-   */
-  @SuppressWarnings("serial")
-  protected void registerInterest(final VM vm) {
-    SerializableRunnable put =
-        new SerializableRunnable("TestSubscriptionsDUnitTest registerInterest") {
-          public void run() {
-            try {
-              Cache cache = GemFireCacheImpl.getInstance();
-              Region<Object, Object> r1 = cache.getRegion(Region.SEPARATOR + REGION_NAME);
-              assertNotNull(r1);
-              r1.registerInterest(k1);
-              r1.registerInterest(k2);
-            } catch (Exception ex) {
-              Assert.fail("TestSubscriptionsDUnitTest failed while register Interest", ex);
-            }
-          }
-
-        };
-    vm.invoke(put);
+      DistributedSystemMXBean distributedSystemMXBean =
+          ManagementService.getExistingManagementService(cache).getDistributedSystemMXBean();
+      assertNotNull(distributedSystemMXBean);
+      assertEquals(2, distributedSystemMXBean.getNumSubscriptions());
+    });
   }
 
-  @SuppressWarnings("serial")
-  protected void put(final VM vm) {
-    SerializableRunnable put = new SerializableRunnable("put") {
-      public void run() {
-        try {
-          Cache cache = GemFireCacheImpl.getInstance();
-          Region r1 = cache.getRegion(Region.SEPARATOR + REGION_NAME);
-          assertNotNull(r1);
-          r1.put(k1, client_k1);
-          assertEquals(r1.getEntry(k1).getValue(), client_k1);
-          r1.put(k2, client_k2);
-          assertEquals(r1.getEntry(k2).getValue(), client_k2);
-        } catch (Exception ex) {
-          Assert.fail("failed while put", ex);
-        }
-      }
+  private void registerInterest(final VM vm) {
+    vm.invoke("TestSubscriptionsDUnitTest registerInterest", () -> {
+      Cache cache = GemFireCacheImpl.getInstance();
+      Region<Object, Object> region = cache.getRegion(Region.SEPARATOR + REGION_NAME);
+      assertNotNull(region);
 
-    };
-    vm.invoke(put);
+      region.registerInterest(KEY1);
+      region.registerInterest(KEY2);
+    });
   }
 
+  private void put(final VM vm) {
+    vm.invoke("put", () -> {
+      Cache cache = GemFireCacheImpl.getInstance();
+      Region region = cache.getRegion(Region.SEPARATOR + REGION_NAME);
+      assertNotNull(region);
+
+      region.put(KEY1, CLIENT_VALUE1);
+      assertEquals(CLIENT_VALUE1, region.getEntry(KEY1).getValue());
+
+      region.put(KEY2, CLIENT_VALUE2);
+      assertEquals(CLIENT_VALUE2, region.getEntry(KEY2).getValue());
+    });
+  }
 }

http://git-wip-us.apache.org/repos/asf/geode/blob/c206d5b7/geode-core/src/test/java/org/apache/geode/test/dunit/AsyncInvocation.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/AsyncInvocation.java b/geode-core/src/test/java/org/apache/geode/test/dunit/AsyncInvocation.java
index 460b562..057454d 100644
--- a/geode-core/src/test/java/org/apache/geode/test/dunit/AsyncInvocation.java
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/AsyncInvocation.java
@@ -316,6 +316,58 @@ public class AsyncInvocation<V> implements Future<V> {
   }
 
   /**
+   * Waits if necessary for at most the given time for the computation to complete.
+   *
+   * @param timeout the maximum time to wait
+   * @param unit the time unit of the timeout argument
+   *
+   * @return this {@code AsyncInvocation}
+   *
+   * @throws AssertionError wrapping any {@code Exception} thrown by this {@code AsyncInvocation}.
+   *
+   * @throws CancellationException if the computation was cancelled
+   *
+   * @throws ExecutionException if the computation threw an exception
+   *
+   * @throws InterruptedException if the current thread is interrupted.
+   *
+   * @throws TimeoutException if the wait timed out
+   */
+  public AsyncInvocation<V> await(final long timeout, final TimeUnit unit)
+      throws ExecutionException, InterruptedException, TimeoutException {
+    long millis = unit.toMillis(timeout);
+    join(millis);
+    timeoutIfAlive(millis);
+    checkException();
+    return this;
+  }
+
+  /**
+   * Waits if necessary for at most the given time for the computation to complete.
+   *
+   * @return this {@code AsyncInvocation}
+   *
+   * @throws AssertionError wrapping any {@code Exception} thrown by this {@code AsyncInvocation}.
+   *
+   * @throws AssertionError wrapping a {@code TimeoutException} if this {@code AsyncInvocation}
+   *         fails to complete within the default timeout of 60 seconds as defined by
+   *         {@link #DEFAULT_JOIN_MILLIS}.
+   *
+   * @throws CancellationException if the computation was cancelled
+   *
+   * @throws ExecutionException if the computation threw an exception
+   *
+   * @throws InterruptedException if the current thread is interrupted.
+   */
+  public AsyncInvocation<V> await() throws ExecutionException, InterruptedException {
+    try {
+      return await(DEFAULT_JOIN_MILLIS, TimeUnit.MILLISECONDS);
+    } catch (TimeoutException timeoutException) {
+      throw new AssertionError(timeoutException);
+    }
+  }
+
+  /**
    * Waits if necessary for the work to complete, and then returns the result of this
    * {@code AsyncInvocation}.
    *
@@ -353,10 +405,6 @@ public class AsyncInvocation<V> implements Future<V> {
    *
    * @throws AssertionError wrapping any {@code Exception} thrown by this {@code AsyncInvocation}.
    *
-   * @throws AssertionError wrapping a {@code TimeoutException} if this {@code AsyncInvocation}
-   *         fails to complete within the default timeout of 60 seconds as defined by
-   *         {@link #DEFAULT_JOIN_MILLIS}.
-   *
    * @throws CancellationException if the computation was cancelled
    *
    * @throws ExecutionException if the computation threw an exception

http://git-wip-us.apache.org/repos/asf/geode/blob/c206d5b7/geode-core/src/test/java/org/apache/geode/test/dunit/Invoke.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/Invoke.java b/geode-core/src/test/java/org/apache/geode/test/dunit/Invoke.java
index a09f5ff..af7e217 100755
--- a/geode-core/src/test/java/org/apache/geode/test/dunit/Invoke.java
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/Invoke.java
@@ -22,13 +22,13 @@ import java.util.Map;
  * invoke a <code>SerializableRunnable</code> or <code>SerializableCallable</code> in a remote test
  * <code>VM</code>.
  * 
- * These methods can be used directly: <code>Invoke.invokeInEveryVM(...)</code>, however, they are
- * intended to be referenced through static import:
+ * These methods can be used directly: <code>Invoke.invokeInEveryVMAndController(...)</code>,
+ * however, they are intended to be referenced through static import:
  *
  * <pre>
  * import static org.apache.geode.test.dunit.Invoke.*;
  *    ...
- *    invokeInEveryVM(...);
+ *    invokeInEveryVMAndController(...);
  * </pre>
  *
  * Extracted from DistributedTestCase.

http://git-wip-us.apache.org/repos/asf/geode/blob/c206d5b7/geode-core/src/test/java/org/apache/geode/test/dunit/VM.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/VM.java b/geode-core/src/test/java/org/apache/geode/test/dunit/VM.java
index 04d2951..9a42caa 100644
--- a/geode-core/src/test/java/org/apache/geode/test/dunit/VM.java
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/VM.java
@@ -24,6 +24,7 @@ import java.util.concurrent.Callable;
 import com.jayway.awaitility.Awaitility;
 import hydra.MethExecutorResult;
 
+import org.apache.geode.internal.process.PidUnavailableException;
 import org.apache.geode.internal.process.ProcessUtils;
 import org.apache.geode.test.dunit.standalone.BounceResult;
 import org.apache.geode.test.dunit.standalone.RemoteDUnitVMIF;
@@ -91,7 +92,11 @@ public class VM implements Serializable {
    * Returns the process id of this {@code VM}.
    */
   public int getPid() {
-    return this.pid;
+    // try {
+    return invoke(() -> ProcessUtils.identifyPid());
+    // } catch (PidUnavailableException e) {
+    // return this.pid;
+    // }
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/geode/blob/c206d5b7/geode-core/src/test/java/org/apache/geode/test/dunit/Wait.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/Wait.java b/geode-core/src/test/java/org/apache/geode/test/dunit/Wait.java
index f25810e..7d4e6d5 100755
--- a/geode-core/src/test/java/org/apache/geode/test/dunit/Wait.java
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/Wait.java
@@ -17,6 +17,8 @@ package org.apache.geode.test.dunit;
 import static org.apache.geode.test.dunit.Jitter.*;
 import static org.junit.Assert.*;
 
+import java.io.Serializable;
+
 import org.apache.logging.log4j.Logger;
 
 import org.apache.geode.internal.cache.LocalRegion;

http://git-wip-us.apache.org/repos/asf/geode/blob/c206d5b7/geode-core/src/test/java/org/apache/geode/test/dunit/cache/internal/JUnit4CacheTestCase.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/cache/internal/JUnit4CacheTestCase.java b/geode-core/src/test/java/org/apache/geode/test/dunit/cache/internal/JUnit4CacheTestCase.java
index 037d73c..a511995 100644
--- a/geode-core/src/test/java/org/apache/geode/test/dunit/cache/internal/JUnit4CacheTestCase.java
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/cache/internal/JUnit4CacheTestCase.java
@@ -245,6 +245,11 @@ public abstract class JUnit4CacheTestCase extends JUnit4DistributedTestCase
     return getCache(false, factory);
   }
 
+  public final Cache getCache(final Properties properties) {
+    getSystem(properties);
+    return getCache();
+  }
+
   public final Cache getCache(final boolean client) {
     return getCache(client, null);
   }

http://git-wip-us.apache.org/repos/asf/geode/blob/c206d5b7/geode-core/src/test/java/org/apache/geode/test/dunit/internal/JUnit4DistributedTestCase.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/internal/JUnit4DistributedTestCase.java b/geode-core/src/test/java/org/apache/geode/test/dunit/internal/JUnit4DistributedTestCase.java
index c54b6ac..19949c2 100644
--- a/geode-core/src/test/java/org/apache/geode/test/dunit/internal/JUnit4DistributedTestCase.java
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/internal/JUnit4DistributedTestCase.java
@@ -113,7 +113,7 @@ public abstract class JUnit4DistributedTestCase implements DistributedTestFixtur
   }
 
   @Rule
-  public SerializableTestName testName = new SerializableTestName();
+  public SerializableTestName testNameForDistributedTestCase = new SerializableTestName();
 
   private static DUnitBlackboard blackboard;
 
@@ -139,7 +139,7 @@ public abstract class JUnit4DistributedTestCase implements DistributedTestFixtur
     if (this.distributedTestFixture != this) {
       return this.distributedTestFixture.getName();
     }
-    return this.testName.getMethodName();
+    return this.testNameForDistributedTestCase.getMethodName();
   }
 
   public final Class<? extends DistributedTestFixture> getTestClass() {

http://git-wip-us.apache.org/repos/asf/geode/blob/c206d5b7/geode-core/src/test/java/org/apache/geode/test/dunit/rules/DistributedDisconnectRule.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/rules/DistributedDisconnectRule.java b/geode-core/src/test/java/org/apache/geode/test/dunit/rules/DistributedDisconnectRule.java
index ddf37c5..9107d4d 100755
--- a/geode-core/src/test/java/org/apache/geode/test/dunit/rules/DistributedDisconnectRule.java
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/rules/DistributedDisconnectRule.java
@@ -43,14 +43,14 @@ public class DistributedDisconnectRule extends DistributedExternalResource {
   @Override
   protected void before() throws Throwable {
     if (this.disconnectBefore) {
-      invoker().invokeEverywhere(serializableRunnable());
+      invoker().invokeInEveryVMAndController(serializableRunnable());
     }
   }
 
   @Override
   protected void after() {
     if (this.disconnectAfter) {
-      invoker().invokeEverywhere(serializableRunnable());
+      invoker().invokeInEveryVMAndController(serializableRunnable());
     }
   }
 

http://git-wip-us.apache.org/repos/asf/geode/blob/c206d5b7/geode-core/src/test/java/org/apache/geode/test/dunit/rules/DistributedRestoreSystemProperties.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/rules/DistributedRestoreSystemProperties.java b/geode-core/src/test/java/org/apache/geode/test/dunit/rules/DistributedRestoreSystemProperties.java
index 6b9102e..21c2f45 100755
--- a/geode-core/src/test/java/org/apache/geode/test/dunit/rules/DistributedRestoreSystemProperties.java
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/rules/DistributedRestoreSystemProperties.java
@@ -46,7 +46,7 @@ public class DistributedRestoreSystemProperties extends RestoreSystemProperties
   @Override
   public void before() throws Throwable {
     super.before();
-    this.invoker.remoteInvokeInEveryVMAndLocator(new SerializableRunnable() {
+    this.invoker.invokeInEveryVMAndController(new SerializableRunnable() {
       @Override
       public void run() {
         originalProperties = getProperties();
@@ -58,7 +58,7 @@ public class DistributedRestoreSystemProperties extends RestoreSystemProperties
   @Override
   public void after() {
     super.after();
-    this.invoker.remoteInvokeInEveryVMAndLocator(new SerializableRunnable() {
+    this.invoker.invokeInEveryVMAndController(new SerializableRunnable() {
       @Override
       public void run() {
         setProperties(originalProperties);

http://git-wip-us.apache.org/repos/asf/geode/blob/c206d5b7/geode-core/src/test/java/org/apache/geode/test/dunit/rules/DistributedRule.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/rules/DistributedRule.java b/geode-core/src/test/java/org/apache/geode/test/dunit/rules/DistributedRule.java
new file mode 100644
index 0000000..8e89bdb
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/rules/DistributedRule.java
@@ -0,0 +1,66 @@
+/*
+ * 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 java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.junit.Rule;
+
+/**
+ * Annotates a field or method as a type of {@link Rule} that can be invoked across multiple VMs in
+ * a {@code DistributedTest}.
+ *
+ * If there are multiple annotated {@code DistributedRule}s on a class, they will be applied in
+ * order of fields first, then methods. Furthermore, if there are multiple fields (or methods) they
+ * will be applied in an order that depends on your JVM's implementation of the reflection API,
+ * which is undefined. Rules defined by fields will always be applied before Rules defined by
+ * methods. You can use a {@link org.junit.rules.RuleChain} or
+ * {@link org.apache.geode.test.junit.rules.RuleList} if you want to have control over the order in
+ * which the Rules are applied.
+ *
+ * <p>
+ * For example, here is a test class that makes a unique {@link org.junit.rules.TemporaryFolder}
+ * available to each DUnit VM:
+ * 
+ * <pre>
+ * {@literal @}Category(DistributedTest.class)
+ * public class EachVMHasItsOwnTemporaryFolder {
+ *
+ *   {@literal @}DistributedRule
+ *   public TemporaryFolder folder = new TemporaryFolder();
+ *
+ *   {@literal @}Rule
+ *   public DistributedTestRule distributedTestRule = DistributedTestRule.builder().build();
+ *
+ *   {@literal @}Test
+ *   public void eachVMHasItsOwnTemporaryFolder() throws Exception {
+ *     Host.getHost(0).getVM(0).invoke(() -> {
+ *       File gemfireProps = folder.newFile({@literal "}gemfire.properties{@literal "});
+ *       File diskDirs = folder.newFolder({@literal "}diskDirs{@literal "});
+ *       ...
+ *     }
+ *   }
+ * }
+ * </pre>
+ *
+ * @see org.apache.geode.test.junit.rules.serializable.SerializableTestRule
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.FIELD, ElementType.METHOD})
+public @interface DistributedRule {
+}

http://git-wip-us.apache.org/repos/asf/geode/blob/c206d5b7/geode-core/src/test/java/org/apache/geode/test/dunit/rules/DistributedRunRules.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/rules/DistributedRunRules.java b/geode-core/src/test/java/org/apache/geode/test/dunit/rules/DistributedRunRules.java
new file mode 100644
index 0000000..7a86613
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/rules/DistributedRunRules.java
@@ -0,0 +1,76 @@
+/*
+ * 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 java.io.Serializable;
+
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+import org.apache.geode.test.dunit.Host;
+import org.apache.geode.test.dunit.SerializableRunnable;
+
+/**
+ * Runs Rules in specified DUnit VMs.
+ */
+public class DistributedRunRules extends Statement implements Serializable {
+  private final Statement statement;
+  private final WhichVMs whichVMs;
+
+  public DistributedRunRules(final Statement base, final Iterable<TestRule> rules,
+      final Description description, final WhichVMs whichVMs) {
+    this.statement = applyAll(base, rules, description);
+    this.whichVMs = whichVMs;
+  }
+
+  @Override
+  public void evaluate() throws Throwable {
+    if (this.whichVMs.controllerVM()) {
+      this.statement.evaluate();
+    }
+    if (this.whichVMs.everyVM()) {
+      for (int i = 0; i < Host.getHost(0).getVMCount(); i++) {
+        Host.getHost(0).getVM(i).invoke(runnable());
+      }
+    }
+    if (this.whichVMs.locatorVM()) {
+      Host.getHost(0).getLocator().invoke(runnable());
+    }
+  }
+
+  private Statement applyAll(Statement result, final Iterable<TestRule> rules,
+      final Description description) {
+    for (TestRule each : rules) {
+      result = each.apply(result, description);
+    }
+    return result;
+  }
+
+  private SerializableRunnable runnable() {
+    return new SerializableRunnable() {
+      @Override
+      public void run() {
+        try {
+          DistributedRunRules.this.statement.evaluate();
+        } catch (Error | RuntimeException e) {
+          throw e;
+        } catch (Throwable t) {
+          throw new RuntimeException(t);
+        }
+      }
+    };
+  }
+}

http://git-wip-us.apache.org/repos/asf/geode/blob/c206d5b7/geode-core/src/test/java/org/apache/geode/test/dunit/rules/DistributedStatement.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/rules/DistributedStatement.java b/geode-core/src/test/java/org/apache/geode/test/dunit/rules/DistributedStatement.java
new file mode 100644
index 0000000..cdc8dda
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/rules/DistributedStatement.java
@@ -0,0 +1,75 @@
+/*
+ * 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 java.io.Serializable;
+
+import org.junit.runners.model.Statement;
+
+import org.apache.geode.test.dunit.Host;
+import org.apache.geode.test.dunit.SerializableRunnable;
+import org.apache.geode.test.junit.rules.serializable.SerializableStatement;
+
+/**
+ * Invokes Statement in specified DUnit VMs.
+ */
+public class DistributedStatement extends SerializableStatement {
+  private final SerializableStatement next;
+  private final WhichVMs whichVMs;
+
+  /**
+   * Construct a new {@code DistributedStatement} statement.
+   * 
+   * @param next the next {@code Statement} in the execution chain
+   * @param whichVMs specifies which VMs should invoke the statement
+   */
+  public DistributedStatement(final SerializableStatement next, final WhichVMs whichVMs) {
+    this.next = next;
+    this.whichVMs = whichVMs;
+  }
+
+  /**
+   * Invoke the {@link Statement} in the specified VMs.
+   */
+  @Override
+  public void evaluate() throws Throwable {
+    if (this.whichVMs.controllerVM()) {
+      this.next.evaluate();
+    }
+    if (this.whichVMs.everyVM()) {
+      for (int i = 0; i < Host.getHost(0).getVMCount(); i++) {
+        Host.getHost(0).getVM(i).invoke(runnable());
+      }
+    }
+    if (this.whichVMs.locatorVM()) {
+      Host.getHost(0).getLocator().invoke(runnable());
+    }
+  }
+
+  private SerializableRunnable runnable() {
+    return new SerializableRunnable() {
+      @Override
+      public void run() {
+        try {
+          next.evaluate();
+        } catch (Error | RuntimeException e) {
+          throw e;
+        } catch (Throwable t) {
+          throw new RuntimeException(t);
+        }
+      }
+    };
+  }
+}

http://git-wip-us.apache.org/repos/asf/geode/blob/c206d5b7/geode-core/src/test/java/org/apache/geode/test/dunit/rules/DistributedTestRule.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/rules/DistributedTestRule.java b/geode-core/src/test/java/org/apache/geode/test/dunit/rules/DistributedTestRule.java
new file mode 100644
index 0000000..31fba3d
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/rules/DistributedTestRule.java
@@ -0,0 +1,200 @@
+/*
+ * 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 java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.rules.MethodRule;
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.Statement;
+import org.junit.runners.model.TestClass;
+
+import org.apache.geode.test.dunit.standalone.DUnitLauncher;
+
+/**
+ * Launches the DUnit framework for a {@code DistributedTest}.
+ *
+ * <p>
+ * Enables use of {@link DistributedRule} annotations on any Rules.
+ *
+ * <pre>
+ * {@literal @}Category(DistributedTest.class)
+ * public class QueryDataDUnitTest {
+ *
+ *   {@literal @}DistributedRule
+ *   public UseJacksonForJsonPathRule useJacksonForJsonPathRule = new UseJacksonForJsonPathRule();
+ *
+ *   {@literal @}Rule
+ *   public DistributedTestRule distributedTestRule = DistributedTestRule.builder().build();
+ *
+ *   ...
+ * }
+ * </pre>
+ * <p>
+ * Use the {@code Builder} to specify which {@code VM}s should invoke any {@code Rule} annotated
+ * with {@literal @}DistributedRule. By default, {@code controllerVM} is {@code true},
+ * {@code everyVM} is {@code true} and {@code locatorVM} is {@code false}.
+ */
+public class DistributedTestRule implements MethodRule, Serializable {
+
+  public static Builder builder() {
+    return new Builder();
+  }
+
+  private TestClass testClass;
+
+  private final List<?> rules = new ArrayList<>(); // types are TestRule or MethodRule
+
+  private final RemoteInvoker invoker;
+
+  private final WhichVMs whichVMs;
+
+  // TODO: add ability to specify ordering of DistributedRules
+
+  protected DistributedTestRule(final Builder builder) {
+    this(new RemoteInvoker(), builder);
+  }
+
+  protected DistributedTestRule(final RemoteInvoker invoker, final Builder builder) {
+    this.invoker = invoker;
+
+    this.whichVMs = new WhichVMs();
+    if (builder.controllerVM) {
+      this.whichVMs.addControllerVM();
+    }
+    if (builder.everyVM) {
+      this.whichVMs.addEveryVM();
+    }
+    if (builder.locatorVM) {
+      this.whichVMs.addLocatorVM();
+    }
+  }
+
+  @Override
+  public Statement apply(final Statement base, final FrameworkMethod method, final Object target) {
+    this.testClass = new TestClass(target.getClass());
+    Statement statement = base;
+    statement = withRules(method, target, statement);
+    statement = withDUnit(method, target, statement);
+    return statement;
+  }
+
+  protected Statement withDUnit(final FrameworkMethod method, final Object target,
+      final Statement statement) {
+    return new Statement() {
+      @Override
+      public void evaluate() throws Throwable {
+        setUpDUnit();
+        try {
+          statement.evaluate();
+        } finally {
+          tearDownDUnit();
+        }
+      }
+    };
+  }
+
+  protected void setUpDUnit() throws Exception {
+    DUnitLauncher.launchIfNeeded();
+    // TODO: customize based on fields
+  }
+
+  protected void tearDownDUnit() throws Exception {}
+
+  protected Statement withRules(final FrameworkMethod method, final Object target,
+      final Statement statement) {
+    List<TestRule> testRules = this.testRules(target);
+    Statement result = statement;
+    // result = withMethodRules(method, testRules, target, result);
+    result = withTestRules(method, testRules, result);
+
+    return result;
+  }
+
+  // protected Statement withMethodRules(final FrameworkMethod method, final List<TestRule>
+  // testRules, final Object target, final Statement result) {
+  // Statement statement = result;
+  // for (MethodRule rule : methodRules(target)) {
+  // if (!testRules.contains(rule)) {
+  // statement = new DistributedStatement(rule.apply((result, method, target), this.whichVMs);
+  // }
+  // }
+  // return statement;
+  // }
+
+  protected Statement withTestRules(final FrameworkMethod method, final List<TestRule> testRules,
+      final Statement statement) {
+    Description description = Description.createTestDescription(this.testClass.getJavaClass(),
+        method.getName(), method.getAnnotations());
+    return testRules.isEmpty() ? statement
+        : new DistributedRunRules(statement, testRules, description, this.whichVMs);
+  }
+
+  protected List<MethodRule> methodRules(final Object target) {
+    List<MethodRule> rules =
+        this.testClass.getAnnotatedMethodValues(target, DistributedRule.class, MethodRule.class);
+    rules.addAll(
+        this.testClass.getAnnotatedFieldValues(target, DistributedRule.class, MethodRule.class));
+    return rules;
+  }
+
+  protected List<TestRule> testRules(final Object target) {
+    List<TestRule> result =
+        this.testClass.getAnnotatedMethodValues(target, DistributedRule.class, TestRule.class);
+    result.addAll(
+        this.testClass.getAnnotatedFieldValues(target, DistributedRule.class, TestRule.class));
+    return result;
+  }
+
+  /**
+   * Builds an instance of {@link DistributedTestRule}.
+   *
+   * <p>
+   * By default, {@code controllerVM} is {@code true}, {@code everyVM} is {@code true} and
+   * {@code locatorVM} is {@code false}.
+   */
+  public static class Builder {
+
+    private boolean everyVM = true;
+    private boolean locatorVM = false;
+    private boolean controllerVM = true;
+
+    protected Builder() {}
+
+    public Builder everyVM(final boolean everyVM) {
+      this.everyVM = everyVM;
+      return this;
+    }
+
+    public Builder locatorVM(final boolean locatorVM) {
+      this.locatorVM = locatorVM;
+      return this;
+    }
+
+    public Builder controllerVM(final boolean locatorVM) {
+      this.locatorVM = locatorVM;
+      return this;
+    }
+
+    public DistributedTestRule build() {
+      return new DistributedTestRule(this);
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/geode/blob/c206d5b7/geode-core/src/test/java/org/apache/geode/test/dunit/rules/DistributedUseJacksonForJsonPathRule.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/rules/DistributedUseJacksonForJsonPathRule.java b/geode-core/src/test/java/org/apache/geode/test/dunit/rules/DistributedUseJacksonForJsonPathRule.java
new file mode 100644
index 0000000..8c85775
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/rules/DistributedUseJacksonForJsonPathRule.java
@@ -0,0 +1,50 @@
+/*
+ * 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.junit.rules.UseJacksonForJsonPathRule;
+
+public class DistributedUseJacksonForJsonPathRule extends UseJacksonForJsonPathRule {
+
+  private static UseJacksonForJsonPathRule instance = new UseJacksonForJsonPathRule();
+
+  private final RemoteInvoker invoker;
+
+  public DistributedUseJacksonForJsonPathRule() {
+    this(new RemoteInvoker());
+  }
+
+  public DistributedUseJacksonForJsonPathRule(final RemoteInvoker invoker) {
+    this.invoker = invoker;
+  }
+
+  @Override
+  public void before() {
+    this.invoker.invokeInEveryVMAndController(DistributedUseJacksonForJsonPathRule::invokeBefore);
+  }
+
+  @Override
+  public void after() {
+    this.invoker.invokeInEveryVMAndController(DistributedUseJacksonForJsonPathRule::invokeAfter);
+  }
+
+  private static void invokeBefore() {
+    instance.before();
+  }
+
+  private static void invokeAfter() {
+    instance.after();
+  }
+}

http://git-wip-us.apache.org/repos/asf/geode/blob/c206d5b7/geode-core/src/test/java/org/apache/geode/test/dunit/rules/DistributedWrapperRule.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/rules/DistributedWrapperRule.java b/geode-core/src/test/java/org/apache/geode/test/dunit/rules/DistributedWrapperRule.java
new file mode 100644
index 0000000..6b1f8f1
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/rules/DistributedWrapperRule.java
@@ -0,0 +1,51 @@
+/*
+ * 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.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+import org.apache.geode.test.junit.rules.UseJacksonForJsonPathRule;
+import org.apache.geode.test.junit.rules.serializable.SerializableExternalResource;
+import org.apache.geode.test.junit.rules.serializable.SerializableStatement;
+import org.apache.geode.test.junit.rules.serializable.SerializableTestRule;
+
+public class DistributedWrapperRule implements SerializableTestRule {
+
+  private static SerializableTestRule instance;
+
+  private final RemoteInvoker invoker;
+  private final WhichVMs whichVMs;
+
+  public DistributedWrapperRule(final SerializableTestRule testRule) {
+    this(testRule, new WhichVMs().addControllerVM().addEveryVM());
+  }
+
+  public DistributedWrapperRule(final SerializableTestRule testRule, final WhichVMs whichVMs) {
+    this(new RemoteInvoker(), testRule, whichVMs);
+  }
+
+  public DistributedWrapperRule(final RemoteInvoker invoker, final SerializableTestRule testRule,
+      final WhichVMs whichVMs) {
+    this.invoker = invoker;
+    instance = testRule;
+    this.whichVMs = whichVMs;
+  }
+
+  @Override
+  public Statement apply(Statement base, Description description) {
+    return new DistributedStatement((SerializableStatement) base, whichVMs);
+  }
+}

http://git-wip-us.apache.org/repos/asf/geode/blob/c206d5b7/geode-core/src/test/java/org/apache/geode/test/dunit/rules/RemoteInvoker.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/rules/RemoteInvoker.java b/geode-core/src/test/java/org/apache/geode/test/dunit/rules/RemoteInvoker.java
index 6398e45..866a0d5 100755
--- a/geode-core/src/test/java/org/apache/geode/test/dunit/rules/RemoteInvoker.java
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/rules/RemoteInvoker.java
@@ -18,7 +18,8 @@ import static org.apache.geode.test.dunit.Invoke.*;
 
 import java.io.Serializable;
 
-import org.apache.geode.test.dunit.SerializableRunnable;
+import org.apache.geode.test.dunit.Invoke;
+import org.apache.geode.test.dunit.SerializableRunnableIF;
 
 /**
  * Provides remote invocation support to a {@code TestRule}. These methods will invoke a
@@ -28,18 +29,21 @@ class RemoteInvoker implements Serializable {
 
   private static final long serialVersionUID = -1759722991299584649L;
 
-  public void invokeEverywhere(final SerializableRunnable runnable) {
+  // controller VM
+  // dunit VMs
+  // locator VM
+
+  public void invokeInEveryVMAndController(final SerializableRunnableIF runnable) {
     try {
       runnable.run();
     } catch (Exception e) {
       throw new RuntimeException(e);
     }
-    invokeInEveryVM(runnable);
-    invokeInLocator(runnable);
+    Invoke.invokeInEveryVM(runnable);
   }
 
-  public void remoteInvokeInEveryVMAndLocator(final SerializableRunnable runnable) {
-    invokeInEveryVM(runnable);
+  public void invokeInEveryVMAndLocator(final SerializableRunnableIF runnable) {
+    Invoke.invokeInEveryVM(runnable);
     invokeInLocator(runnable);
   }
 }

http://git-wip-us.apache.org/repos/asf/geode/blob/c206d5b7/geode-core/src/test/java/org/apache/geode/test/dunit/rules/WhichVMs.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/rules/WhichVMs.java b/geode-core/src/test/java/org/apache/geode/test/dunit/rules/WhichVMs.java
new file mode 100644
index 0000000..1048f2e
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/rules/WhichVMs.java
@@ -0,0 +1,59 @@
+/*
+ * 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 java.io.Serializable;
+
+/**
+ * Specifies which DUnit VMs will invoke a Rule.
+ *
+ * TODO: add ability to specify specific VMs
+ *
+ * TODO: add ability to specify order
+ */
+public class WhichVMs implements Serializable {
+  private boolean controllerVM;
+  private boolean everyVM;
+  private boolean locatorVM;
+
+  public WhichVMs() {}
+
+  public WhichVMs addControllerVM() {
+    this.controllerVM = true;
+    return this;
+  }
+
+  public WhichVMs addEveryVM() {
+    this.everyVM = true;
+    return this;
+  }
+
+  public WhichVMs addLocatorVM() {
+    this.locatorVM = true;
+    return this;
+  }
+
+  public boolean controllerVM() {
+    return this.controllerVM;
+  }
+
+  public boolean everyVM() {
+    return this.everyVM;
+  }
+
+  public boolean locatorVM() {
+    return this.locatorVM;
+  }
+}

http://git-wip-us.apache.org/repos/asf/geode/blob/c206d5b7/geode-core/src/test/java/org/apache/geode/test/dunit/standalone/DUnitLauncher.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/standalone/DUnitLauncher.java b/geode-core/src/test/java/org/apache/geode/test/dunit/standalone/DUnitLauncher.java
index 8587ea5..d6f2013 100644
--- a/geode-core/src/test/java/org/apache/geode/test/dunit/standalone/DUnitLauncher.java
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/standalone/DUnitLauncher.java
@@ -36,21 +36,51 @@ import org.apache.logging.log4j.core.appender.FileAppender;
 import org.apache.logging.log4j.core.config.LoggerConfig;
 import org.apache.logging.log4j.core.layout.PatternLayout;
 import org.junit.Assert;
+import static org.apache.geode.distributed.ConfigurationProperties.*;
 
-import java.io.*;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.IOException;
 import java.lang.reflect.Method;
 import java.net.InetAddress;
 import java.net.URISyntaxException;
 import java.nio.channels.FileChannel;
 import java.nio.charset.Charset;
-import java.rmi.*;
+import java.rmi.AccessException;
+import java.rmi.AlreadyBoundException;
+import java.rmi.NotBoundException;
+import java.rmi.Remote;
+import java.rmi.RemoteException;
 import java.rmi.registry.LocateRegistry;
 import java.rmi.registry.Registry;
 import java.rmi.server.UnicastRemoteObject;
 import java.util.List;
 import java.util.Properties;
 
-import static org.apache.geode.distributed.ConfigurationProperties.*;
+import batterytest.greplogs.ExpectedStrings;
+import batterytest.greplogs.LogConsumer;
+import hydra.MethExecutorResult;
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.appender.FileAppender;
+import org.apache.logging.log4j.core.config.LoggerConfig;
+import org.apache.logging.log4j.core.layout.PatternLayout;
+import org.junit.Assert;
+
+import org.apache.geode.distributed.Locator;
+import org.apache.geode.distributed.internal.DistributionConfig;
+import org.apache.geode.distributed.internal.InternalLocator;
+import org.apache.geode.distributed.internal.membership.gms.membership.GMSJoinLeave;
+import org.apache.geode.internal.AvailablePortHelper;
+import org.apache.geode.internal.logging.LogService;
+import org.apache.geode.test.dunit.DUnitEnv;
+import org.apache.geode.test.dunit.Host;
+import org.apache.geode.test.dunit.SerializableCallable;
+import org.apache.geode.test.dunit.VM;
 
 /**
  * A class to build a fake test configuration and launch some DUnit VMS.
@@ -75,6 +105,9 @@ public class DUnitLauncher {
   private static final int LOCATOR_VM_NUM = -2;
 
   static final long STARTUP_TIMEOUT = 120 * 1000;
+  private static final String STARTUP_TIMEOUT_MESSAGE =
+      "VMs did not start up within " + (STARTUP_TIMEOUT / 1000) + " seconds";
+
   private static final String SUSPECT_FILENAME = "dunit_suspect.log";
   private static File DUNIT_SUSPECT_FILE;
 
@@ -195,7 +228,7 @@ public class DUnitLauncher {
 
     // wait for the VM to start up
     if (!processManager.waitForVMs(STARTUP_TIMEOUT)) {
-      throw new RuntimeException("VMs did not start up with 30 seconds");
+      throw new RuntimeException("VMs did not start up within 30 seconds");
     }
 
     locatorPort = startLocator(registry);
@@ -210,7 +243,7 @@ public class DUnitLauncher {
 
     // wait for the VMS to start up
     if (!processManager.waitForVMs(STARTUP_TIMEOUT)) {
-      throw new RuntimeException("VMs did not start up with 30 seconds");
+      throw new RuntimeException("VMs did not start up within 30 seconds");
     }
 
     // populate the Host class with our stubs. The tests use this host class

http://git-wip-us.apache.org/repos/asf/geode/blob/c206d5b7/geode-core/src/test/resources/org/apache/geode/codeAnalysis/sanctionedSerializables.txt
----------------------------------------------------------------------
diff --git a/geode-core/src/test/resources/org/apache/geode/codeAnalysis/sanctionedSerializables.txt b/geode-core/src/test/resources/org/apache/geode/codeAnalysis/sanctionedSerializables.txt
index 9626be7..61c139d 100755
--- a/geode-core/src/test/resources/org/apache/geode/codeAnalysis/sanctionedSerializables.txt
+++ b/geode-core/src/test/resources/org/apache/geode/codeAnalysis/sanctionedSerializables.txt
@@ -482,7 +482,9 @@ org/apache/geode/internal/util/concurrent/StoppableReentrantReadWriteLock,true,-
 org/apache/geode/lang/AttachAPINotFoundException,true,-5953162090462085551
 org/apache/geode/management/AlreadyRunningException,true,8947734854770335071
 org/apache/geode/management/DependenciesNotFoundException,true,9082304929238159814
+org/apache/geode/management/JVMMetrics,false,committedMemory:long,gcCount:long,gcTimeMillis:long,initMemory:long,maxMemory:long,totalThreads:int,usedMemory:long
 org/apache/geode/management/ManagementException,true,879398950879472121
+org/apache/geode/management/OSMetrics,false,arch:java/lang/String,availableProcessors:int,committedVirtualMemorySize:long,freePhysicalMemorySize:long,freeSwapSpaceSize:long,maxFileDescriptorCount:long,name:java/lang/String,openFileDescriptorCount:long,processCpuTime:long,systemLoadAverage:double,totalPhysicalMemorySize:long,totalSwapSpaceSize:long,version:java/lang/String
 org/apache/geode/management/cli/CommandProcessingException,true,-1398779521639575884,errorData:java/lang/Object,errorType:int
 org/apache/geode/management/cli/CommandServiceException,true,7316102209844678329
 org/apache/geode/management/cli/Result$Status,false,code:int
@@ -561,7 +563,6 @@ org/apache/geode/management/internal/cli/functions/DestroyDiskStoreFunction,true
 org/apache/geode/management/internal/cli/functions/DestroyIndexFunction,true,1
 org/apache/geode/management/internal/cli/functions/ExportConfigFunction,true,1
 org/apache/geode/management/internal/cli/functions/ExportDataFunction,true,1
-org/apache/geode/management/internal/cli/functions/ExportSharedConfigurationFunction,true,1
 org/apache/geode/management/internal/cli/functions/FetchRegionAttributesFunction,true,4366812590788342070
 org/apache/geode/management/internal/cli/functions/FetchRegionAttributesFunction$FetchRegionAttributesFunctionResult,true,-3970828263897978845,cacheListenerClasses:java/lang/String[],cacheLoaderClass:java/lang/String,cacheWriterClass:java/lang/String,regionAttributes:org/apache/geode/cache/RegionAttributes
 org/apache/geode/management/internal/cli/functions/FetchSharedConfigurationStatusFunction,true,1
@@ -579,14 +580,12 @@ org/apache/geode/management/internal/cli/functions/GetRegionsFunction,true,1
 org/apache/geode/management/internal/cli/functions/GetStackTracesFunction,true,1
 org/apache/geode/management/internal/cli/functions/GetSubscriptionQueueSizeFunction,true,1
 org/apache/geode/management/internal/cli/functions/ImportDataFunction,true,1
-org/apache/geode/management/internal/cli/functions/ImportSharedConfigurationArtifactsFunction,true,1
 org/apache/geode/management/internal/cli/functions/ListAsyncEventQueuesFunction,true,1
 org/apache/geode/management/internal/cli/functions/ListDeployedFunction,true,1
 org/apache/geode/management/internal/cli/functions/ListDiskStoresFunction,false
 org/apache/geode/management/internal/cli/functions/ListDurableCqNamesFunction,true,1
 org/apache/geode/management/internal/cli/functions/ListFunctionFunction,true,1
 org/apache/geode/management/internal/cli/functions/ListIndexFunction,false
-org/apache/geode/management/internal/cli/functions/LoadSharedConfigurationFunction,true,1
 org/apache/geode/management/internal/cli/functions/LogFileFunction,true,1
 org/apache/geode/management/internal/cli/functions/MemberRegionFunction,true,1
 org/apache/geode/management/internal/cli/functions/MembersForRegionFunction,true,8746830191680509335
@@ -625,11 +624,6 @@ org/apache/geode/management/internal/cli/util/MemberInformation,true,1,cacheXmlF
 org/apache/geode/management/internal/cli/util/MemberNotFoundException,true,5686788909239181174
 org/apache/geode/management/internal/cli/util/VisualVmNotFoundException,true,-8491645604829510102
 org/apache/geode/management/internal/configuration/domain/SharedConfigurationStatus,false
-org/apache/geode/management/internal/configuration/functions/AddJarFunction,true,1
-org/apache/geode/management/internal/configuration/functions/AddXmlEntityFunction,true,1
-org/apache/geode/management/internal/configuration/functions/DeleteJarFunction,true,1
-org/apache/geode/management/internal/configuration/functions/DeleteXmlEntityFunction,true,1
-org/apache/geode/management/internal/configuration/functions/ModifyXmlAndPropertiesFunction,true,1
 org/apache/geode/management/internal/configuration/functions/UploadJarFunction,true,1
 org/apache/geode/management/internal/web/domain/Link,false,href:java/net/URI,method:org/apache/geode/management/internal/web/http/HttpMethod,relation:java/lang/String
 org/apache/geode/management/internal/web/domain/QueryParameterSource,true,34131123582155,objectName:javax/management/ObjectName,queryExpression:javax/management/QueryExp

http://git-wip-us.apache.org/repos/asf/geode/blob/c206d5b7/geode-junit/build.gradle
----------------------------------------------------------------------
diff --git a/geode-junit/build.gradle b/geode-junit/build.gradle
index f7e5e46..e47095f 100755
--- a/geode-junit/build.gradle
+++ b/geode-junit/build.gradle
@@ -16,6 +16,7 @@
  */
 
 dependencies {
+  compile 'com.jayway.jsonpath:json-path:' + project.'json-path.version'
   testCompile 'commons-lang:commons-lang:' + project.'commons-lang.version'
   testCompile 'com.google.guava:guava:' + project.'guava.version'
   testCompile 'org.assertj:assertj-core:' + project.'assertj-core.version'

http://git-wip-us.apache.org/repos/asf/geode/blob/c206d5b7/geode-junit/src/main/java/org/apache/geode/test/junit/rules/UseJacksonForJsonPathRule.java
----------------------------------------------------------------------
diff --git a/geode-junit/src/main/java/org/apache/geode/test/junit/rules/UseJacksonForJsonPathRule.java b/geode-junit/src/main/java/org/apache/geode/test/junit/rules/UseJacksonForJsonPathRule.java
new file mode 100644
index 0000000..c7c326a
--- /dev/null
+++ b/geode-junit/src/main/java/org/apache/geode/test/junit/rules/UseJacksonForJsonPathRule.java
@@ -0,0 +1,128 @@
+/*
+ * 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.EnumSet;
+import java.util.Set;
+
+import com.jayway.jsonpath.Configuration;
+import com.jayway.jsonpath.Configuration.Defaults;
+import com.jayway.jsonpath.Option;
+import com.jayway.jsonpath.spi.json.JacksonJsonProvider;
+import com.jayway.jsonpath.spi.json.JsonProvider;
+import com.jayway.jsonpath.spi.mapper.JacksonMappingProvider;
+import com.jayway.jsonpath.spi.mapper.MappingProvider;
+
+import org.apache.geode.test.junit.rules.serializable.SerializableExternalResource;
+
+/**
+ * JUnit Rule that configures json-path to use the {@code JacksonJsonProvider}
+ *
+ * <p>
+ * UseJacksonForJsonPathRule can be used in tests that need to use json-path-assert:
+ * 
+ * <pre>
+ * {@literal @}ClassRule
+ * public static UseJacksonForJsonPathRule useJacksonForJsonPathRule = new UseJacksonForJsonPathRule();
+ *
+ * {@literal @}Test
+ * public void hasAssertionsUsingJsonPathMatchers() {
+ *   ...
+ *   assertThat(json, isJson());
+ *   assertThat(json, hasJsonPath("$.result"));
+ * }
+ * </pre>
+ */
+@SuppressWarnings({"serial", "unused"})
+public class UseJacksonForJsonPathRule extends SerializableExternalResource {
+
+  private boolean hadDefaults;
+  private JsonProvider jsonProvider;
+  private MappingProvider mappingProvider;
+  private Set<Option> options;
+
+  /**
+   * Override to set up your specific external resource.
+   */
+  @Override
+  public void before() {
+    saveDefaults();
+    Configuration.setDefaults(new Defaults() {
+
+      private final JsonProvider jsonProvider = new JacksonJsonProvider();
+      private final MappingProvider mappingProvider = new JacksonMappingProvider();
+
+      @Override
+      public JsonProvider jsonProvider() {
+        return jsonProvider;
+      }
+
+      @Override
+      public MappingProvider mappingProvider() {
+        return mappingProvider;
+      }
+
+      @Override
+      public Set<Option> options() {
+        return EnumSet.noneOf(Option.class);
+      }
+
+    });
+  }
+
+  /**
+   * Override to tear down your specific external resource.
+   */
+  @Override
+  public void after() {
+    restoreDefaults();
+  }
+
+  private void saveDefaults() {
+    try {
+      Configuration defaultConfiguration = Configuration.defaultConfiguration();
+      this.jsonProvider = defaultConfiguration.jsonProvider();
+      this.mappingProvider = defaultConfiguration.mappingProvider();
+      this.options = defaultConfiguration.getOptions();
+      this.hadDefaults = true;
+    } catch (NoClassDefFoundError ignore) {
+      this.hadDefaults = false;
+    }
+  }
+
+  private void restoreDefaults() {
+    if (!this.hadDefaults) {
+      return;
+    }
+    Configuration.setDefaults(new Defaults() {
+
+      @Override
+      public JsonProvider jsonProvider() {
+        return jsonProvider;
+      }
+
+      @Override
+      public MappingProvider mappingProvider() {
+        return mappingProvider;
+      }
+
+      @Override
+      public Set<Option> options() {
+        return options;
+      }
+
+    });
+  }
+}


Mime
View raw message