You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by kl...@apache.org on 2017/09/22 17:15:38 UTC

[geode] branch develop updated: GEODE-3638: cleanup minor issues found while prepping dunit talk

This is an automated email from the ASF dual-hosted git repository.

klund 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 f5f59f0  GEODE-3638: cleanup minor issues found while prepping dunit talk
f5f59f0 is described below

commit f5f59f060adf009a44c604d4f050cb290b415159
Author: Kirk Lund <kl...@apache.org>
AuthorDate: Mon Sep 18 09:05:52 2017 -0700

    GEODE-3638: cleanup minor issues found while prepping dunit talk
    
    * fix some dunit rules
    * add some dunit rule tests
    * add dunit examples
---
 .../org/apache/geode/cache30/CacheTestCase.java    |  10 +-
 .../java/org/apache/geode/test/dunit/Assert.java   |  14 +-
 .../apache/geode/test/dunit/AsyncInvocation.java   |   2 +
 .../apache/geode/test/dunit/DUnitBlackboard.java   |   8 +-
 .../java/org/apache/geode/test/dunit/DUnitEnv.java |   9 +-
 .../org/apache/geode/test/dunit/DebuggerUtils.java |  13 +-
 .../geode/test/dunit/DistributedTestUtils.java     |  20 ++-
 .../java/org/apache/geode/test/dunit/Host.java     |  33 +---
 .../dunit/cache}/CacheTestCase.java                |   2 +-
 .../cache/examples/CacheTestCaseExampleTest.java   |  27 +--
 .../dunit/cache/internal/JUnit3CacheTestCase.java  |  10 +-
 .../dunit/cache/internal/JUnit4CacheTestCase.java  | 172 ++++++++-----------
 .../examples/AsyncInvokeCallableExampleTest.java   |  92 ++++++++++
 .../AsyncInvokeRunnableExampleTest.java}           |  43 ++---
 .../BeforeClassExampleTest.java}                   |  32 ++--
 .../CatchingUnexpectedExceptionExampleTest.java    |  98 +++++++++++
 .../DistributedTestCaseExampleTest.java}           |  33 ++--
 .../DistributedTestRuleExampleTest.java}           |  32 ++--
 ...DoNotHandleUnexpectedExceptionExampleTest.java} |  43 +++--
 .../FixtureOrderingExampleTest.java}               |  52 +++---
 .../dunit/examples/InvokeCallableExampleTest.java  |  55 ++++++
 .../InvokeRunnableExampleTest.java}                |  36 ++--
 .../examples/LocatorPortClusterExampleTest.java    |  73 ++++++++
 .../ReplaceTryFinallyExampleTest.java}             |  48 +++---
 .../dunit/internal/JUnit3DistributedTestCase.java  |   5 +
 .../dunit/rules/DistributedDisconnectRule.java     |  57 ++++++-
 .../dunit/rules/DistributedExternalResource.java   |   2 +-
 ...ernalResource.java => DistributedTestRule.java} |  37 ++--
 .../DistributedDisconnectRuleAsClassRuleTest.java  | 171 +++++++++++++++++++
 .../rules/tests/DistributedDisconnectRuleTest.java | 187 +++++++++++++++++++++
 .../DistributedTestRuleTest.java}                  |  32 ++--
 .../{test => tests}/MemberStarterRuleTest.java     |   3 +-
 .../geode/test/dunit/tests/BasicDUnitTest.java     |   6 +-
 .../tests/GetDefaultDiskStoreNameDUnitTest.java    |   4 +-
 .../dunit/tests/GetTestMethodNameDUnitTest.java    |   4 +-
 ...Test.java => GetUniqueNameDistributedTest.java} |  34 ++--
 .../test/dunit/tests/JUnit4BasicDUnitTest.java     |   4 +-
 .../JUnit4GetDefaultDiskStoreNameDUnitTest.java    |   1 +
 .../tests/JUnit4GetTestMethodNameDUnitTest.java    |   1 +
 ...ridingGetPropertiesDisconnectsAllDUnitTest.java |   1 +
 .../geode/test/dunit/tests/JUnit4VMDUnitTest.java  |   1 +
 ...ridingGetPropertiesDisconnectsAllDUnitTest.java |   5 +-
 .../apache/geode/test/dunit/tests/VMDUnitTest.java |   1 +
 .../junit/rules/DescribedExternalResource.java     |   2 +-
 .../serializable/SerializableExternalResource.java |   2 +-
 .../runners/CategoryWithParameterizedRunner.java   |   9 +-
 .../CategoryWithParameterizedRunnerFactory.java    |   7 +-
 .../{runner => runners}/SuiteBlockRunner.java      |  12 +-
 .../junit/{runner => runners}/SuiteRunner.java     |  28 +--
 .../geode/test/junit/runners}/TestRunner.java      |   2 +-
 .../geode/test/junit/categories/CategoryTest.java  |   2 +-
 .../test/junit/rules/ExpectedTimeoutRuleTest.java  |   1 +
 .../test/junit/rules/IgnoreUntilRuleTest.java      |   1 +
 .../geode/test/junit/rules/RepeatRuleTest.java     |   1 +
 .../test/junit/rules/RestoreLocaleRuleTest.java    |  16 +-
 .../junit/rules/RetryRuleGlobalWithErrorTest.java  |   1 +
 .../rules/RetryRuleGlobalWithExceptionTest.java    |   1 +
 .../junit/rules/RetryRuleLocalWithErrorTest.java   |   1 +
 .../rules/RetryRuleLocalWithExceptionTest.java     |   1 +
 .../geode/test/junit/rules/RuleListTest.java       |   1 +
 .../test/junit/rules/TemporaryFileRuleTest.java    |   1 +
 .../junit/rules/examples/RuleAndClassRuleTest.java |   2 +-
 .../cli/commands/CommandOverHttpDUnitTest.java     |   2 +-
 63 files changed, 1168 insertions(+), 438 deletions(-)

diff --git a/geode-core/src/test/java/org/apache/geode/cache30/CacheTestCase.java b/geode-core/src/test/java/org/apache/geode/cache30/CacheTestCase.java
index 917986d..0e8e3d7 100644
--- a/geode-core/src/test/java/org/apache/geode/cache30/CacheTestCase.java
+++ b/geode-core/src/test/java/org/apache/geode/cache30/CacheTestCase.java
@@ -14,13 +14,9 @@
  */
 package org.apache.geode.cache30;
 
-import org.apache.geode.cache.Cache;
-import org.apache.geode.test.dunit.cache.internal.JUnit4CacheTestCase;
-
 /**
- * The abstract superclass of tests that require the creation of a {@link Cache}.
- *
- * @since GemFire 3.0
+ * @deprecated Please use {@link org.apache.geode.test.dunit.cache.CacheTestCase} instead.
  */
-public abstract class CacheTestCase extends JUnit4CacheTestCase {
+@Deprecated
+public abstract class CacheTestCase extends org.apache.geode.test.dunit.cache.CacheTestCase {
 }
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/Assert.java b/geode-core/src/test/java/org/apache/geode/test/dunit/Assert.java
index fe92a08..ac6f46b 100755
--- a/geode-core/src/test/java/org/apache/geode/test/dunit/Assert.java
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/Assert.java
@@ -14,11 +14,14 @@
  */
 package org.apache.geode.test.dunit;
 
+import org.assertj.core.api.Assertions;
+
 /**
- * Extends <code>org.junit.Assert</code> with additional assertion and fail methods.
- * 
- * These methods can be used directly: <code>Assert.assertIndexDetailsEquals(...)</code>, however,
- * they are intended to be referenced through static import:
+ * Extends {@code org.junit.Assert} with additional assertion and fail methods.
+ *
+ * <p>
+ * These methods can be used directly: {@code Assert.assertIndexDetailsEquals(...)}, however, they
+ * are intended to be referenced through static import:
  *
  * <pre>
  * import static org.apache.geode.test.dunit.Assert.*;
@@ -29,7 +32,10 @@ package org.apache.geode.test.dunit;
  * Extracted from DistributedTestCase.
  * 
  * @see java.lang.AssertionError
+ *
+ * @deprecated Please use AssertJ {@link Assertions} instead.
  */
+@Deprecated
 public class Assert extends org.junit.Assert {
 
   protected Assert() {}
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 057454d..ba80318 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
@@ -47,9 +47,11 @@ import org.apache.geode.SystemFailure;
  * </pre>
  *
  * @param <V> The result type returned by this AsyncInvocation's {@code get} methods
+ *
  * @see VM#invokeAsync(Class, String)
  */
 public class AsyncInvocation<V> implements Future<V> {
+
   // TODO:davidw: Add the ability to get a return value back from the
   // async method call. (Use a static ThreadLocal field that is
   // accessible from the Runnable used in VM#invoke)
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/DUnitBlackboard.java b/geode-core/src/test/java/org/apache/geode/test/dunit/DUnitBlackboard.java
index 62c92bd..b273591 100755
--- a/geode-core/src/test/java/org/apache/geode/test/dunit/DUnitBlackboard.java
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/DUnitBlackboard.java
@@ -24,18 +24,22 @@ import org.apache.geode.test.dunit.internal.InternalBlackboardImpl;
 
 /**
  * DUnitBlackboard provides mailboxes and synchronization gateways for distributed unit tests.
+ *
  * <p>
  * Tests may use the blackboard to pass objects and status between JVMs with mailboxes instead of
  * using static variables in classes. The caveat being that the objects will be serialized using
  * Java serialization.
+ *
  * <p>
  * Gates may be used to synchronize operations between unit test JVMs. Combined with Awaitility
  * these can be used to test for conditions being met, actions having happened, etc.
+ *
  * <p>
  * Look for references to the given methods in your IDE for examples.
  */
 public class DUnitBlackboard {
-  InternalBlackboard blackboard;
+
+  private InternalBlackboard blackboard;
 
   public DUnitBlackboard() {
     blackboard = InternalBlackboardImpl.getInstance();
@@ -75,7 +79,6 @@ public class DUnitBlackboard {
     } catch (RemoteException e) {
       throw new RuntimeException("remote call failed", e);
     }
-
   }
 
   /**
@@ -121,5 +124,4 @@ public class DUnitBlackboard {
       throw new RuntimeException("remote call failed", e);
     }
   }
-
 }
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/DUnitEnv.java b/geode-core/src/test/java/org/apache/geode/test/dunit/DUnitEnv.java
index 45fb919..c363d28 100644
--- a/geode-core/src/test/java/org/apache/geode/test/dunit/DUnitEnv.java
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/DUnitEnv.java
@@ -12,9 +12,6 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-/**
- * 
- */
 package org.apache.geode.test.dunit;
 
 import java.io.File;
@@ -26,14 +23,14 @@ import org.apache.geode.test.dunit.standalone.BounceResult;
 /**
  * This class provides an abstraction over the environment that is used to run dunit. This will
  * delegate to the hydra or to the standalone dunit launcher as needed.
- * 
+ *
+ * <p>
  * Any dunit tests that rely on hydra configuration should go through here, so that we can separate
  * them out from depending on hydra and run them on a different VM launching system.
- * 
  */
 public abstract class DUnitEnv {
 
-  public static DUnitEnv instance = null;
+  private static DUnitEnv instance = null;
 
   public static DUnitEnv get() {
     if (instance == null) {
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/DebuggerUtils.java b/geode-core/src/test/java/org/apache/geode/test/dunit/DebuggerUtils.java
index 2a30a8b..37c6fea 100755
--- a/geode-core/src/test/java/org/apache/geode/test/dunit/DebuggerUtils.java
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/DebuggerUtils.java
@@ -17,10 +17,11 @@ package org.apache.geode.test.dunit;
 import org.apache.geode.internal.util.DebuggerSupport;
 
 /**
- * <code>DebuggerUtils</code> provides static utility methods that facilitate runtime debugging.
- * 
- * These methods can be used directly: <code>DebuggerUtils.attachDebugger(...)</code>, however, they
- * are intended to be referenced through static import:
+ * {@code DebuggerUtils} provides static utility methods that facilitate runtime debugging.
+ *
+ * <p>
+ * These methods can be used directly: {@code DebuggerUtils.attachDebugger(...)}, however, they are
+ * intended to be referenced through static import:
  *
  * <pre>
  * import static org.apache.geode.test.dunit.DebuggerUtils.*;
@@ -34,7 +35,9 @@ import org.apache.geode.internal.util.DebuggerSupport;
  */
 public class DebuggerUtils {
 
-  protected DebuggerUtils() {}
+  protected DebuggerUtils() {
+    // nothing
+  }
 
   @SuppressWarnings("serial")
   public static void attachDebugger(final VM vm, final String message) {
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/DistributedTestUtils.java b/geode-core/src/test/java/org/apache/geode/test/dunit/DistributedTestUtils.java
index effbf25..9903737 100755
--- a/geode-core/src/test/java/org/apache/geode/test/dunit/DistributedTestUtils.java
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/DistributedTestUtils.java
@@ -29,12 +29,12 @@ import java.util.Map;
 import java.util.Properties;
 
 /**
- * <code>DistributedTestUtils</code> provides static utility methods that affect the runtime
- * environment or artifacts generated by a DistributedTest.
- * 
- * These methods can be used directly:
- * <code>DistributedTestUtils.crashDistributedSystem(...)</code>, however, they are intended to be
- * referenced through static import:
+ * {@code DistributedTestUtils} provides static utility methods that affect the runtime environment
+ * or artifacts generated by a DistributedTest.
+ *
+ * <p>
+ * These methods can be used directly: {@code DistributedTestUtils.crashDistributedSystem(...)},
+ * however, they are intended to be referenced through static import:
  *
  * <pre>
  * import static org.apache.geode.test.dunit.DistributedTestUtils.*;
@@ -46,7 +46,9 @@ import java.util.Properties;
  */
 public class DistributedTestUtils {
 
-  protected DistributedTestUtils() {}
+  protected DistributedTestUtils() {
+    // nothing
+  }
 
   /**
    * Fetches the GemFireDescription for this test and adds its DistributedSystem properties to the
@@ -71,8 +73,8 @@ public class DistributedTestUtils {
    * Crash the cache in the given VM in such a way that it immediately stops communicating with
    * peers. This forces the VM's membership manager to throw a ForcedDisconnectException by forcibly
    * terminating the JGroups protocol stack with a fake EXIT event.
+   *
    * <p>
-   * 
    * NOTE: if you use this method be sure that you clean up the VM before the end of your test with
    * disconnectFromDS() or disconnectAllFromDS().
    */
@@ -95,8 +97,8 @@ public class DistributedTestUtils {
    * Crash the cache in the given VM in such a way that it immediately stops communicating with
    * peers. This forces the VM's membership manager to throw a ForcedDisconnectException by forcibly
    * terminating the JGroups protocol stack with a fake EXIT event.
+   *
    * <p>
-   * 
    * NOTE: if you use this method be sure that you clean up the VM before the end of your test with
    * disconnectFromDS() or disconnectAllFromDS().
    */
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/Host.java b/geode-core/src/test/java/org/apache/geode/test/dunit/Host.java
index 4cb6992..2e09172 100755
--- a/geode-core/src/test/java/org/apache/geode/test/dunit/Host.java
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/Host.java
@@ -25,17 +25,13 @@ import org.apache.geode.test.dunit.standalone.RemoteDUnitVMIF;
 import org.apache.geode.test.dunit.standalone.VersionManager;
 
 /**
- * <P>
  * This class represents a host on which a remote method may be invoked. It provides access to the
  * VMs and GemFire systems that run on that host.
- * </P>
  *
- * <P>
+ * <p>
  * Additionally, it provides access to the Java RMI registry that runs on the host. By default, an
  * RMI registry is only started on the host on which Hydra's Master VM runs. RMI registries may be
  * started on other hosts via additional Hydra configuration.
- * </P>
- *
  */
 @SuppressWarnings("serial")
 public abstract class Host implements Serializable {
@@ -48,8 +44,6 @@ public abstract class Host implements Serializable {
   /** Indicates an unstarted RMI registry */
   protected static int NO_REGISTRY = -1;
 
-  //////////////////// Instance Fields ////////////////////
-
   /** The name of this host machine */
   private String hostName;
 
@@ -62,8 +56,6 @@ public abstract class Host implements Serializable {
   /** Key is system name, value is GemFireSystem instance */
   private HashMap systemNames;
 
-  //////////////////// Static Methods /////////////////////
-
   /**
    * Returns the number of known hosts
    */
@@ -72,7 +64,7 @@ public abstract class Host implements Serializable {
   }
 
   /**
-   * Makes note of a new <code>Host</code>
+   * Makes note of a new {@code Host}
    */
   protected static void addHost(Host host) {
     hosts.add(host);
@@ -83,7 +75,7 @@ public abstract class Host implements Serializable {
    *
    * @param n A zero-based identifier of the host
    *
-   * @throws IllegalArgumentException <code>n</code> is more than the number of hosts
+   * @throws IllegalArgumentException {@code n} is more than the number of hosts
    */
   public static Host getHost(int n) {
     int size = hosts.size();
@@ -119,7 +111,7 @@ public abstract class Host implements Serializable {
   ///////////////////// Constructors //////////////////////
 
   /**
-   * Creates a new <code>Host</code> with the given name
+   * Creates a new {@code Host} with the given name
    */
   protected Host(String hostName) {
     if (hostName == null) {
@@ -154,7 +146,7 @@ public abstract class Host implements Serializable {
    *
    * @param n A zero-based identifier of the VM
    *
-   * @throws IllegalArgumentException <code>n</code> is more than the number of VMs
+   * @throws IllegalArgumentException {@code n} is more than the number of VMs
    */
   public VM getVM(int n) {
     int size = vms.size();
@@ -179,17 +171,13 @@ public abstract class Host implements Serializable {
   /**
    * Returns the nth VM of the given version. Optional operation currently supported only in
    * distributedTests.
-   * 
-   * @param version
-   * @param n
-   * @return the requested VM
    */
   public VM getVM(String version, int n) {
     throw new UnsupportedOperationException("Not supported in this implementation of Host");
   }
 
   /**
-   * Adds a VM to this <code>Host</code> with the given process id and client record.
+   * Adds a VM to this {@code Host} with the given process id and client record.
    */
   protected void addVM(int pid, RemoteDUnitVMIF client) {
     VM vm = new VM(this, pid, client);
@@ -215,10 +203,8 @@ public abstract class Host implements Serializable {
     return this.systems.size();
   }
 
-  //////////////////// Utility Methods ////////////////////
-
   public String toString() {
-    StringBuffer sb = new StringBuffer("Host ");
+    StringBuilder sb = new StringBuilder("Host ");
     sb.append(this.getHostName());
     sb.append(" with ");
     sb.append(getVMCount());
@@ -227,7 +213,7 @@ public abstract class Host implements Serializable {
   }
 
   /**
-   * Two <code>Host</code>s are considered equal if they have the same name.
+   * Two {@code Host}s are considered equal if they have the same name.
    */
   public boolean equals(Object o) {
     if (o instanceof Host) {
@@ -239,10 +225,9 @@ public abstract class Host implements Serializable {
   }
 
   /**
-   * A <code>Host</code>'s hash code is based on the hash code of its name.
+   * A {@code Host}'s hash code is based on the hash code of its name.
    */
   public int hashCode() {
     return this.getHostName().hashCode();
   }
-
 }
diff --git a/geode-core/src/test/java/org/apache/geode/cache30/CacheTestCase.java b/geode-core/src/test/java/org/apache/geode/test/dunit/cache/CacheTestCase.java
similarity index 96%
copy from geode-core/src/test/java/org/apache/geode/cache30/CacheTestCase.java
copy to geode-core/src/test/java/org/apache/geode/test/dunit/cache/CacheTestCase.java
index 917986d..3795338 100644
--- a/geode-core/src/test/java/org/apache/geode/cache30/CacheTestCase.java
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/cache/CacheTestCase.java
@@ -12,7 +12,7 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.cache30;
+package org.apache.geode.test.dunit.cache;
 
 import org.apache.geode.cache.Cache;
 import org.apache.geode.test.dunit.cache.internal.JUnit4CacheTestCase;
diff --git a/geode-junit/src/test/java/org/apache/geode/test/junit/rules/TestRunner.java b/geode-core/src/test/java/org/apache/geode/test/dunit/cache/examples/CacheTestCaseExampleTest.java
old mode 100755
new mode 100644
similarity index 56%
copy from geode-junit/src/test/java/org/apache/geode/test/junit/rules/TestRunner.java
copy to geode-core/src/test/java/org/apache/geode/test/dunit/cache/examples/CacheTestCaseExampleTest.java
index 9064a5a..bbc8d4a
--- a/geode-junit/src/test/java/org/apache/geode/test/junit/rules/TestRunner.java
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/cache/examples/CacheTestCaseExampleTest.java
@@ -12,21 +12,24 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.test.junit.rules;
+package org.apache.geode.test.dunit.cache.examples;
 
-import org.junit.runner.JUnitCore;
-import org.junit.runner.Request;
-import org.junit.runner.Result;
+import static org.assertj.core.api.Assertions.assertThat;
 
-/**
- * Used by JUnit rule unit tests to execute inner test cases.
- */
-public class TestRunner {
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import org.apache.geode.internal.cache.InternalCache;
+import org.apache.geode.test.dunit.cache.CacheTestCase;
+import org.apache.geode.test.junit.categories.DistributedTest;
 
-  protected TestRunner() {}
+@Category(DistributedTest.class)
+@SuppressWarnings("serial")
+public class CacheTestCaseExampleTest extends CacheTestCase {
 
-  public static Result runTest(Class<?> test) {
-    JUnitCore junitCore = new JUnitCore();
-    return junitCore.run(Request.aClass(test).getRunner());
+  @Test
+  public void getCacheCreatesCache() throws Exception {
+    InternalCache cache = getCache();
+    assertThat(cache.isClosed()).isFalse();
   }
 }
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/cache/internal/JUnit3CacheTestCase.java b/geode-core/src/test/java/org/apache/geode/test/dunit/cache/internal/JUnit3CacheTestCase.java
index 012cec2..7c88cc3 100644
--- a/geode-core/src/test/java/org/apache/geode/test/dunit/cache/internal/JUnit3CacheTestCase.java
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/cache/internal/JUnit3CacheTestCase.java
@@ -30,11 +30,16 @@ import org.apache.geode.cache30.CacheSerializableRunnable;
 import org.apache.geode.internal.cache.GemFireCacheImpl;
 import org.apache.geode.internal.cache.InternalCache;
 import org.apache.geode.test.dunit.IgnoredException;
+import org.apache.geode.test.dunit.cache.CacheTestCase;
 import org.apache.geode.test.dunit.internal.JUnit3DistributedTestCase;
 
 /**
  * The abstract superclass of tests that require the creation of a {@link Cache}.
+ *
+ * @deprecated Please use {@link CacheTestCase} which extends {@link JUnit4CacheTestCase} when
+ *             writing new tests.
  */
+@Deprecated
 public abstract class JUnit3CacheTestCase extends JUnit3DistributedTestCase
     implements CacheTestFixture {
 
@@ -106,8 +111,11 @@ public abstract class JUnit3CacheTestCase extends JUnit3DistributedTestCase
 
   /**
    * Invokes {@link #getCache()} and casts the return to {@code GemFireCacheImpl}.
+   *
+   * @deprecated Please use {@link #getCache} which returns InternalCache instead.
    */
-  public final GemFireCacheImpl getGemfireCache() { // TODO: remove?
+  @Deprecated
+  public final GemFireCacheImpl getGemfireCache() {
     return delegate.getGemfireCache();
   }
 
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 bc6136f..34507d2 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
@@ -15,6 +15,7 @@
 package org.apache.geode.test.dunit.cache.internal;
 
 import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT;
+import static org.apache.geode.distributed.internal.DistributionConfig.GEMFIRE_PREFIX;
 
 import java.io.File;
 import java.io.FileWriter;
@@ -25,7 +26,6 @@ import java.util.Map;
 import java.util.Properties;
 
 import org.apache.commons.io.FileUtils;
-import org.apache.logging.log4j.Logger;
 
 import org.apache.geode.cache.AttributesFactory;
 import org.apache.geode.cache.Cache;
@@ -42,15 +42,12 @@ import org.apache.geode.cache.client.ClientCache;
 import org.apache.geode.cache.client.ClientCacheFactory;
 import org.apache.geode.cache.client.PoolManager;
 import org.apache.geode.cache30.CacheSerializableRunnable;
-import org.apache.geode.distributed.internal.DistributionConfig;
 import org.apache.geode.distributed.internal.DistributionMessageObserver;
 import org.apache.geode.internal.cache.GemFireCacheImpl;
 import org.apache.geode.internal.cache.InternalCache;
-import org.apache.geode.internal.cache.InternalRegionArguments;
 import org.apache.geode.internal.cache.LocalRegion;
 import org.apache.geode.internal.cache.xmlcache.CacheCreation;
 import org.apache.geode.internal.cache.xmlcache.CacheXmlGenerator;
-import org.apache.geode.internal.logging.LogService;
 import org.apache.geode.test.dunit.Assert;
 import org.apache.geode.test.dunit.IgnoredException;
 import org.apache.geode.test.dunit.Invoke;
@@ -67,8 +64,6 @@ import org.apache.geode.test.dunit.internal.JUnit4DistributedTestCase;
 public abstract class JUnit4CacheTestCase extends JUnit4DistributedTestCase
     implements CacheTestFixture {
 
-  private static final Logger logger = LogService.getLogger();
-
   /**
    * The Cache from which regions are obtained.
    *
@@ -109,25 +104,25 @@ public abstract class JUnit4CacheTestCase extends JUnit4DistributedTestCase
   private final void createCache(final boolean client, final CacheFactory factory) {
     synchronized (JUnit4CacheTestCase.class) {
       try {
-        System.setProperty(
-            DistributionConfig.GEMFIRE_PREFIX + "DISABLE_DISCONNECT_DS_ON_CACHE_CLOSE", "true");
+        System.setProperty(GEMFIRE_PREFIX + "DISABLE_DISCONNECT_DS_ON_CACHE_CLOSE", "true");
         InternalCache newCache;
         if (client) {
-          System.setProperty(DistributionConfig.GEMFIRE_PREFIX + "locators", "");
-          System.setProperty(DistributionConfig.GEMFIRE_PREFIX + MCAST_PORT, "0");
+          System.setProperty(GEMFIRE_PREFIX + "locators", "");
+          System.setProperty(GEMFIRE_PREFIX + MCAST_PORT, "0");
           newCache = (InternalCache) new ClientCacheFactory(getSystem().getProperties()).create();
         } else {
           if (factory == null) {
             newCache = (InternalCache) CacheFactory.create(getSystem());
           } else {
-            Properties props = getSystem().getProperties();
-            for (Map.Entry entry : props.entrySet()) {
+            Properties config = getSystem().getProperties();
+            for (Map.Entry entry : config.entrySet()) {
               factory.set((String) entry.getKey(), (String) entry.getValue());
             }
             newCache = (InternalCache) factory.create();
           }
         }
         cache = newCache;
+
       } catch (CacheExistsException e) {
         Assert.fail("the cache already exists", e); // TODO: remove error handling
 
@@ -136,11 +131,11 @@ public abstract class JUnit4CacheTestCase extends JUnit4DistributedTestCase
 
       } catch (Exception ex) {
         Assert.fail("Checked exception while initializing cache??", ex);
+
       } finally {
-        System.clearProperty(
-            DistributionConfig.GEMFIRE_PREFIX + "DISABLE_DISCONNECT_DS_ON_CACHE_CLOSE");
-        System.clearProperty(DistributionConfig.GEMFIRE_PREFIX + "locators");
-        System.clearProperty(DistributionConfig.GEMFIRE_PREFIX + MCAST_PORT);
+        System.clearProperty(GEMFIRE_PREFIX + "DISABLE_DISCONNECT_DS_ON_CACHE_CLOSE");
+        System.clearProperty(GEMFIRE_PREFIX + "locators");
+        System.clearProperty(GEMFIRE_PREFIX + MCAST_PORT);
       }
     }
   }
@@ -148,24 +143,24 @@ public abstract class JUnit4CacheTestCase extends JUnit4DistributedTestCase
   /**
    * Creates the {@code Cache} for this test that is not connected to other members.
    */
-  public final Cache createLonerCache() {
+  public final InternalCache createLonerCache() {
     synchronized (JUnit4CacheTestCase.class) {
       try {
-        System.setProperty(
-            DistributionConfig.GEMFIRE_PREFIX + "DISABLE_DISCONNECT_DS_ON_CACHE_CLOSE", "true");
+        System.setProperty(GEMFIRE_PREFIX + "DISABLE_DISCONNECT_DS_ON_CACHE_CLOSE", "true");
         InternalCache newCache = (InternalCache) CacheFactory.create(getLonerSystem());
         cache = newCache;
+
       } catch (CacheExistsException e) {
-        Assert.fail("the cache already exists", e); // TODO: remove error handling
+        Assert.fail("the cache already exists", e);
 
       } catch (RuntimeException ex) {
         throw ex;
 
       } catch (Exception ex) {
         Assert.fail("Checked exception while initializing cache??", ex);
+
       } finally {
-        System.clearProperty(
-            DistributionConfig.GEMFIRE_PREFIX + "DISABLE_DISCONNECT_DS_ON_CACHE_CLOSE");
+        System.clearProperty(GEMFIRE_PREFIX + "DISABLE_DISCONNECT_DS_ON_CACHE_CLOSE");
       }
       return cache;
     }
@@ -188,11 +183,10 @@ public abstract class JUnit4CacheTestCase extends JUnit4DistributedTestCase
     synchronized (JUnit4CacheTestCase.class) {
       File file = new File(name + "-cache.xml");
       try {
-        PrintWriter pw = new PrintWriter(new FileWriter(file), true);
-        CacheXmlGenerator.generate(cache, pw);
-        pw.close();
+        PrintWriter printWriter = new PrintWriter(new FileWriter(file), true);
+        CacheXmlGenerator.generate(cache, printWriter);
+        printWriter.close();
       } catch (IOException ex) {
-        // TODO: remove error handling
         Assert.fail("IOException during cache.xml generation to " + file, ex);
       }
       // TODO: System.setProperty(GEMFIRE_PREFIX + CACHE_XML_FILE, file.getAbsolutePath());
@@ -217,9 +211,9 @@ public abstract class JUnit4CacheTestCase extends JUnit4DistributedTestCase
       dir.mkdirs();
       File file = new File(dir, name + ".xml");
       try {
-        PrintWriter pw = new PrintWriter(new FileWriter(file), true);
-        CacheXmlGenerator.generate(cache, pw, useSchema, xmlVersion);
-        pw.close();
+        PrintWriter printWriter = new PrintWriter(new FileWriter(file), true);
+        CacheXmlGenerator.generate(cache, printWriter, useSchema, xmlVersion);
+        printWriter.close();
       } catch (IOException ex) {
         // TODO: remove error handling
         Assert.fail("IOException during cache.xml generation to " + file, ex);
@@ -256,10 +250,11 @@ public abstract class JUnit4CacheTestCase extends JUnit4DistributedTestCase
 
   public final InternalCache getCache(final boolean client, final CacheFactory factory) {
     synchronized (JUnit4CacheTestCase.class) {
-      final GemFireCacheImpl gemFireCache = GemFireCacheImpl.getInstance();
+      InternalCache gemFireCache = GemFireCacheImpl.getInstance();
       if (gemFireCache != null && !gemFireCache.isClosed()
           && gemFireCache.getCancelCriterion().isCancelInProgress()) {
         Wait.waitForCriterion(new WaitCriterion() { // TODO: replace with Awaitility
+
           @Override
           public boolean done() {
             return gemFireCache.isClosed();
@@ -289,10 +284,11 @@ public abstract class JUnit4CacheTestCase extends JUnit4DistributedTestCase
    */
   public final ClientCache getClientCache(final ClientCacheFactory factory) {
     synchronized (JUnit4CacheTestCase.class) {
-      final GemFireCacheImpl gemFireCache = GemFireCacheImpl.getInstance();
+      InternalCache gemFireCache = GemFireCacheImpl.getInstance();
       if (gemFireCache != null && !gemFireCache.isClosed()
           && gemFireCache.getCancelCriterion().isCancelInProgress()) {
         Wait.waitForCriterion(new WaitCriterion() { // TODO: replace with Awaitility
+
           @Override
           public boolean done() {
             return gemFireCache.isClosed();
@@ -318,8 +314,14 @@ public abstract class JUnit4CacheTestCase extends JUnit4DistributedTestCase
 
   /**
    * Invokes {@link #getCache()} and casts the return to {@code GemFireCacheImpl}.
+   *
+   * <p>
+   * TODO: change all callers to use getCache and delete getGemfireCache
+   *
+   * @deprecated Please use {@link #getCache} which returns InternalCache instead.
    */
-  public final GemFireCacheImpl getGemfireCache() { // TODO: remove?
+  @Deprecated
+  public final GemFireCacheImpl getGemfireCache() {
     return (GemFireCacheImpl) getCache();
   }
 
@@ -330,7 +332,7 @@ public abstract class JUnit4CacheTestCase extends JUnit4DistributedTestCase
   /**
    * Return current cache without creating one.
    */
-  public static final synchronized Cache basicGetCache() {
+  public static final synchronized InternalCache basicGetCache() {
     return cache;
   }
 
@@ -338,7 +340,7 @@ public abstract class JUnit4CacheTestCase extends JUnit4DistributedTestCase
    * Close the cache.
    */
   public static final synchronized void closeCache() {
-    // Workaround for that fact that some classes are now extending
+    // Workaround for the fact that some classes are now extending
     // CacheTestCase but not using it properly.
     if (cache == null) {
       cache = GemFireCacheImpl.getInstance();
@@ -348,12 +350,16 @@ public abstract class JUnit4CacheTestCase extends JUnit4DistributedTestCase
         try {
           if (!cache.isClosed()) {
             if (cache instanceof GemFireCacheImpl) {
-              CacheTransactionManager txMgr = ((GemFireCacheImpl) cache).getTxManager();
-              if (txMgr != null) {
-                if (txMgr.exists()) {
+              // this unnecessary type-cast prevents NoSuchMethodError
+              // java.lang.NoSuchMethodError:
+              // org.apache.geode.internal.cache.InternalCache.getTxManager()Lorg/apache/geode/internal/cache/TXManagerImpl
+              CacheTransactionManager transactionManager =
+                  ((GemFireCacheImpl) cache).getTxManager();
+              if (transactionManager != null) {
+                if (transactionManager.exists()) {
                   try {
                     // make sure we cleanup this threads txid stored in a thread local
-                    txMgr.rollback();
+                    transactionManager.rollback();
                   } catch (Exception ignore) {
 
                   }
@@ -367,8 +373,7 @@ public abstract class JUnit4CacheTestCase extends JUnit4DistributedTestCase
         }
       } // cache != null
     } finally {
-      // Make sure all pools are closed, even if we never
-      // created a cache
+      // Make sure all pools are closed, even if we never created a cache
       PoolManager.close(false);
     }
   }
@@ -435,56 +440,28 @@ public abstract class JUnit4CacheTestCase extends JUnit4DistributedTestCase
     return createRegion(name, "root", attributes);
   }
 
-  /**
-   * Provide any internal region arguments, typically required when internal use (aka meta-data)
-   * regions are needed.
-   *
-   * @return internal arguments, which may be null. If null, then default InternalRegionArguments
-   *         are used to construct the Region
-   */
-  private final InternalRegionArguments getInternalRegionArguments() { // TODO: delete?
-    return null;
-  }
-
   public final Region createRegion(final String name, final String rootName,
       final RegionAttributes attributes) throws CacheException {
     Region root = getRootRegion(rootName);
     if (root == null) {
       // don't put listeners on root region
-      RegionAttributes rootAttrs = attributes;
-      AttributesFactory fac = new AttributesFactory(attributes);
+      AttributesFactory attributesFactory = new AttributesFactory(attributes);
       ExpirationAttributes expiration = ExpirationAttributes.DEFAULT;
 
-      // fac.setCacheListener(null);
-      fac.setCacheLoader(null);
-      fac.setCacheWriter(null);
-      fac.setPoolName(null);
-      fac.setPartitionAttributes(null);
-      fac.setRegionTimeToLive(expiration);
-      fac.setEntryTimeToLive(expiration);
-      fac.setRegionIdleTimeout(expiration);
-      fac.setEntryIdleTimeout(expiration);
-      rootAttrs = fac.create();
+      attributesFactory.setCacheLoader(null);
+      attributesFactory.setCacheWriter(null);
+      attributesFactory.setPoolName(null);
+      attributesFactory.setPartitionAttributes(null);
+      attributesFactory.setRegionTimeToLive(expiration);
+      attributesFactory.setEntryTimeToLive(expiration);
+      attributesFactory.setRegionIdleTimeout(expiration);
+      attributesFactory.setEntryIdleTimeout(expiration);
+
+      RegionAttributes rootAttrs = attributesFactory.create();
       root = createRootRegion(rootName, rootAttrs);
     }
 
-    InternalRegionArguments internalArgs = getInternalRegionArguments();
-    if (internalArgs == null) {
-      return root.createSubregion(name, attributes);
-    } else {
-      try {
-        LocalRegion lr = (LocalRegion) root;
-        return lr.createSubregion(name, attributes, internalArgs);
-      } catch (IOException ioe) {
-        AssertionError assErr = new AssertionError("unexpected exception");
-        assErr.initCause(ioe);
-        throw assErr;
-      } catch (ClassNotFoundException cnfe) {
-        AssertionError assErr = new AssertionError("unexpected exception");
-        assErr.initCause(cnfe);
-        throw assErr;
-      }
-    }
+    return root.createSubregion(name, attributes);
   }
 
   public final Region getRootRegion() {
@@ -516,40 +493,37 @@ public abstract class JUnit4CacheTestCase extends JUnit4DistributedTestCase
   }
 
   /**
+   * TODO: delete addExceptionTag1 method
+   *
    * @deprecated Please use {@link IgnoredException#addIgnoredException(String)} instead.
    */
   @Deprecated
-  public final CacheSerializableRunnable addExceptionTag1(final String exceptionStringToIgnore) { // TODO:
-                                                                                                  // delete
-                                                                                                  // this
-                                                                                                  // method
-    CacheSerializableRunnable addExceptionTag = new CacheSerializableRunnable("addExceptionTag") {
+  public final CacheSerializableRunnable addExceptionTag1(final String exceptionStringToIgnore) {
+    return new CacheSerializableRunnable("addExceptionTag") {
+
       @Override
       public void run2() {
         getCache().getLogger().info(
             "<ExpectedException action=add>" + exceptionStringToIgnore + "</ExpectedException>");
       }
     };
-    return addExceptionTag;
   }
 
   /**
+   * TODO: delete removeExceptionTag1 method
+   *
    * @deprecated Please use {@link IgnoredException#addIgnoredException(String)} instead.
    */
   @Deprecated
-  public final CacheSerializableRunnable removeExceptionTag1(final String exceptionStringToIgnore) { // TODO:
-                                                                                                     // delete
-                                                                                                     // this
-                                                                                                     // method
-    CacheSerializableRunnable removeExceptionTag =
-        new CacheSerializableRunnable("removeExceptionTag") {
-          @Override
-          public void run2() throws CacheException {
-            getCache().getLogger().info("<ExpectedException action=remove>"
-                + exceptionStringToIgnore + "</ExpectedException>");
-          }
-        };
-    return removeExceptionTag;
+  public final CacheSerializableRunnable removeExceptionTag1(final String exceptionStringToIgnore) {
+    return new CacheSerializableRunnable("removeExceptionTag") {
+
+      @Override
+      public void run2() throws CacheException {
+        getCache().getLogger().info(
+            "<ExpectedException action=remove>" + exceptionStringToIgnore + "</ExpectedException>");
+      }
+    };
   }
 
   public static final File getDiskDir() {
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/examples/AsyncInvokeCallableExampleTest.java b/geode-core/src/test/java/org/apache/geode/test/dunit/examples/AsyncInvokeCallableExampleTest.java
new file mode 100644
index 0000000..30cee5d
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/examples/AsyncInvokeCallableExampleTest.java
@@ -0,0 +1,92 @@
+/*
+ * 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.examples;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.concurrent.TimeUnit;
+
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+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.rules.DistributedTestRule;
+import org.apache.geode.test.junit.categories.DistributedTest;
+
+@Category(DistributedTest.class)
+@SuppressWarnings("serial")
+public class AsyncInvokeCallableExampleTest {
+
+  @ClassRule
+  public static DistributedTestRule distributedTestRule = new DistributedTestRule();
+
+  @Test
+  public void invokeAsyncAsFuture() throws Exception {
+    VM workerVM = Host.getHost(0).getVM(0);
+    boolean success = workerVM.invokeAsync(() -> longRunningWorkWithResult()).get();
+    assertThat(success).isTrue();
+  }
+
+  @Test
+  public void invokeAsyncAsFutureWithTimeout() throws Exception {
+    VM workerVM = Host.getHost(0).getVM(0);
+    boolean success =
+        workerVM.invokeAsync(() -> longRunningWorkWithResult()).get(1, TimeUnit.MINUTES);
+    assertThat(success).isTrue();
+  }
+
+  @Test
+  public void invokeAsyncWithExceptionOccurred() throws Exception {
+    VM workerVM = Host.getHost(0).getVM(0);
+
+    AsyncInvocation<Boolean> asyncInvocation =
+        workerVM.invokeAsync(() -> longRunningWorkThatThrowsException());
+    asyncInvocation.join();
+
+    assertThat(asyncInvocation.exceptionOccurred()).isTrue();
+    assertThat(asyncInvocation.getException()).isInstanceOf(Exception.class).hasMessage("failed");
+  }
+
+  /**
+   * {@link VM#invokeAsync} uses {@link AsyncInvocation} which wraps underlying Exception in
+   * AssertionError.
+   */
+  @Test(expected = AssertionError.class)
+  public void invokeAsyncWithAwait() throws Exception {
+    Host.getHost(0).getVM(0).invokeAsync(() -> longRunningWorkThatThrowsException()).await();
+  }
+
+  /**
+   * {@link VM#invokeAsync} uses {@link AsyncInvocation} which wraps underlying Exception in
+   * AssertionError.
+   */
+  @Test(expected = AssertionError.class)
+  public void invokeAsyncWithAwaitWithTimeout() throws Exception {
+    Host.getHost(0).getVM(0).invokeAsync(() -> longRunningWorkThatThrowsException()).await(1,
+        TimeUnit.MINUTES);
+  }
+
+  private static boolean longRunningWorkWithResult() {
+    // perform some task that takes a while
+    return true;
+  }
+
+  private static boolean longRunningWorkThatThrowsException() throws Exception {
+    throw new Exception("failed");
+  }
+}
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/tests/GetTestMethodNameDUnitTest.java b/geode-core/src/test/java/org/apache/geode/test/dunit/examples/AsyncInvokeRunnableExampleTest.java
old mode 100755
new mode 100644
similarity index 50%
copy from geode-core/src/test/java/org/apache/geode/test/dunit/tests/GetTestMethodNameDUnitTest.java
copy to geode-core/src/test/java/org/apache/geode/test/dunit/examples/AsyncInvokeRunnableExampleTest.java
index 5e4d2b8..7a2be5e
--- a/geode-core/src/test/java/org/apache/geode/test/dunit/tests/GetTestMethodNameDUnitTest.java
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/examples/AsyncInvokeRunnableExampleTest.java
@@ -12,42 +12,45 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.test.dunit.tests;
+package org.apache.geode.test.dunit.examples;
 
-import static org.assertj.core.api.Assertions.*;
+import java.util.ArrayList;
+import java.util.List;
 
+import org.junit.ClassRule;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
+import org.apache.geode.test.dunit.AsyncInvocation;
 import org.apache.geode.test.dunit.Host;
-import org.apache.geode.test.dunit.internal.JUnit4DistributedTestCase;
+import org.apache.geode.test.dunit.VM;
+import org.apache.geode.test.dunit.rules.DistributedTestRule;
 import org.apache.geode.test.junit.categories.DistributedTest;
 
 @Category(DistributedTest.class)
 @SuppressWarnings("serial")
-public class GetTestMethodNameDUnitTest extends JUnit4DistributedTestCase {
+public class AsyncInvokeRunnableExampleTest {
 
-  @Test
-  public void testGetTestMethodName() {
-    assertGetTestMethodName("testGetTestMethodName");
-  }
+  @ClassRule
+  public static DistributedTestRule distributedTestRule = new DistributedTestRule();
 
   @Test
-  public void testGetTestMethodNameChanges() {
-    assertGetTestMethodName("testGetTestMethodNameChanges");
+  public void invokeAsyncHelloWorldInEachVM() throws Exception {
+    for (VM vm : Host.getHost(0).getAllVMs()) {
+      vm.invokeAsync(() -> System.out.println(vm + " says Hello World!"));
+    }
   }
 
   @Test
-  public void testGetTestMethodNameInAllVMs() {
-    assertGetTestMethodName("testGetTestMethodNameInAllVMs");
-
-    for (int vmIndex = 0; vmIndex < Host.getHost(0).getVMCount(); vmIndex++) {
-      Host.getHost(0).getVM(vmIndex)
-          .invoke(() -> assertGetTestMethodName("testGetTestMethodNameInAllVMs"));
+  public void invokeAsyncHelloWorldInEachVMWithAwait() throws Exception {
+    List<AsyncInvocation> invocations = new ArrayList<>();
+    for (VM vm : Host.getHost(0).getAllVMs()) {
+      AsyncInvocation invocation =
+          vm.invokeAsync(() -> System.out.println(vm + " says Hello World!"));
+      invocations.add(invocation);
+    }
+    for (AsyncInvocation invocation : invocations) {
+      invocation.await();
     }
-  }
-
-  private void assertGetTestMethodName(final String expected) {
-    assertThat(getTestMethodName()).isEqualTo(expected);
   }
 }
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/rules/DistributedExternalResource.java b/geode-core/src/test/java/org/apache/geode/test/dunit/examples/BeforeClassExampleTest.java
old mode 100755
new mode 100644
similarity index 53%
copy from geode-core/src/test/java/org/apache/geode/test/dunit/rules/DistributedExternalResource.java
copy to geode-core/src/test/java/org/apache/geode/test/dunit/examples/BeforeClassExampleTest.java
index d6f2019..fa9bb11
--- a/geode-core/src/test/java/org/apache/geode/test/dunit/rules/DistributedExternalResource.java
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/examples/BeforeClassExampleTest.java
@@ -12,28 +12,28 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.test.dunit.rules;
+package org.apache.geode.test.dunit.examples;
 
-import org.apache.geode.test.junit.rules.serializable.SerializableExternalResource;
+import static org.assertj.core.api.Assertions.assertThat;
 
-/**
- * Distributed version of SerializableExternalResource which affects all remote DUnit JVMs including
- * the Locator JVM.
- */
-public class DistributedExternalResource extends SerializableExternalResource {
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
 
-  private final RemoteInvoker invoker;
+import org.apache.geode.test.dunit.Host;
+import org.apache.geode.test.dunit.standalone.DUnitLauncher;
+import org.apache.geode.test.junit.categories.DistributedTest;
 
-  public DistributedExternalResource() {
-    this(new RemoteInvoker());
-  }
+@Category(DistributedTest.class)
+public class BeforeClassExampleTest {
 
-  public DistributedExternalResource(final RemoteInvoker invoker) {
-    super();
-    this.invoker = invoker;
+  @BeforeClass
+  public static void initializeDUnit() throws Exception {
+    DUnitLauncher.launchIfNeeded();
   }
 
-  protected RemoteInvoker invoker() {
-    return this.invoker;
+  @Test
+  public void shouldHaveFourDUnitVMsByDefault() throws Exception {
+    assertThat(Host.getHost(0).getVMCount()).isEqualTo(4);
   }
 }
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/examples/CatchingUnexpectedExceptionExampleTest.java b/geode-core/src/test/java/org/apache/geode/test/dunit/examples/CatchingUnexpectedExceptionExampleTest.java
new file mode 100644
index 0000000..da2b71b
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/examples/CatchingUnexpectedExceptionExampleTest.java
@@ -0,0 +1,98 @@
+/*
+ * 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.examples;
+
+import static org.apache.geode.test.dunit.Assert.fail;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.io.Serializable;
+
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import org.apache.geode.cache.AttributesFactory;
+import org.apache.geode.cache.Cache;
+import org.apache.geode.cache.CacheException;
+import org.apache.geode.cache.CacheFactory;
+import org.apache.geode.cache.RegionFactory;
+import org.apache.geode.internal.cache.LocalRegion;
+import org.apache.geode.test.dunit.Host;
+import org.apache.geode.test.dunit.SerializableRunnable;
+import org.apache.geode.test.dunit.rules.DistributedDisconnectRule;
+import org.apache.geode.test.dunit.rules.DistributedTestRule;
+import org.apache.geode.test.junit.categories.DistributedTest;
+
+@Category(DistributedTest.class)
+@SuppressWarnings("serial")
+public class CatchingUnexpectedExceptionExampleTest implements Serializable {
+
+  @ClassRule
+  public static DistributedTestRule distributedTestRule = new DistributedTestRule();
+
+  @Rule
+  public DistributedDisconnectRule disconnectRule =
+      new DistributedDisconnectRule.Builder().disconnectAfter(true).build();
+
+  /**
+   * Don't do this! Catch Exception and invoke fail => anti-pattern
+   */
+  @Test
+  public void createRegion_withTryCatch_dontDoThis() throws Exception {
+    Host.getHost(0).getVM(0).invoke(new SerializableRunnable("Create Region") {
+      @Override
+      public void run() {
+        try {
+          Cache cache = new CacheFactory().create();
+          RegionFactory regionFactory = cache.createRegionFactory(new AttributesFactory().create());
+          LocalRegion region = (LocalRegion) regionFactory.create("region1");
+          assertThat(region).isNotNull();
+        } catch (CacheException ex) {
+          fail("While creating region", ex);
+        }
+      }
+    });
+  }
+
+  /**
+   * Use "throws Exception" is better!
+   */
+  @Test
+  public void createRegion_withThrowsException_thisIsBetter() throws Exception {
+    Host.getHost(0).getVM(0).invoke(new SerializableRunnable("Create Region") {
+      @Override
+      public void run() throws Exception {
+        Cache cache = new CacheFactory().create();
+        RegionFactory regionFactory = cache.createRegionFactory(new AttributesFactory().create());
+        LocalRegion region = (LocalRegion) regionFactory.create("region1");
+        assertThat(region).isNotNull();
+      }
+    });
+  }
+
+  /**
+   * Use lambda without having to specify run() with throws Exception -- best!
+   */
+  @Test
+  public void createRegion_withLambda_thisIsBest() throws Exception {
+    Host.getHost(0).getVM(0).invoke("Create Region", () -> {
+      Cache cache = new CacheFactory().create();
+      RegionFactory regionFactory = cache.createRegionFactory(new AttributesFactory().create());
+      LocalRegion region = (LocalRegion) regionFactory.create("region1");
+      assertThat(region).isNotNull();
+    });
+  }
+}
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/rules/DistributedExternalResource.java b/geode-core/src/test/java/org/apache/geode/test/dunit/examples/DistributedTestCaseExampleTest.java
old mode 100755
new mode 100644
similarity index 54%
copy from geode-core/src/test/java/org/apache/geode/test/dunit/rules/DistributedExternalResource.java
copy to geode-core/src/test/java/org/apache/geode/test/dunit/examples/DistributedTestCaseExampleTest.java
index d6f2019..629f578
--- a/geode-core/src/test/java/org/apache/geode/test/dunit/rules/DistributedExternalResource.java
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/examples/DistributedTestCaseExampleTest.java
@@ -12,28 +12,25 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.test.dunit.rules;
+package org.apache.geode.test.dunit.examples;
 
-import org.apache.geode.test.junit.rules.serializable.SerializableExternalResource;
+import static org.assertj.core.api.Assertions.assertThat;
 
-/**
- * Distributed version of SerializableExternalResource which affects all remote DUnit JVMs including
- * the Locator JVM.
- */
-public class DistributedExternalResource extends SerializableExternalResource {
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
 
-  private final RemoteInvoker invoker;
+import org.apache.geode.distributed.internal.InternalDistributedSystem;
+import org.apache.geode.test.dunit.DistributedTestCase;
+import org.apache.geode.test.junit.categories.DistributedTest;
 
-  public DistributedExternalResource() {
-    this(new RemoteInvoker());
-  }
+@Category(DistributedTest.class)
+@SuppressWarnings("serial")
+public class DistributedTestCaseExampleTest extends DistributedTestCase {
 
-  public DistributedExternalResource(final RemoteInvoker invoker) {
-    super();
-    this.invoker = invoker;
-  }
-
-  protected RemoteInvoker invoker() {
-    return this.invoker;
+  @Test
+  public void getSystemCreatesSystem() throws Exception {
+    InternalDistributedSystem system = getSystem();
+    assertThat(system.isConnected()).isTrue();
   }
 }
+
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/rules/DistributedExternalResource.java b/geode-core/src/test/java/org/apache/geode/test/dunit/examples/DistributedTestRuleExampleTest.java
old mode 100755
new mode 100644
similarity index 54%
copy from geode-core/src/test/java/org/apache/geode/test/dunit/rules/DistributedExternalResource.java
copy to geode-core/src/test/java/org/apache/geode/test/dunit/examples/DistributedTestRuleExampleTest.java
index d6f2019..a73f4b4
--- a/geode-core/src/test/java/org/apache/geode/test/dunit/rules/DistributedExternalResource.java
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/examples/DistributedTestRuleExampleTest.java
@@ -12,28 +12,26 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.test.dunit.rules;
+package org.apache.geode.test.dunit.examples;
 
-import org.apache.geode.test.junit.rules.serializable.SerializableExternalResource;
+import static org.assertj.core.api.Assertions.assertThat;
 
-/**
- * Distributed version of SerializableExternalResource which affects all remote DUnit JVMs including
- * the Locator JVM.
- */
-public class DistributedExternalResource extends SerializableExternalResource {
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
 
-  private final RemoteInvoker invoker;
+import org.apache.geode.test.dunit.Host;
+import org.apache.geode.test.dunit.rules.DistributedTestRule;
+import org.apache.geode.test.junit.categories.DistributedTest;
 
-  public DistributedExternalResource() {
-    this(new RemoteInvoker());
-  }
+@Category(DistributedTest.class)
+public class DistributedTestRuleExampleTest {
 
-  public DistributedExternalResource(final RemoteInvoker invoker) {
-    super();
-    this.invoker = invoker;
-  }
+  @ClassRule
+  public static DistributedTestRule distributedTestRule = new DistributedTestRule();
 
-  protected RemoteInvoker invoker() {
-    return this.invoker;
+  @Test
+  public void shouldHaveFourDUnitVMsByDefault() throws Exception {
+    assertThat(Host.getHost(0).getVMCount()).isEqualTo(4);
   }
 }
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/tests/JUnit4GetTestMethodNameDUnitTest.java b/geode-core/src/test/java/org/apache/geode/test/dunit/examples/DoNotHandleUnexpectedExceptionExampleTest.java
similarity index 52%
copy from geode-core/src/test/java/org/apache/geode/test/dunit/tests/JUnit4GetTestMethodNameDUnitTest.java
copy to geode-core/src/test/java/org/apache/geode/test/dunit/examples/DoNotHandleUnexpectedExceptionExampleTest.java
index e607320..9a6272e 100644
--- a/geode-core/src/test/java/org/apache/geode/test/dunit/tests/JUnit4GetTestMethodNameDUnitTest.java
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/examples/DoNotHandleUnexpectedExceptionExampleTest.java
@@ -12,41 +12,48 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.test.dunit.tests;
+package org.apache.geode.test.dunit.examples;
 
-import static org.assertj.core.api.Assertions.*;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Fail.fail;
 
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
-import org.apache.geode.test.dunit.Host;
-import org.apache.geode.test.dunit.internal.JUnit4DistributedTestCase;
 import org.apache.geode.test.junit.categories.DistributedTest;
 
 @Category(DistributedTest.class)
-public class JUnit4GetTestMethodNameDUnitTest extends JUnit4DistributedTestCase {
+public class DoNotHandleUnexpectedExceptionExampleTest {
 
   @Test
-  public void testGetTestMethodName() {
-    assertGetTestMethodName("testGetTestMethodName");
+  public void thisIsTooVerbose() {
+    boolean success = false;
+    try {
+      success = doDangerousWork();
+    } catch (Exception unexpected) {
+      fail(unexpected.getMessage());
+    }
+    assertThat(success).isTrue();
   }
 
   @Test
-  public void testGetTestMethodNameChanges() {
-    assertGetTestMethodName("testGetTestMethodNameChanges");
+  public void thisIsEvenWorse() {
+    try {
+      assertThat(doDangerousWork()).isTrue();
+    } catch (Error | Exception unexpected) {
+      fail(unexpected.getMessage());
+    }
   }
 
   @Test
-  public void testGetTestMethodNameInAllVMs() {
-    assertGetTestMethodName("testGetTestMethodNameInAllVMs");
-
-    for (int vmIndex = 0; vmIndex < Host.getHost(0).getVMCount(); vmIndex++) {
-      Host.getHost(0).getVM(vmIndex)
-          .invoke(() -> assertGetTestMethodName("testGetTestMethodNameInAllVMs"));
-    }
+  public void thisIsTheCorrectWay() throws Exception {
+    assertThat(doDangerousWork()).isTrue();
   }
 
-  private void assertGetTestMethodName(final String expected) {
-    assertThat(getTestMethodName()).isEqualTo(expected);
+  private boolean doDangerousWork() throws Exception {
+    if (false) {
+      throw new Exception("fatal");
+    }
+    return true;
   }
 }
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/tests/GetTestMethodNameDUnitTest.java b/geode-core/src/test/java/org/apache/geode/test/dunit/examples/FixtureOrderingExampleTest.java
old mode 100755
new mode 100644
similarity index 52%
copy from geode-core/src/test/java/org/apache/geode/test/dunit/tests/GetTestMethodNameDUnitTest.java
copy to geode-core/src/test/java/org/apache/geode/test/dunit/examples/FixtureOrderingExampleTest.java
index 5e4d2b8..ec270d3
--- a/geode-core/src/test/java/org/apache/geode/test/dunit/tests/GetTestMethodNameDUnitTest.java
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/examples/FixtureOrderingExampleTest.java
@@ -12,42 +12,52 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.test.dunit.tests;
-
-import static org.assertj.core.api.Assertions.*;
+package org.apache.geode.test.dunit.examples;
 
+import org.junit.After;
+import org.junit.Before;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
-import org.apache.geode.test.dunit.Host;
-import org.apache.geode.test.dunit.internal.JUnit4DistributedTestCase;
+import org.apache.geode.test.dunit.DistributedTestCase;
 import org.apache.geode.test.junit.categories.DistributedTest;
 
 @Category(DistributedTest.class)
 @SuppressWarnings("serial")
-public class GetTestMethodNameDUnitTest extends JUnit4DistributedTestCase {
+public class FixtureOrderingExampleTest extends DistributedTestCase {
 
-  @Test
-  public void testGetTestMethodName() {
-    assertGetTestMethodName("testGetTestMethodName");
+  @Override
+  public void preSetUp() throws Exception {
+    System.out.println("@Override preSetUp");
   }
 
-  @Test
-  public void testGetTestMethodNameChanges() {
-    assertGetTestMethodName("testGetTestMethodNameChanges");
+  @Before
+  public void setUp() throws Exception {
+    System.out.println("@Before setUp");
   }
 
-  @Test
-  public void testGetTestMethodNameInAllVMs() {
-    assertGetTestMethodName("testGetTestMethodNameInAllVMs");
+  @Override
+  public void postSetUp() throws Exception {
+    System.out.println("@Override postSetUp");
+  }
 
-    for (int vmIndex = 0; vmIndex < Host.getHost(0).getVMCount(); vmIndex++) {
-      Host.getHost(0).getVM(vmIndex)
-          .invoke(() -> assertGetTestMethodName("testGetTestMethodNameInAllVMs"));
-    }
+  @Override
+  public void preTearDown() throws Exception {
+    System.out.println("@Override preTearDown");
   }
 
-  private void assertGetTestMethodName(final String expected) {
-    assertThat(getTestMethodName()).isEqualTo(expected);
+  @After
+  public void tearDown() throws Exception {
+    System.out.println("@After tearDown");
+  }
+
+  @Override
+  public void postTearDown() throws Exception {
+    System.out.println("@Override postTearDown");
+  }
+
+  @Test
+  public void demoOrdering() throws Exception {
+    // nothing
   }
 }
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/examples/InvokeCallableExampleTest.java b/geode-core/src/test/java/org/apache/geode/test/dunit/examples/InvokeCallableExampleTest.java
new file mode 100644
index 0000000..32f7232
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/examples/InvokeCallableExampleTest.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.dunit.examples;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import org.apache.geode.internal.process.ProcessUtils;
+import org.apache.geode.test.dunit.Host;
+import org.apache.geode.test.dunit.VM;
+import org.apache.geode.test.dunit.rules.DistributedTestRule;
+import org.apache.geode.test.junit.categories.DistributedTest;
+
+@Category(DistributedTest.class)
+public class InvokeCallableExampleTest {
+
+  @ClassRule
+  public static DistributedTestRule distributedTestRule = new DistributedTestRule();
+
+  private static final String[] names = {"Batman", "Superman", "Wonder Woman", "Aquaman"};
+
+  @Test
+  public void invokeIdentityInEachVM() throws Exception {
+    for (int i = 0; i < Host.getHost(0).getVMCount(); i++) {
+      final int whichVM = i;
+      VM vm = Host.getHost(0).getVM(whichVM);
+      String name = vm.invoke(() -> names[whichVM]);
+      assertThat(name).isEqualTo(names[i]);
+    }
+  }
+
+  @Test
+  public void getPidOfEachVM() throws Exception {
+    for (VM vm : Host.getHost(0).getAllVMs()) {
+      System.out.println(vm + " pid is " + vm.invoke(() -> ProcessUtils.identifyPid()));
+      // NOTE: VM.getPid() currently returns the VM number instead of pid
+      System.out.println("vm.getPid() is " + vm.getPid());
+    }
+  }
+}
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/tests/JUnit4GetTestMethodNameDUnitTest.java b/geode-core/src/test/java/org/apache/geode/test/dunit/examples/InvokeRunnableExampleTest.java
similarity index 53%
copy from geode-core/src/test/java/org/apache/geode/test/dunit/tests/JUnit4GetTestMethodNameDUnitTest.java
copy to geode-core/src/test/java/org/apache/geode/test/dunit/examples/InvokeRunnableExampleTest.java
index e607320..3477d5a 100644
--- a/geode-core/src/test/java/org/apache/geode/test/dunit/tests/JUnit4GetTestMethodNameDUnitTest.java
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/examples/InvokeRunnableExampleTest.java
@@ -12,41 +12,35 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.test.dunit.tests;
-
-import static org.assertj.core.api.Assertions.*;
+package org.apache.geode.test.dunit.examples;
 
+import org.junit.ClassRule;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
 import org.apache.geode.test.dunit.Host;
-import org.apache.geode.test.dunit.internal.JUnit4DistributedTestCase;
+import org.apache.geode.test.dunit.VM;
+import org.apache.geode.test.dunit.rules.DistributedTestRule;
 import org.apache.geode.test.junit.categories.DistributedTest;
 
 @Category(DistributedTest.class)
-public class JUnit4GetTestMethodNameDUnitTest extends JUnit4DistributedTestCase {
+public class InvokeRunnableExampleTest {
 
-  @Test
-  public void testGetTestMethodName() {
-    assertGetTestMethodName("testGetTestMethodName");
-  }
+  @ClassRule
+  public static DistributedTestRule distributedTestRule = new DistributedTestRule();
 
   @Test
-  public void testGetTestMethodNameChanges() {
-    assertGetTestMethodName("testGetTestMethodNameChanges");
+  public void invokeHelloWorldForEachVMInGetAllVMs() throws Exception {
+    for (VM vm : Host.getHost(0).getAllVMs()) {
+      vm.invoke(() -> System.out.println(vm + " says Hello World!"));
+    }
   }
 
   @Test
-  public void testGetTestMethodNameInAllVMs() {
-    assertGetTestMethodName("testGetTestMethodNameInAllVMs");
-
-    for (int vmIndex = 0; vmIndex < Host.getHost(0).getVMCount(); vmIndex++) {
-      Host.getHost(0).getVM(vmIndex)
-          .invoke(() -> assertGetTestMethodName("testGetTestMethodNameInAllVMs"));
+  public void invokeHelloWorldInEachVMInOrder() throws Exception {
+    for (int whichVM = 0; whichVM < Host.getHost(0).getVMCount(); whichVM++) {
+      VM vm = Host.getHost(0).getVM(whichVM);
+      vm.invoke(() -> System.out.println(vm + " says Hello World!"));
     }
   }
-
-  private void assertGetTestMethodName(final String expected) {
-    assertThat(getTestMethodName()).isEqualTo(expected);
-  }
 }
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/examples/LocatorPortClusterExampleTest.java b/geode-core/src/test/java/org/apache/geode/test/dunit/examples/LocatorPortClusterExampleTest.java
new file mode 100644
index 0000000..c87ec9f
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/examples/LocatorPortClusterExampleTest.java
@@ -0,0 +1,73 @@
+/*
+ * 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.examples;
+
+import static org.apache.geode.distributed.ConfigurationProperties.LOCATORS;
+import static org.apache.geode.test.dunit.DistributedTestUtils.getDUnitLocatorPort;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.io.Serializable;
+import java.util.Properties;
+
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import org.apache.geode.cache.CacheFactory;
+import org.apache.geode.internal.cache.InternalCache;
+import org.apache.geode.test.dunit.Host;
+import org.apache.geode.test.dunit.VM;
+import org.apache.geode.test.dunit.rules.DistributedDisconnectRule;
+import org.apache.geode.test.dunit.rules.DistributedTestRule;
+import org.apache.geode.test.junit.categories.DistributedTest;
+
+@Category(DistributedTest.class)
+@SuppressWarnings("serial")
+public class LocatorPortClusterExampleTest implements Serializable {
+
+  @ClassRule
+  public static DistributedTestRule distributedTestRule = new DistributedTestRule();
+
+  @Rule
+  public DistributedDisconnectRule disconnectRule =
+      new DistributedDisconnectRule.Builder().disconnectAfter(true).build();
+
+  private static InternalCache cache;
+
+  private Properties config;
+
+  @Before
+  public void setUp() throws Exception {
+    config = new Properties();
+    config.put(LOCATORS, Host.getHost(0).getHostName() + "[" + getDUnitLocatorPort() + "]");
+
+    cache = (InternalCache) new CacheFactory(config).create();
+
+    for (VM vm : Host.getHost(0).getAllVMs()) {
+      vm.invoke(() -> {
+        cache = (InternalCache) new CacheFactory(config).create();
+      });
+    }
+  }
+
+  @Test
+  public void clusterHasSixVMsByDefault() throws Exception {
+    assertThat(cache.getDistributionManager().getViewMembers()).hasSize(6);
+    assertThat(Host.getHost(0).getVMCount()).isEqualTo(4);
+    assertThat(Host.getHost(0).getAllVMs()).hasSize(4);
+  }
+}
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/tests/GetTestMethodNameDUnitTest.java b/geode-core/src/test/java/org/apache/geode/test/dunit/examples/ReplaceTryFinallyExampleTest.java
old mode 100755
new mode 100644
similarity index 52%
copy from geode-core/src/test/java/org/apache/geode/test/dunit/tests/GetTestMethodNameDUnitTest.java
copy to geode-core/src/test/java/org/apache/geode/test/dunit/examples/ReplaceTryFinallyExampleTest.java
index 5e4d2b8..be2e61c
--- a/geode-core/src/test/java/org/apache/geode/test/dunit/tests/GetTestMethodNameDUnitTest.java
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/examples/ReplaceTryFinallyExampleTest.java
@@ -12,42 +12,50 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.test.dunit.tests;
-
-import static org.assertj.core.api.Assertions.*;
+package org.apache.geode.test.dunit.examples;
 
+import org.junit.After;
+import org.junit.Before;
+import org.junit.ClassRule;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
-import org.apache.geode.test.dunit.Host;
-import org.apache.geode.test.dunit.internal.JUnit4DistributedTestCase;
+import org.apache.geode.test.dunit.rules.DistributedTestRule;
 import org.apache.geode.test.junit.categories.DistributedTest;
 
 @Category(DistributedTest.class)
 @SuppressWarnings("serial")
-public class GetTestMethodNameDUnitTest extends JUnit4DistributedTestCase {
+public class ReplaceTryFinallyExampleTest {
+
+  @ClassRule
+  public static DistributedTestRule distributedTestRule = new DistributedTestRule();
 
   @Test
-  public void testGetTestMethodName() {
-    assertGetTestMethodName("testGetTestMethodName");
+  public void doNotUseTryFinallyInTest() {
+    Bar.behaveSlowly = true;
+    try {
+      // perform testing
+    } finally {
+      Bar.behaveSlowly = false;
+    }
   }
 
-  @Test
-  public void testGetTestMethodNameChanges() {
-    assertGetTestMethodName("testGetTestMethodNameChanges");
+  @Before
+  public void setUp() throws Exception {
+    Bar.behaveSlowly = true;
   }
 
-  @Test
-  public void testGetTestMethodNameInAllVMs() {
-    assertGetTestMethodName("testGetTestMethodNameInAllVMs");
+  @After
+  public void tearDown() throws Exception {
+    Bar.behaveSlowly = false;
+  }
 
-    for (int vmIndex = 0; vmIndex < Host.getHost(0).getVMCount(); vmIndex++) {
-      Host.getHost(0).getVM(vmIndex)
-          .invoke(() -> assertGetTestMethodName("testGetTestMethodNameInAllVMs"));
-    }
+  @Test
+  public void useBeforeAndAfterInstead() throws Exception {
+    // perform testing that needs behaveSlowly
   }
 
-  private void assertGetTestMethodName(final String expected) {
-    assertThat(getTestMethodName()).isEqualTo(expected);
+  public static class Bar {
+    static boolean behaveSlowly = false;
   }
 }
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/internal/JUnit3DistributedTestCase.java b/geode-core/src/test/java/org/apache/geode/test/dunit/internal/JUnit3DistributedTestCase.java
index 107aa8b..b43a817 100755
--- a/geode-core/src/test/java/org/apache/geode/test/dunit/internal/JUnit3DistributedTestCase.java
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/internal/JUnit3DistributedTestCase.java
@@ -22,11 +22,16 @@ import org.junit.experimental.categories.Category;
 
 import org.apache.geode.distributed.DistributedSystem;
 import org.apache.geode.distributed.internal.InternalDistributedSystem;
+import org.apache.geode.test.dunit.DistributedTestCase;
 import org.apache.geode.test.junit.categories.DistributedTest;
 
 /**
  * This class is the superclass of all distributed tests using JUnit 3.
+ *
+ * @deprecated Please use {@link DistributedTestCase} which extends
+ *             {@link JUnit4DistributedTestCase} when writing new tests.
  */
+@Deprecated
 @Category(DistributedTest.class)
 public abstract class JUnit3DistributedTestCase extends TestCase
     implements DistributedTestFixture, Serializable {
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 8984884..46eaa98 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
@@ -14,12 +14,40 @@
  */
 package org.apache.geode.test.dunit.rules;
 
-// TODO:uncomment: import static org.apache.geode.test.dunit.DistributedTestRule.*;
+import static java.util.concurrent.TimeUnit.MINUTES;
 
+import com.google.common.base.Stopwatch;
+
+import org.apache.geode.admin.internal.AdminDistributedSystemImpl;
+import org.apache.geode.distributed.internal.InternalDistributedSystem;
 import org.apache.geode.test.dunit.SerializableRunnable;
 
 /**
- * Disconnects all remote DUnit JVMs including the Locator JVM.
+ * JUnit Rule that disconnects DistributedSystem in all VMs.
+ *
+ * <p>
+ * DistributedDisconnectRule can be used in DistributedTests to disconnect all VMs before or after
+ * each test:
+ *
+ * <pre>
+ * {@literal @}Rule
+ * public DistributedDisconnectRule distributedDisconnectRule = new DistributedDisconnectRule();
+ *
+ * {@literal @}Test
+ * public void createCacheInEveryDUnitVM() throws Exception {
+ *   cache = (InternalCache) new CacheFactory().create();
+ *   assertThat(cache.isClosed()).isFalse();
+ *   assertThat(cache.getInternalDistributedSystem().isConnected()).isTrue();
+ *
+ *   for (VM vm: Host.getHost(0).getAllVMs()) {
+ *     vm.invoke(() -> {
+ *       cache = (InternalCache) new CacheFactory().create();
+ *       assertThat(cache.isClosed()).isFalse();
+ *       assertThat(cache.getInternalDistributedSystem().isConnected()).isTrue();
+ *     });
+ *   }
+ * }
+ * </pre>
  */
 public class DistributedDisconnectRule extends DistributedExternalResource {
 
@@ -58,11 +86,30 @@ public class DistributedDisconnectRule extends DistributedExternalResource {
     return new SerializableRunnable() {
       @Override
       public void run() {
-        // TODO:uncomment: disconnectFromDS();
+        disconnect();
       }
     };
   }
 
+  public static void disconnect() {
+    Stopwatch stopwatch = Stopwatch.createStarted();
+    InternalDistributedSystem system = InternalDistributedSystem.getConnectedInstance();
+
+    while (system != null && stopwatch.elapsed(MINUTES) < 10) {
+      system = InternalDistributedSystem.getConnectedInstance();
+      try {
+        system.disconnect();
+      } catch (Exception ignore) {
+        // ignored
+      }
+    }
+
+    AdminDistributedSystemImpl adminSystem = AdminDistributedSystemImpl.getConnectedInstance();
+    if (adminSystem != null) {
+      adminSystem.disconnect();
+    }
+  }
+
   /**
    * Builds an instance of DistributedDisconnectRule
    */
@@ -70,7 +117,9 @@ public class DistributedDisconnectRule extends DistributedExternalResource {
     private boolean disconnectBefore;
     private boolean disconnectAfter;
 
-    public Builder() {}
+    public Builder() {
+      // nothing
+    }
 
     public Builder disconnectBefore(final boolean disconnectBefore) {
       this.disconnectBefore = disconnectBefore;
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/rules/DistributedExternalResource.java b/geode-core/src/test/java/org/apache/geode/test/dunit/rules/DistributedExternalResource.java
index d6f2019..529643a 100755
--- a/geode-core/src/test/java/org/apache/geode/test/dunit/rules/DistributedExternalResource.java
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/rules/DistributedExternalResource.java
@@ -20,7 +20,7 @@ import org.apache.geode.test.junit.rules.serializable.SerializableExternalResour
  * Distributed version of SerializableExternalResource which affects all remote DUnit JVMs including
  * the Locator JVM.
  */
-public class DistributedExternalResource extends SerializableExternalResource {
+public abstract class DistributedExternalResource extends SerializableExternalResource {
 
   private final RemoteInvoker invoker;
 
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/rules/DistributedExternalResource.java b/geode-core/src/test/java/org/apache/geode/test/dunit/rules/DistributedTestRule.java
old mode 100755
new mode 100644
similarity index 54%
copy from geode-core/src/test/java/org/apache/geode/test/dunit/rules/DistributedExternalResource.java
copy to geode-core/src/test/java/org/apache/geode/test/dunit/rules/DistributedTestRule.java
index d6f2019..7449b2d
--- a/geode-core/src/test/java/org/apache/geode/test/dunit/rules/DistributedExternalResource.java
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/rules/DistributedTestRule.java
@@ -14,26 +14,29 @@
  */
 package org.apache.geode.test.dunit.rules;
 
-import org.apache.geode.test.junit.rules.serializable.SerializableExternalResource;
+import org.apache.geode.test.dunit.standalone.DUnitLauncher;
 
 /**
- * Distributed version of SerializableExternalResource which affects all remote DUnit JVMs including
- * the Locator JVM.
+ * JUnit Rule that launches DistributedTest VMs without {@code DistributedTestCase}. Class may need
+ * to implement {@code Serializable}.
+ *
+ * <p>
+ * DistributedTestRule can be used in DistributedTests:
+ *
+ * <pre>
+ * {@literal @}ClassRule
+ * public static DistributedTestRule distributedTestRule = new DistributedTestRule();
+ *
+ * {@literal @}Test
+ * public void shouldHaveFourDUnitVMsByDefault() {
+ *   assertThat(Host.getHost(0).getVMCount()).isEqualTo(4);
+ * }
+ * </pre>
  */
-public class DistributedExternalResource extends SerializableExternalResource {
-
-  private final RemoteInvoker invoker;
-
-  public DistributedExternalResource() {
-    this(new RemoteInvoker());
-  }
-
-  public DistributedExternalResource(final RemoteInvoker invoker) {
-    super();
-    this.invoker = invoker;
-  }
+public class DistributedTestRule extends DistributedExternalResource {
 
-  protected RemoteInvoker invoker() {
-    return this.invoker;
+  @Override
+  protected void before() throws Throwable {
+    DUnitLauncher.launchIfNeeded();
   }
 }
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/rules/tests/DistributedDisconnectRuleAsClassRuleTest.java b/geode-core/src/test/java/org/apache/geode/test/dunit/rules/tests/DistributedDisconnectRuleAsClassRuleTest.java
new file mode 100644
index 0000000..3425d32
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/rules/tests/DistributedDisconnectRuleAsClassRuleTest.java
@@ -0,0 +1,171 @@
+/*
+ * 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.tests;
+
+import static org.apache.geode.test.dunit.rules.DistributedDisconnectRule.disconnect;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.After;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.runner.Result;
+import org.junit.runners.MethodSorters;
+
+import org.apache.geode.cache.CacheFactory;
+import org.apache.geode.internal.cache.InternalCache;
+import org.apache.geode.test.dunit.Host;
+import org.apache.geode.test.dunit.VM;
+import org.apache.geode.test.dunit.rules.DistributedDisconnectRule;
+import org.apache.geode.test.dunit.rules.DistributedTestRule;
+import org.apache.geode.test.junit.categories.DistributedTest;
+import org.apache.geode.test.junit.rules.RuleList;
+import org.apache.geode.test.junit.runners.TestRunner;
+
+@Category(DistributedTest.class)
+public class DistributedDisconnectRuleAsClassRuleTest {
+
+  @After
+  public void tearDown() throws Exception {
+    disconnect();
+    DisconnectBefore.cache = null;
+    DisconnectAfter.cache = null;
+
+    for (VM vm : Host.getHost(0).getAllVMs()) {
+      vm.invoke(() -> {
+        disconnect();
+        DisconnectBefore.cache = null;
+        DisconnectAfter.cache = null;
+      });
+    }
+  }
+
+  @Test
+  public void disconnectBeforeShouldDisconnectAllBeforeTests() throws Exception {
+    Result result = TestRunner.runTest(DisconnectBefore.class);
+
+    assertThat(result.wasSuccessful()).isTrue();
+
+    assertThat(DisconnectBefore.cache.getInternalDistributedSystem().isConnected()).isTrue();
+    assertThat(DisconnectBefore.cache.isClosed()).isFalse();
+
+    for (VM vm : Host.getHost(0).getAllVMs()) {
+      vm.invoke(() -> {
+        assertThat(DisconnectBefore.cache.getInternalDistributedSystem().isConnected()).isTrue();
+        assertThat(DisconnectBefore.cache.isClosed()).isFalse();
+      });
+    }
+  }
+
+  @Test
+  public void disconnectAfterShouldDisconnectAllAfterTests() throws Exception {
+    Result result = TestRunner.runTest(DisconnectAfter.class);
+
+    assertThat(result.wasSuccessful()).isTrue();
+
+    assertThat(DisconnectAfter.cache.getInternalDistributedSystem().isConnected()).isFalse();
+    assertThat(DisconnectAfter.cache.isClosed()).isTrue();
+
+    for (VM vm : Host.getHost(0).getAllVMs()) {
+      vm.invoke(() -> {
+        assertThat(DisconnectAfter.cache.getInternalDistributedSystem().isConnected()).isFalse();
+        assertThat(DisconnectAfter.cache.isClosed()).isTrue();
+      });
+    }
+  }
+
+  /**
+   * Used by test {@link #disconnectBeforeShouldDisconnectAllBeforeTests()}
+   */
+  public static class DisconnectBefore {
+
+    @ClassRule
+    public static RuleList rules = new RuleList().add(new DistributedTestRule())
+        .add(new DistributedDisconnectRule.Builder().disconnectBefore(true).build());
+
+    static InternalCache cache;
+
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+      cache = (InternalCache) new CacheFactory().create();
+      assertThat(cache.isClosed()).isFalse();
+      assertThat(cache.getInternalDistributedSystem().isConnected()).isTrue();
+
+      for (VM vm : Host.getHost(0).getAllVMs()) {
+        vm.invoke(() -> {
+          cache = (InternalCache) new CacheFactory().create();
+          assertThat(cache.isClosed()).isFalse();
+          assertThat(cache.getInternalDistributedSystem().isConnected()).isTrue();
+        });
+      }
+    }
+
+    @Test
+    public void everyDUnitVMShouldStillBeConnected() throws Exception {
+      assertThat(cache.isClosed()).isFalse();
+      assertThat(cache.getInternalDistributedSystem().isConnected()).isTrue();
+
+      for (VM vm : Host.getHost(0).getAllVMs()) {
+        vm.invoke(() -> {
+          assertThat(cache.isClosed()).isFalse();
+          assertThat(cache.getInternalDistributedSystem().isConnected()).isTrue();
+        });
+      }
+    }
+  }
+
+  /**
+   * Used by test {@link #disconnectAfterShouldDisconnectAllAfterTests()}
+   */
+  @FixMethodOrder(MethodSorters.NAME_ASCENDING)
+  public static class DisconnectAfter {
+
+    @ClassRule
+    public static RuleList rules = new RuleList().add(new DistributedTestRule())
+        .add(new DistributedDisconnectRule.Builder().disconnectAfter(true).build());
+
+    static InternalCache cache;
+
+    @Test
+    public void createCacheInEveryVM() throws Exception {
+      cache = (InternalCache) new CacheFactory().create();
+      assertThat(cache.isClosed()).isFalse();
+      assertThat(cache.getInternalDistributedSystem().isConnected()).isTrue();
+
+      for (VM vm : Host.getHost(0).getAllVMs()) {
+        vm.invoke(() -> {
+          cache = (InternalCache) new CacheFactory().create();
+          assertThat(cache.isClosed()).isFalse();
+          assertThat(cache.getInternalDistributedSystem().isConnected()).isTrue();
+        });
+      }
+    }
+
+    @Test
+    public void everyVMShouldStillBeConnected() throws Exception {
+      assertThat(cache.isClosed()).isFalse();
+      assertThat(cache.getInternalDistributedSystem().isConnected()).isTrue();
+
+      for (VM vm : Host.getHost(0).getAllVMs()) {
+        vm.invoke(() -> {
+          assertThat(cache.isClosed()).isFalse();
+          assertThat(cache.getInternalDistributedSystem().isConnected()).isTrue();
+        });
+      }
+    }
+  }
+}
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/rules/tests/DistributedDisconnectRuleTest.java b/geode-core/src/test/java/org/apache/geode/test/dunit/rules/tests/DistributedDisconnectRuleTest.java
new file mode 100644
index 0000000..9363be2
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/rules/tests/DistributedDisconnectRuleTest.java
@@ -0,0 +1,187 @@
+/*
+ * 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.tests;
+
+import static org.apache.geode.test.dunit.rules.DistributedDisconnectRule.disconnect;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.After;
+import org.junit.ClassRule;
+import org.junit.FixMethodOrder;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.runner.Result;
+import org.junit.runners.MethodSorters;
+
+import org.apache.geode.cache.CacheFactory;
+import org.apache.geode.internal.cache.InternalCache;
+import org.apache.geode.test.dunit.Host;
+import org.apache.geode.test.dunit.VM;
+import org.apache.geode.test.dunit.rules.DistributedDisconnectRule;
+import org.apache.geode.test.dunit.rules.DistributedTestRule;
+import org.apache.geode.test.junit.categories.DistributedTest;
+import org.apache.geode.test.junit.runners.TestRunner;
+
+@Category(DistributedTest.class)
+public class DistributedDisconnectRuleTest {
+
+  @ClassRule
+  public static DistributedTestRule distributedTestRule = new DistributedTestRule();
+
+  static InternalCache cache;
+
+  @After
+  public void tearDown() throws Exception {
+    disconnect();
+    cache = null;
+
+    for (VM vm : Host.getHost(0).getAllVMs()) {
+      vm.invoke(() -> {
+        disconnect();
+        cache = null;
+      });
+    }
+  }
+
+  @Test
+  public void disconnectShouldDisconnect() throws Exception {
+    cache = (InternalCache) new CacheFactory().create();
+    assertThat(cache.isClosed()).isFalse();
+    assertThat(cache.getInternalDistributedSystem().isConnected()).isTrue();
+
+    disconnect();
+
+    assertThat(cache.isClosed()).isTrue();
+    assertThat(cache.getInternalDistributedSystem().isConnected()).isFalse();
+  }
+
+  @Test
+  public void disconnectBeforeShouldDisconnectBeforeEachTest() throws Exception {
+    createCacheInEveryVM();
+    assertThatConnectedInEveryVM();
+
+    Result result = TestRunner.runTest(DisconnectBefore.class);
+
+    assertThat(result.wasSuccessful()).isTrue();
+    assertThatConnectedInEveryVM();
+  }
+
+  @Test
+  public void disconnectAfterShouldDisconnectAfterEachTest() throws Exception {
+    createCacheInEveryVM();
+    assertThatConnectedInEveryVM();
+
+    Result result = TestRunner.runTest(DisconnectAfter.class);
+
+    assertThat(result.wasSuccessful()).isTrue();
+    assertThatDisconnectedInEveryVM();
+  }
+
+  static void createCacheInEveryVM() throws Exception {
+    cache = (InternalCache) new CacheFactory().create();
+
+    for (VM vm : Host.getHost(0).getAllVMs()) {
+      vm.invoke(() -> {
+        cache = (InternalCache) new CacheFactory().create();
+      });
+    }
+  }
+
+  static void assertThatConnectedInEveryVM() throws Exception {
+    assertThat(cache.isClosed()).isFalse();
+    assertThat(cache.getInternalDistributedSystem().isConnected()).isTrue();
+
+    for (VM vm : Host.getHost(0).getAllVMs()) {
+      vm.invoke(() -> {
+        assertThat(cache.isClosed()).isFalse();
+        assertThat(cache.getInternalDistributedSystem().isConnected()).isTrue();
+      });
+    }
+  }
+
+  static void assertThatDisconnectedInEveryVM() throws Exception {
+    assertThat(cache.getInternalDistributedSystem().isConnected()).isFalse();
+    assertThat(cache.isClosed()).isTrue();
+
+    for (VM vm : Host.getHost(0).getAllVMs()) {
+      vm.invoke(() -> {
+        assertThat(cache.getInternalDistributedSystem().isConnected()).isFalse();
+        assertThat(cache.isClosed()).isTrue();
+      });
+    }
+  }
+
+  /**
+   * Used by test {@link #disconnectBeforeShouldDisconnectBeforeEachTest()}
+   */
+  @FixMethodOrder(MethodSorters.NAME_ASCENDING)
+  public static class DisconnectBefore {
+
+    @ClassRule
+    public static DistributedTestRule distributedTestRule = new DistributedTestRule();
+
+    @Rule
+    public DistributedDisconnectRule distributedDisconnectRule =
+        new DistributedDisconnectRule.Builder().disconnectBefore(true).build();
+
+    @Test
+    public void test001CreateCacheInEveryVM() throws Exception {
+      assertThatDisconnectedInEveryVM();
+      createCacheInEveryVM();
+      assertThatConnectedInEveryVM();
+    }
+
+    @Test
+    public void test002EveryVMShouldHaveDisconnected() throws Exception {
+      assertThatDisconnectedInEveryVM();
+      createCacheInEveryVM();
+      assertThatConnectedInEveryVM();
+    }
+  }
+
+  /**
+   * Used by test {@link #disconnectAfterShouldDisconnectAfterEachTest()}
+   */
+  @FixMethodOrder(MethodSorters.NAME_ASCENDING)
+  public static class DisconnectAfter {
+
+    @ClassRule
+    public static DistributedTestRule distributedTestRule = new DistributedTestRule();
+
+    @Rule
+    public DistributedDisconnectRule distributedDisconnectRule =
+        new DistributedDisconnectRule.Builder().disconnectAfter(true).build();
+
+    @Test
+    public void test001AlreadyHasCacheInEveryVM() throws Exception {
+      assertThatConnectedInEveryVM();
+    }
+
+    @Test
+    public void test002CreateCacheInEveryVM() throws Exception {
+      assertThatDisconnectedInEveryVM();
+      createCacheInEveryVM();
+      assertThatConnectedInEveryVM();
+    }
+
+    @Test
+    public void test003EveryVMShouldHaveDisconnected() throws Exception {
+      assertThatDisconnectedInEveryVM();
+      createCacheInEveryVM();
+      assertThatConnectedInEveryVM();
+    }
+  }
+}
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/rules/DistributedExternalResource.java b/geode-core/src/test/java/org/apache/geode/test/dunit/rules/tests/DistributedTestRuleTest.java
old mode 100755
new mode 100644
similarity index 54%
copy from geode-core/src/test/java/org/apache/geode/test/dunit/rules/DistributedExternalResource.java
copy to geode-core/src/test/java/org/apache/geode/test/dunit/rules/tests/DistributedTestRuleTest.java
index d6f2019..c2c0cc8
--- a/geode-core/src/test/java/org/apache/geode/test/dunit/rules/DistributedExternalResource.java
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/rules/tests/DistributedTestRuleTest.java
@@ -12,28 +12,26 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.test.dunit.rules;
+package org.apache.geode.test.dunit.rules.tests;
 
-import org.apache.geode.test.junit.rules.serializable.SerializableExternalResource;
+import static org.assertj.core.api.Assertions.assertThat;
 
-/**
- * Distributed version of SerializableExternalResource which affects all remote DUnit JVMs including
- * the Locator JVM.
- */
-public class DistributedExternalResource extends SerializableExternalResource {
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
 
-  private final RemoteInvoker invoker;
+import org.apache.geode.test.dunit.Host;
+import org.apache.geode.test.dunit.rules.DistributedTestRule;
+import org.apache.geode.test.junit.categories.DistributedTest;
 
-  public DistributedExternalResource() {
-    this(new RemoteInvoker());
-  }
+@Category(DistributedTest.class)
+public class DistributedTestRuleTest {
 
-  public DistributedExternalResource(final RemoteInvoker invoker) {
-    super();
-    this.invoker = invoker;
-  }
+  @ClassRule
+  public static DistributedTestRule distributedTestRule = new DistributedTestRule();
 
-  protected RemoteInvoker invoker() {
-    return this.invoker;
+  @Test
+  public void shouldHaveFourDUnitVMsByDefault() throws Exception {
+    assertThat(Host.getHost(0).getVMCount()).isEqualTo(4);
   }
 }
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/rules/test/MemberStarterRuleTest.java b/geode-core/src/test/java/org/apache/geode/test/dunit/rules/tests/MemberStarterRuleTest.java
similarity index 98%
rename from geode-core/src/test/java/org/apache/geode/test/dunit/rules/test/MemberStarterRuleTest.java
rename to geode-core/src/test/java/org/apache/geode/test/dunit/rules/tests/MemberStarterRuleTest.java
index f1686d9..d2d4dc6 100644
--- a/geode-core/src/test/java/org/apache/geode/test/dunit/rules/test/MemberStarterRuleTest.java
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/rules/tests/MemberStarterRuleTest.java
@@ -12,8 +12,7 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-
-package org.apache.geode.test.dunit.rules.test;
+package org.apache.geode.test.dunit.rules.tests;
 
 import static org.apache.geode.distributed.ConfigurationProperties.JMX_MANAGER_PORT;
 import static org.assertj.core.api.Assertions.assertThat;
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/tests/BasicDUnitTest.java b/geode-core/src/test/java/org/apache/geode/test/dunit/tests/BasicDUnitTest.java
index 6111e2c..acad6f6 100644
--- a/geode-core/src/test/java/org/apache/geode/test/dunit/tests/BasicDUnitTest.java
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/tests/BasicDUnitTest.java
@@ -27,18 +27,18 @@ import org.junit.experimental.categories.Category;
 
 import org.apache.geode.test.dunit.AsyncInvocation;
 import org.apache.geode.test.dunit.DUnitEnv;
+import org.apache.geode.test.dunit.DistributedTestCase;
 import org.apache.geode.test.dunit.Host;
 import org.apache.geode.test.dunit.RMIException;
 import org.apache.geode.test.dunit.VM;
-import org.apache.geode.test.dunit.internal.JUnit4DistributedTestCase;
 import org.apache.geode.test.junit.categories.DistributedTest;
 
 /**
  * This class tests the basic functionality of the distributed unit test framework.
  */
-@SuppressWarnings("unused")
 @Category(DistributedTest.class)
-public class BasicDUnitTest extends JUnit4DistributedTestCase {
+@SuppressWarnings({"serial", "unused"})
+public class BasicDUnitTest extends DistributedTestCase {
 
   private static final String MESSAGE_FOR_remoteThrowException = "Test exception.  Please ignore.";
 
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/tests/GetDefaultDiskStoreNameDUnitTest.java b/geode-core/src/test/java/org/apache/geode/test/dunit/tests/GetDefaultDiskStoreNameDUnitTest.java
index 841036e..6c271f0 100755
--- a/geode-core/src/test/java/org/apache/geode/test/dunit/tests/GetDefaultDiskStoreNameDUnitTest.java
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/tests/GetDefaultDiskStoreNameDUnitTest.java
@@ -20,13 +20,13 @@ import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
 import org.apache.geode.internal.cache.GemFireCacheImpl;
+import org.apache.geode.test.dunit.DistributedTestCase;
 import org.apache.geode.test.dunit.Host;
-import org.apache.geode.test.dunit.internal.JUnit4DistributedTestCase;
 import org.apache.geode.test.junit.categories.DistributedTest;
 
 @Category(DistributedTest.class)
 @SuppressWarnings("serial")
-public class GetDefaultDiskStoreNameDUnitTest extends JUnit4DistributedTestCase {
+public class GetDefaultDiskStoreNameDUnitTest extends DistributedTestCase {
 
   @Test
   public void testGetTestMethodName() {
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/tests/GetTestMethodNameDUnitTest.java b/geode-core/src/test/java/org/apache/geode/test/dunit/tests/GetTestMethodNameDUnitTest.java
index 5e4d2b8..31ac51b 100755
--- a/geode-core/src/test/java/org/apache/geode/test/dunit/tests/GetTestMethodNameDUnitTest.java
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/tests/GetTestMethodNameDUnitTest.java
@@ -19,13 +19,13 @@ import static org.assertj.core.api.Assertions.*;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
+import org.apache.geode.test.dunit.DistributedTestCase;
 import org.apache.geode.test.dunit.Host;
-import org.apache.geode.test.dunit.internal.JUnit4DistributedTestCase;
 import org.apache.geode.test.junit.categories.DistributedTest;
 
 @Category(DistributedTest.class)
 @SuppressWarnings("serial")
-public class GetTestMethodNameDUnitTest extends JUnit4DistributedTestCase {
+public class GetTestMethodNameDUnitTest extends DistributedTestCase {
 
   @Test
   public void testGetTestMethodName() {
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/tests/GetTestMethodNameDUnitTest.java b/geode-core/src/test/java/org/apache/geode/test/dunit/tests/GetUniqueNameDistributedTest.java
old mode 100755
new mode 100644
similarity index 53%
copy from geode-core/src/test/java/org/apache/geode/test/dunit/tests/GetTestMethodNameDUnitTest.java
copy to geode-core/src/test/java/org/apache/geode/test/dunit/tests/GetUniqueNameDistributedTest.java
index 5e4d2b8..2b5806e
--- a/geode-core/src/test/java/org/apache/geode/test/dunit/tests/GetTestMethodNameDUnitTest.java
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/tests/GetUniqueNameDistributedTest.java
@@ -14,40 +14,26 @@
  */
 package org.apache.geode.test.dunit.tests;
 
-import static org.assertj.core.api.Assertions.*;
+import static org.assertj.core.api.Assertions.assertThat;
 
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
+import org.junit.rules.TestName;
 
-import org.apache.geode.test.dunit.Host;
-import org.apache.geode.test.dunit.internal.JUnit4DistributedTestCase;
+import org.apache.geode.test.dunit.DistributedTestCase;
 import org.apache.geode.test.junit.categories.DistributedTest;
 
 @Category(DistributedTest.class)
 @SuppressWarnings("serial")
-public class GetTestMethodNameDUnitTest extends JUnit4DistributedTestCase {
+public class GetUniqueNameDistributedTest extends DistributedTestCase {
 
-  @Test
-  public void testGetTestMethodName() {
-    assertGetTestMethodName("testGetTestMethodName");
-  }
-
-  @Test
-  public void testGetTestMethodNameChanges() {
-    assertGetTestMethodName("testGetTestMethodNameChanges");
-  }
+  @Rule
+  public TestName testName = new TestName();
 
   @Test
-  public void testGetTestMethodNameInAllVMs() {
-    assertGetTestMethodName("testGetTestMethodNameInAllVMs");
-
-    for (int vmIndex = 0; vmIndex < Host.getHost(0).getVMCount(); vmIndex++) {
-      Host.getHost(0).getVM(vmIndex)
-          .invoke(() -> assertGetTestMethodName("testGetTestMethodNameInAllVMs"));
-    }
-  }
-
-  private void assertGetTestMethodName(final String expected) {
-    assertThat(getTestMethodName()).isEqualTo(expected);
+  public void getUniqueNameShouldContainSimpleClassNameAndMethodName() throws Exception {
+    assertThat(getUniqueName()).startsWith(getClass().getSimpleName())
+        .endsWith(testName.getMethodName());
   }
 }
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/tests/JUnit4BasicDUnitTest.java b/geode-core/src/test/java/org/apache/geode/test/dunit/tests/JUnit4BasicDUnitTest.java
index d9bfd5b..3a35c7b 100644
--- a/geode-core/src/test/java/org/apache/geode/test/dunit/tests/JUnit4BasicDUnitTest.java
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/tests/JUnit4BasicDUnitTest.java
@@ -37,11 +37,9 @@ import org.apache.geode.test.junit.categories.DistributedTest;
 
 /**
  * This class tests the basic functionality of the distributed unit test framework.
- *
- * @see JUnit4BasicDUnitTest
  */
 @Category(DistributedTest.class)
-@SuppressWarnings("unused")
+@SuppressWarnings({"serial", "unused"})
 public class JUnit4BasicDUnitTest extends JUnit4DistributedTestCase {
 
   private static final String MESSAGE_FOR_remoteThrowException = "Test exception.  Please ignore.";
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/tests/JUnit4GetDefaultDiskStoreNameDUnitTest.java b/geode-core/src/test/java/org/apache/geode/test/dunit/tests/JUnit4GetDefaultDiskStoreNameDUnitTest.java
index 1a45991..c8cd900 100644
--- a/geode-core/src/test/java/org/apache/geode/test/dunit/tests/JUnit4GetDefaultDiskStoreNameDUnitTest.java
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/tests/JUnit4GetDefaultDiskStoreNameDUnitTest.java
@@ -25,6 +25,7 @@ import org.apache.geode.test.dunit.internal.JUnit4DistributedTestCase;
 import org.apache.geode.test.junit.categories.DistributedTest;
 
 @Category(DistributedTest.class)
+@SuppressWarnings("serial")
 public class JUnit4GetDefaultDiskStoreNameDUnitTest extends JUnit4DistributedTestCase {
 
   @Test
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/tests/JUnit4GetTestMethodNameDUnitTest.java b/geode-core/src/test/java/org/apache/geode/test/dunit/tests/JUnit4GetTestMethodNameDUnitTest.java
index e607320..e88ec6f 100644
--- a/geode-core/src/test/java/org/apache/geode/test/dunit/tests/JUnit4GetTestMethodNameDUnitTest.java
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/tests/JUnit4GetTestMethodNameDUnitTest.java
@@ -24,6 +24,7 @@ import org.apache.geode.test.dunit.internal.JUnit4DistributedTestCase;
 import org.apache.geode.test.junit.categories.DistributedTest;
 
 @Category(DistributedTest.class)
+@SuppressWarnings("serial")
 public class JUnit4GetTestMethodNameDUnitTest extends JUnit4DistributedTestCase {
 
   @Test
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/tests/JUnit4OverridingGetPropertiesDisconnectsAllDUnitTest.java b/geode-core/src/test/java/org/apache/geode/test/dunit/tests/JUnit4OverridingGetPropertiesDisconnectsAllDUnitTest.java
index 64fbe50..4b75bcd 100644
--- a/geode-core/src/test/java/org/apache/geode/test/dunit/tests/JUnit4OverridingGetPropertiesDisconnectsAllDUnitTest.java
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/tests/JUnit4OverridingGetPropertiesDisconnectsAllDUnitTest.java
@@ -30,6 +30,7 @@ import static org.apache.geode.test.dunit.Invoke.invokeInEveryVM;
  * {@code disconnectAllFromDS} during tear down.
  */
 @Category(DistributedTest.class)
+@SuppressWarnings("serial")
 public class JUnit4OverridingGetPropertiesDisconnectsAllDUnitTest
     extends JUnit4DistributedTestCase {
 
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/tests/JUnit4VMDUnitTest.java b/geode-core/src/test/java/org/apache/geode/test/dunit/tests/JUnit4VMDUnitTest.java
index 237b5a5..1538355 100644
--- a/geode-core/src/test/java/org/apache/geode/test/dunit/tests/JUnit4VMDUnitTest.java
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/tests/JUnit4VMDUnitTest.java
@@ -34,6 +34,7 @@ import org.apache.geode.test.junit.categories.DistributedTest;
  * This class tests the functionality of the {@link VM} class.
  */
 @Category(DistributedTest.class)
+@SuppressWarnings("serial")
 public class JUnit4VMDUnitTest extends JUnit4DistributedTestCase {
 
   private static final AtomicInteger COUNTER = new AtomicInteger();
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/tests/OverridingGetPropertiesDisconnectsAllDUnitTest.java b/geode-core/src/test/java/org/apache/geode/test/dunit/tests/OverridingGetPropertiesDisconnectsAllDUnitTest.java
index 4c7d7f2..1d51b9ef 100644
--- a/geode-core/src/test/java/org/apache/geode/test/dunit/tests/OverridingGetPropertiesDisconnectsAllDUnitTest.java
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/tests/OverridingGetPropertiesDisconnectsAllDUnitTest.java
@@ -23,7 +23,7 @@ import java.util.Properties;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
-import org.apache.geode.test.dunit.internal.JUnit4DistributedTestCase;
+import org.apache.geode.test.dunit.DistributedTestCase;
 import org.apache.geode.test.junit.categories.DistributedTest;
 
 /**
@@ -31,7 +31,8 @@ import org.apache.geode.test.junit.categories.DistributedTest;
  * {@code disconnectAllFromDS} during tear down.
  */
 @Category(DistributedTest.class)
-public class OverridingGetPropertiesDisconnectsAllDUnitTest extends JUnit4DistributedTestCase {
+@SuppressWarnings("serial")
+public class OverridingGetPropertiesDisconnectsAllDUnitTest extends DistributedTestCase {
 
   @Override
   public final void preTearDownAssertions() throws Exception {
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/tests/VMDUnitTest.java b/geode-core/src/test/java/org/apache/geode/test/dunit/tests/VMDUnitTest.java
index 93bf73c..862fbd3 100644
--- a/geode-core/src/test/java/org/apache/geode/test/dunit/tests/VMDUnitTest.java
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/tests/VMDUnitTest.java
@@ -34,6 +34,7 @@ import org.apache.geode.test.junit.categories.DistributedTest;
  * This class tests the functionality of the {@link VM} class.
  */
 @Category(DistributedTest.class)
+@SuppressWarnings("serial")
 public class VMDUnitTest extends JUnit4DistributedTestCase {
 
   private static final AtomicInteger COUNTER = new AtomicInteger();
diff --git a/geode-junit/src/main/java/org/apache/geode/test/junit/rules/DescribedExternalResource.java b/geode-junit/src/main/java/org/apache/geode/test/junit/rules/DescribedExternalResource.java
index f357a6c..f8d4668 100644
--- a/geode-junit/src/main/java/org/apache/geode/test/junit/rules/DescribedExternalResource.java
+++ b/geode-junit/src/main/java/org/apache/geode/test/junit/rules/DescribedExternalResource.java
@@ -23,7 +23,7 @@ import org.junit.runners.model.Statement;
  * object in the before and after methods, so that the implementation would have access to the
  * annotation of the test methods
  */
-public class DescribedExternalResource implements TestRule {
+public abstract class DescribedExternalResource implements TestRule {
   public Statement apply(Statement base, Description description) {
     return statement(base, description);
   }
diff --git a/geode-junit/src/main/java/org/apache/geode/test/junit/rules/serializable/SerializableExternalResource.java b/geode-junit/src/main/java/org/apache/geode/test/junit/rules/serializable/SerializableExternalResource.java
index be561df..2bcce04 100755
--- a/geode-junit/src/main/java/org/apache/geode/test/junit/rules/serializable/SerializableExternalResource.java
+++ b/geode-junit/src/main/java/org/apache/geode/test/junit/rules/serializable/SerializableExternalResource.java
@@ -26,7 +26,7 @@ import org.junit.runners.model.Statement;
 public abstract class SerializableExternalResource extends ExternalResource
     implements SerializableTestRule {
 
-  public Statement apply(Statement base, Description description) {
+  public Statement apply(final Statement base, final Description description) {
     return statement(base);
   }
 
diff --git a/geode-junit/src/main/java/org/apache/geode/test/junit/runners/CategoryWithParameterizedRunner.java b/geode-junit/src/main/java/org/apache/geode/test/junit/runners/CategoryWithParameterizedRunner.java
index 89d1fdd..48282b4 100644
--- a/geode-junit/src/main/java/org/apache/geode/test/junit/runners/CategoryWithParameterizedRunner.java
+++ b/geode-junit/src/main/java/org/apache/geode/test/junit/runners/CategoryWithParameterizedRunner.java
@@ -14,17 +14,18 @@
  */
 package org.apache.geode.test.junit.runners;
 
+import java.lang.annotation.Annotation;
+import java.util.ArrayList;
+import java.util.List;
+
 import org.junit.runner.RunWith;
 import org.junit.runners.model.InitializationError;
 import org.junit.runners.parameterized.BlockJUnit4ClassRunnerWithParameters;
 import org.junit.runners.parameterized.TestWithParameters;
 
-import java.lang.annotation.Annotation;
-import java.util.ArrayList;
-import java.util.List;
-
 public class CategoryWithParameterizedRunner extends BlockJUnit4ClassRunnerWithParameters
     implements ExposedGetAnnotations {
+
   public CategoryWithParameterizedRunner(TestWithParameters test) throws InitializationError {
     super(test);
   }
diff --git a/geode-junit/src/main/java/org/apache/geode/test/junit/runners/CategoryWithParameterizedRunnerFactory.java b/geode-junit/src/main/java/org/apache/geode/test/junit/runners/CategoryWithParameterizedRunnerFactory.java
index 6ae44b9..8673075 100644
--- a/geode-junit/src/main/java/org/apache/geode/test/junit/runners/CategoryWithParameterizedRunnerFactory.java
+++ b/geode-junit/src/main/java/org/apache/geode/test/junit/runners/CategoryWithParameterizedRunnerFactory.java
@@ -14,17 +14,11 @@
  */
 package org.apache.geode.test.junit.runners;
 
-import org.junit.runner.RunWith;
 import org.junit.runner.Runner;
 import org.junit.runners.model.InitializationError;
-import org.junit.runners.parameterized.BlockJUnit4ClassRunnerWithParameters;
 import org.junit.runners.parameterized.ParametersRunnerFactory;
 import org.junit.runners.parameterized.TestWithParameters;
 
-import java.lang.annotation.Annotation;
-import java.util.ArrayList;
-import java.util.List;
-
 /**
  * This class provides an early fix for JUnit issue <a
  * href="https://github.com/junit-team/junit4/issues/751>751</a>.
@@ -34,6 +28,7 @@ import java.util.List;
  * See also <a href="https://issues.apache.org/jira/browse/GEODE-1350">GEODE-1350</a>
  */
 public class CategoryWithParameterizedRunnerFactory implements ParametersRunnerFactory {
+
   @Override
   public Runner createRunnerForTestWithParameters(TestWithParameters test)
       throws InitializationError {
diff --git a/geode-junit/src/main/java/org/apache/geode/test/junit/runner/SuiteBlockRunner.java b/geode-junit/src/main/java/org/apache/geode/test/junit/runners/SuiteBlockRunner.java
similarity index 88%
rename from geode-junit/src/main/java/org/apache/geode/test/junit/runner/SuiteBlockRunner.java
rename to geode-junit/src/main/java/org/apache/geode/test/junit/runners/SuiteBlockRunner.java
index c5608ec..52407ec 100644
--- a/geode-junit/src/main/java/org/apache/geode/test/junit/runner/SuiteBlockRunner.java
+++ b/geode-junit/src/main/java/org/apache/geode/test/junit/runners/SuiteBlockRunner.java
@@ -12,8 +12,7 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-
-package org.apache.geode.test.junit.runner;
+package org.apache.geode.test.junit.runners;
 
 import org.junit.runners.BlockJUnit4ClassRunner;
 import org.junit.runners.model.FrameworkMethod;
@@ -27,14 +26,14 @@ public class SuiteBlockRunner extends BlockJUnit4ClassRunner {
   private Class<?> suiteClass;
 
   /**
-   * Creates a BlockJUnit4ClassRunner to run {@code klass}
+   * Creates a BlockJUnit4ClassRunner to run {@code testClass}
    * 
-   * @param klass
+   * @param testClass the test class
    * @throws InitializationError if the test class is malformed.
    */
-  public SuiteBlockRunner(final Class parentClass, final Class<?> klass)
+  public SuiteBlockRunner(final Class parentClass, final Class<?> testClass)
       throws InitializationError {
-    super(klass);
+    super(testClass);
     this.suiteClass = parentClass;
   }
 
@@ -42,5 +41,4 @@ public class SuiteBlockRunner extends BlockJUnit4ClassRunner {
   protected String testName(FrameworkMethod method) {
     return method.getName() + "@" + suiteClass.getName();
   }
-
 }
diff --git a/geode-junit/src/main/java/org/apache/geode/test/junit/runner/SuiteRunner.java b/geode-junit/src/main/java/org/apache/geode/test/junit/runners/SuiteRunner.java
similarity index 64%
rename from geode-junit/src/main/java/org/apache/geode/test/junit/runner/SuiteRunner.java
rename to geode-junit/src/main/java/org/apache/geode/test/junit/runners/SuiteRunner.java
index dd3fa30..dfa7b95 100644
--- a/geode-junit/src/main/java/org/apache/geode/test/junit/runner/SuiteRunner.java
+++ b/geode-junit/src/main/java/org/apache/geode/test/junit/runners/SuiteRunner.java
@@ -12,8 +12,7 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-
-package org.apache.geode.test.junit.runner;
+package org.apache.geode.test.junit.runners;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -24,28 +23,31 @@ import org.junit.runners.model.InitializationError;
 import org.junit.runners.model.RunnerBuilder;
 
 /**
- * SuiteRunner is like Junit Suite, it's used in conjunction with
- * <code>SuiteClass({xx.class, yy.class})</code> It's different from Suite in two ways: 1. it should
- * only contain contain Junit4 test classes 2. the test method names inside each test class are
- * appended with the suiteClass name so that the result will show up different as when you run these
- * tests alone.
+ * SuiteRunner is like Junit Suite, it's used in conjunction with {@code SuiteClass({xx.class,
+ * yy.class})} It's different from Suite in two ways:
+ * <p>
+ *
+ * 1. it should only contain contain Junit4 test classes<br>
+ * 2. the test method names inside each test class are appended with the suiteClass name so that the
+ * result will show up different as when you run these tests alone.
  */
 public class SuiteRunner extends Suite {
 
-  public SuiteRunner(final Class<?> klass, final RunnerBuilder builder) throws InitializationError {
-    super(klass, getRunners(klass));
+  public SuiteRunner(final Class<?> testClass, final RunnerBuilder builder)
+      throws InitializationError {
+    super(testClass, getRunners(testClass));
   }
 
-  private static List<Runner> getRunners(final Class<?> klass) throws InitializationError {
-    SuiteClasses annotation = klass.getAnnotation(SuiteClasses.class);
+  private static List<Runner> getRunners(final Class<?> testClass) throws InitializationError {
+    SuiteClasses annotation = testClass.getAnnotation(SuiteClasses.class);
     if (annotation == null) {
       throw new InitializationError(
-          String.format("class '%s' must have a SuiteClasses annotation", klass.getName()));
+          String.format("class '%s' must have a SuiteClasses annotation", testClass.getName()));
     }
     Class<?>[] childClasses = annotation.value();
     List<Runner> runners = new ArrayList<>();
     for (Class childClass : childClasses) {
-      runners.add(new SuiteBlockRunner(klass, childClass));
+      runners.add(new SuiteBlockRunner(testClass, childClass));
     }
     return runners;
   }
diff --git a/geode-junit/src/test/java/org/apache/geode/test/junit/rules/TestRunner.java b/geode-junit/src/main/java/org/apache/geode/test/junit/runners/TestRunner.java
similarity index 96%
rename from geode-junit/src/test/java/org/apache/geode/test/junit/rules/TestRunner.java
rename to geode-junit/src/main/java/org/apache/geode/test/junit/runners/TestRunner.java
index 9064a5a..a5c0f36 100755
--- a/geode-junit/src/test/java/org/apache/geode/test/junit/rules/TestRunner.java
+++ b/geode-junit/src/main/java/org/apache/geode/test/junit/runners/TestRunner.java
@@ -12,7 +12,7 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.test.junit.rules;
+package org.apache.geode.test.junit.runners;
 
 import org.junit.runner.JUnitCore;
 import org.junit.runner.Request;
diff --git a/geode-junit/src/test/java/org/apache/geode/test/junit/categories/CategoryTest.java b/geode-junit/src/test/java/org/apache/geode/test/junit/categories/CategoryTest.java
index 6fc51da..7cc481d 100644
--- a/geode-junit/src/test/java/org/apache/geode/test/junit/categories/CategoryTest.java
+++ b/geode-junit/src/test/java/org/apache/geode/test/junit/categories/CategoryTest.java
@@ -25,7 +25,7 @@ import org.junit.runner.Result;
 import org.junit.runner.RunWith;
 import org.junit.runners.Suite;
 
-import org.apache.geode.test.junit.rules.TestRunner;
+import org.apache.geode.test.junit.runners.TestRunner;
 
 @Category(UnitTest.class)
 public class CategoryTest {
diff --git a/geode-junit/src/test/java/org/apache/geode/test/junit/rules/ExpectedTimeoutRuleTest.java b/geode-junit/src/test/java/org/apache/geode/test/junit/rules/ExpectedTimeoutRuleTest.java
index 7f7b459..2aec8b2 100755
--- a/geode-junit/src/test/java/org/apache/geode/test/junit/rules/ExpectedTimeoutRuleTest.java
+++ b/geode-junit/src/test/java/org/apache/geode/test/junit/rules/ExpectedTimeoutRuleTest.java
@@ -26,6 +26,7 @@ import org.junit.experimental.categories.Category;
 import org.junit.runner.Result;
 import org.junit.runner.notification.Failure;
 
+import org.apache.geode.test.junit.runners.TestRunner;
 import org.apache.geode.test.junit.categories.UnitTest;
 
 /**
diff --git a/geode-junit/src/test/java/org/apache/geode/test/junit/rules/IgnoreUntilRuleTest.java b/geode-junit/src/test/java/org/apache/geode/test/junit/rules/IgnoreUntilRuleTest.java
index 98c7ade..bf33bb7 100755
--- a/geode-junit/src/test/java/org/apache/geode/test/junit/rules/IgnoreUntilRuleTest.java
+++ b/geode-junit/src/test/java/org/apache/geode/test/junit/rules/IgnoreUntilRuleTest.java
@@ -26,6 +26,7 @@ import org.junit.runner.Result;
 import org.junit.runner.notification.Failure;
 
 import org.apache.geode.test.junit.IgnoreUntil;
+import org.apache.geode.test.junit.runners.TestRunner;
 import org.apache.geode.test.junit.categories.UnitTest;
 
 /**
diff --git a/geode-junit/src/test/java/org/apache/geode/test/junit/rules/RepeatRuleTest.java b/geode-junit/src/test/java/org/apache/geode/test/junit/rules/RepeatRuleTest.java
index 15d71ee..cea3a9c 100755
--- a/geode-junit/src/test/java/org/apache/geode/test/junit/rules/RepeatRuleTest.java
+++ b/geode-junit/src/test/java/org/apache/geode/test/junit/rules/RepeatRuleTest.java
@@ -26,6 +26,7 @@ import org.junit.runner.Result;
 import org.junit.runner.notification.Failure;
 
 import org.apache.geode.test.junit.Repeat;
+import org.apache.geode.test.junit.runners.TestRunner;
 import org.apache.geode.test.junit.categories.UnitTest;
 
 /**
diff --git a/geode-junit/src/test/java/org/apache/geode/test/junit/rules/RestoreLocaleRuleTest.java b/geode-junit/src/test/java/org/apache/geode/test/junit/rules/RestoreLocaleRuleTest.java
index b45f3a2..8c6c6a5 100644
--- a/geode-junit/src/test/java/org/apache/geode/test/junit/rules/RestoreLocaleRuleTest.java
+++ b/geode-junit/src/test/java/org/apache/geode/test/junit/rules/RestoreLocaleRuleTest.java
@@ -14,20 +14,24 @@
  */
 package org.apache.geode.test.junit.rules;
 
-import static org.hamcrest.CoreMatchers.*;
+import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.Matchers.contains;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
 
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Locale;
 import java.util.Random;
 
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 import org.junit.runner.Result;
 
+import org.apache.geode.test.junit.runners.TestRunner;
 import org.apache.geode.test.junit.categories.UnitTest;
 
 /**
@@ -38,7 +42,8 @@ public class RestoreLocaleRuleTest {
 
   private static Locale notDefaultLocale;
 
-  static {
+  @BeforeClass
+  public static void setUp() throws Exception {
     Locale[] locales = Locale.getAvailableLocales();
     while (notDefaultLocale == null) {
       Locale l = locales[new Random().nextInt(locales.length)];
@@ -47,6 +52,11 @@ public class RestoreLocaleRuleTest {
     }
   }
 
+  @AfterClass
+  public static void tearDown() throws Exception {
+    notDefaultLocale = null;
+  }
+
   @Test
   public void shouldRestoreLocaleInAfter() throws Throwable {
     Locale originalLocale = Locale.getDefault();
diff --git a/geode-junit/src/test/java/org/apache/geode/test/junit/rules/RetryRuleGlobalWithErrorTest.java b/geode-junit/src/test/java/org/apache/geode/test/junit/rules/RetryRuleGlobalWithErrorTest.java
index 8804358..56a5154 100755
--- a/geode-junit/src/test/java/org/apache/geode/test/junit/rules/RetryRuleGlobalWithErrorTest.java
+++ b/geode-junit/src/test/java/org/apache/geode/test/junit/rules/RetryRuleGlobalWithErrorTest.java
@@ -27,6 +27,7 @@ import org.junit.runner.Result;
 import org.junit.runner.notification.Failure;
 
 import org.apache.geode.test.junit.Retry;
+import org.apache.geode.test.junit.runners.TestRunner;
 import org.apache.geode.test.junit.categories.UnitTest;
 
 /**
diff --git a/geode-junit/src/test/java/org/apache/geode/test/junit/rules/RetryRuleGlobalWithExceptionTest.java b/geode-junit/src/test/java/org/apache/geode/test/junit/rules/RetryRuleGlobalWithExceptionTest.java
index 09e163a..ad77a03 100755
--- a/geode-junit/src/test/java/org/apache/geode/test/junit/rules/RetryRuleGlobalWithExceptionTest.java
+++ b/geode-junit/src/test/java/org/apache/geode/test/junit/rules/RetryRuleGlobalWithExceptionTest.java
@@ -26,6 +26,7 @@ import org.junit.runner.Result;
 import org.junit.runner.notification.Failure;
 
 import org.apache.geode.test.junit.Retry;
+import org.apache.geode.test.junit.runners.TestRunner;
 import org.apache.geode.test.junit.categories.UnitTest;
 
 /**
diff --git a/geode-junit/src/test/java/org/apache/geode/test/junit/rules/RetryRuleLocalWithErrorTest.java b/geode-junit/src/test/java/org/apache/geode/test/junit/rules/RetryRuleLocalWithErrorTest.java
index b04a6e0..b90b378 100755
--- a/geode-junit/src/test/java/org/apache/geode/test/junit/rules/RetryRuleLocalWithErrorTest.java
+++ b/geode-junit/src/test/java/org/apache/geode/test/junit/rules/RetryRuleLocalWithErrorTest.java
@@ -27,6 +27,7 @@ import org.junit.runner.Result;
 import org.junit.runner.notification.Failure;
 
 import org.apache.geode.test.junit.Retry;
+import org.apache.geode.test.junit.runners.TestRunner;
 import org.apache.geode.test.junit.categories.UnitTest;
 
 /**
diff --git a/geode-junit/src/test/java/org/apache/geode/test/junit/rules/RetryRuleLocalWithExceptionTest.java b/geode-junit/src/test/java/org/apache/geode/test/junit/rules/RetryRuleLocalWithExceptionTest.java
index 6813b19..ae66b4a 100755
--- a/geode-junit/src/test/java/org/apache/geode/test/junit/rules/RetryRuleLocalWithExceptionTest.java
+++ b/geode-junit/src/test/java/org/apache/geode/test/junit/rules/RetryRuleLocalWithExceptionTest.java
@@ -26,6 +26,7 @@ import org.junit.runner.Result;
 import org.junit.runner.notification.Failure;
 
 import org.apache.geode.test.junit.Retry;
+import org.apache.geode.test.junit.runners.TestRunner;
 import org.apache.geode.test.junit.categories.UnitTest;
 
 /**
diff --git a/geode-junit/src/test/java/org/apache/geode/test/junit/rules/RuleListTest.java b/geode-junit/src/test/java/org/apache/geode/test/junit/rules/RuleListTest.java
index 0d70510..0d8e3b5 100755
--- a/geode-junit/src/test/java/org/apache/geode/test/junit/rules/RuleListTest.java
+++ b/geode-junit/src/test/java/org/apache/geode/test/junit/rules/RuleListTest.java
@@ -16,6 +16,7 @@ package org.apache.geode.test.junit.rules;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
+import org.apache.geode.test.junit.runners.TestRunner;
 import org.apache.geode.test.junit.categories.UnitTest;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
diff --git a/geode-junit/src/test/java/org/apache/geode/test/junit/rules/TemporaryFileRuleTest.java b/geode-junit/src/test/java/org/apache/geode/test/junit/rules/TemporaryFileRuleTest.java
index 6ea5f2c..814378b 100644
--- a/geode-junit/src/test/java/org/apache/geode/test/junit/rules/TemporaryFileRuleTest.java
+++ b/geode-junit/src/test/java/org/apache/geode/test/junit/rules/TemporaryFileRuleTest.java
@@ -26,6 +26,7 @@ import org.junit.Test;
 import org.junit.experimental.categories.Category;
 import org.junit.runner.Result;
 
+import org.apache.geode.test.junit.runners.TestRunner;
 import org.apache.geode.test.junit.categories.IntegrationTest;
 
 @Category(IntegrationTest.class)
diff --git a/geode-junit/src/test/java/org/apache/geode/test/junit/rules/examples/RuleAndClassRuleTest.java b/geode-junit/src/test/java/org/apache/geode/test/junit/rules/examples/RuleAndClassRuleTest.java
index c7579a6..756c6a2 100755
--- a/geode-junit/src/test/java/org/apache/geode/test/junit/rules/examples/RuleAndClassRuleTest.java
+++ b/geode-junit/src/test/java/org/apache/geode/test/junit/rules/examples/RuleAndClassRuleTest.java
@@ -17,7 +17,7 @@ package org.apache.geode.test.junit.rules.examples;
 import static org.assertj.core.api.Assertions.*;
 
 import org.apache.geode.test.junit.categories.UnitTest;
-import org.apache.geode.test.junit.rules.TestRunner;
+import org.apache.geode.test.junit.runners.TestRunner;
 import org.junit.ClassRule;
 import org.junit.Rule;
 import org.junit.Test;
diff --git a/geode-web/src/test/java/org/apache/geode/management/internal/cli/commands/CommandOverHttpDUnitTest.java b/geode-web/src/test/java/org/apache/geode/management/internal/cli/commands/CommandOverHttpDUnitTest.java
index a0488f5..08f39cb 100644
--- a/geode-web/src/test/java/org/apache/geode/management/internal/cli/commands/CommandOverHttpDUnitTest.java
+++ b/geode-web/src/test/java/org/apache/geode/management/internal/cli/commands/CommandOverHttpDUnitTest.java
@@ -22,7 +22,7 @@ import org.junit.runners.Suite;
 
 import org.apache.geode.test.junit.categories.DistributedTest;
 import org.apache.geode.test.junit.categories.SecurityTest;
-import org.apache.geode.test.junit.runner.SuiteRunner;
+import org.apache.geode.test.junit.runners.SuiteRunner;
 
 @Category({DistributedTest.class, SecurityTest.class})
 @RunWith(SuiteRunner.class)

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