geode-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kl...@apache.org
Subject [5/9] incubator-geode git commit: Dunit changes for JUnit 4 syntax. Refactoring to modernize API.
Date Fri, 21 Aug 2015 20:29:32 GMT
Dunit changes for JUnit 4 syntax. Refactoring to modernize API.


Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/49b2913a
Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/49b2913a
Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/49b2913a

Branch: refs/heads/feature/GEODE-217
Commit: 49b2913aca753b408dac556371ea700c81d909f0
Parents: fb5452a
Author: Kirk Lund <klund@pivotal.io>
Authored: Sat Aug 15 17:49:06 2015 -0700
Committer: Kirk Lund <klund@pivotal.io>
Committed: Sat Aug 15 17:49:06 2015 -0700

----------------------------------------------------------------------
 .../gemfire/internal/util/DebuggerSupport.java  |   16 +-
 .../distributed/DistributedMemberDUnitTest.java |  399 +++---
 .../distributed/HostedLocatorsDUnitTest.java    |   70 +-
 .../distributed/MembershipTestSuite.java        |   17 +
 .../offheap/OutOfOffHeapMemoryDUnitTest.java    |   88 +-
 .../catchexception/CatchExceptionDUnitTest.java |   63 +
 .../catchexception/CatchExceptionJUnitTest.java |   95 ++
 .../com/gemstone/gemfire/test/dunit/Assert.java |   11 +
 .../gemfire/test/dunit/AsyncInvocation.java     |  206 +++
 .../gemfire/test/dunit/BounceResult.java        |   20 +
 .../gemstone/gemfire/test/dunit/DUnitEnv.java   |   68 +
 .../gemfire/test/dunit/DebuggerSupport.java     |   20 +
 .../gemfire/test/dunit/DistributedTestCase.java |  659 +++++++++
 .../test/dunit/ExpectedExceptionString.java     |  142 ++
 .../com/gemstone/gemfire/test/dunit/Host.java   |  201 +++
 .../com/gemstone/gemfire/test/dunit/Invoke.java |  146 ++
 .../com/gemstone/gemfire/test/dunit/Jitter.java |   70 +
 .../gemfire/test/dunit/RMIException.java        |  161 +++
 .../gemfire/test/dunit/RemoteDUnitVMIF.java     |   18 +
 .../gemfire/test/dunit/RepeatableRunnable.java  |   13 +
 .../test/dunit/SerializableCallable.java        |   61 +
 .../test/dunit/SerializableRunnable.java        |   83 ++
 .../test/dunit/StoppableWaitCriterion.java      |   12 +
 .../gemstone/gemfire/test/dunit/ThreadDump.java |  157 +++
 .../com/gemstone/gemfire/test/dunit/VM.java     | 1333 ++++++++++++++++++
 .../com/gemstone/gemfire/test/dunit/Wait.java   |  167 +++
 .../gemfire/test/dunit/WaitCriterion.java       |   11 +
 .../gemfire/test/dunit/cache/CacheTestCase.java |  696 +++++++++
 .../gemfire/test/dunit/standalone/ChildVM.java  |   62 +
 .../test/dunit/standalone/DUnitLauncher.java    |  416 ++++++
 .../test/dunit/standalone/ProcessManager.java   |  228 +++
 .../test/dunit/standalone/RemoteDUnitVM.java    |  136 ++
 .../dunit/standalone/StandAloneDUnitEnv.java    |   66 +
 .../test/dunit/tests/BasicDUnitTest.java        |  124 ++
 .../dunit/tests/DUnitFrameworkTestSuite.java    |   16 +
 .../gemfire/test/dunit/tests/TestFailure.java   |   37 +
 .../gemfire/test/dunit/tests/VMDUnitTest.java   |  245 ++++
 .../test/java/dunit/DistributedTestCase.java    |    6 +-
 gemfire-core/src/test/java/dunit/VM.java        |    2 -
 .../java/dunit/standalone/ProcessManager.java   |    2 +-
 .../test/junit/categories/MembershipTest.java   |    9 +
 41 files changed, 6079 insertions(+), 273 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/49b2913a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/util/DebuggerSupport.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/util/DebuggerSupport.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/util/DebuggerSupport.java
index c40df4d..f7d4fcb 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/util/DebuggerSupport.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/util/DebuggerSupport.java
@@ -8,8 +8,11 @@
 
 package com.gemstone.gemfire.internal.util;
 
-import com.gemstone.gemfire.i18n.LogWriterI18n;
+import org.apache.logging.log4j.Logger;
+
 import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+import com.gemstone.gemfire.internal.logging.LogService;
+import com.gemstone.gemfire.internal.logging.log4j.LocalizedMessage;
 
 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 
@@ -19,23 +22,24 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
  *
  */
 public abstract class DebuggerSupport  {
+  private static final Logger logger = LogService.getLogger();
   
   /** Creates a new instance of DebuggerSupport */
   private DebuggerSupport() {
   }
   
   /** Debugger support */
-  public static void waitForJavaDebugger(LogWriterI18n logger) {
-    waitForJavaDebugger(logger, null);
+  public static void waitForJavaDebugger() {
+    waitForJavaDebugger(null);
   }
   
   @SuppressFBWarnings(value="IL_INFINITE_LOOP", justification="Endless loop is for debugging purposes.") 
-  public static void waitForJavaDebugger(LogWriterI18n logger, String extraLogMsg) {
+  public static void waitForJavaDebugger(String extraLogMsg) {
     boolean cont = false;
     String msg = ":";
     if (extraLogMsg != null)
       msg += extraLogMsg;
-    logger.severe(LocalizedStrings.DebuggerSupport_WAITING_FOR_DEBUGGER_TO_ATTACH_0, msg);
+    logger.fatal(LocalizedMessage.create(LocalizedStrings.DebuggerSupport_WAITING_FOR_DEBUGGER_TO_ATTACH_0, msg));
     boolean interrupted = false;
     while (!cont) { // set cont to true in debugger when ready to continue
       try {
@@ -50,6 +54,6 @@ public abstract class DebuggerSupport  {
     if (interrupted) {
       Thread.currentThread().interrupt();
     }
-    logger.info(LocalizedStrings.DebuggerSupport_DEBUGGER_CONTINUING);
+    logger.info(LocalizedMessage.create(LocalizedStrings.DebuggerSupport_DEBUGGER_CONTINUING));
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/49b2913a/gemfire-core/src/test/java/com/gemstone/gemfire/distributed/DistributedMemberDUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/distributed/DistributedMemberDUnitTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/distributed/DistributedMemberDUnitTest.java
index dd35794..e45b02d 100755
--- a/gemfire-core/src/test/java/com/gemstone/gemfire/distributed/DistributedMemberDUnitTest.java
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/distributed/DistributedMemberDUnitTest.java
@@ -7,16 +7,48 @@
  */
 package com.gemstone.gemfire.distributed;
 
+import static java.util.concurrent.TimeUnit.*;
+import static org.hamcrest.Matchers.*;
+import static org.junit.Assert.*;
+import static org.junit.Assume.*;
+import static com.jayway.awaitility.Awaitility.*;
+import static com.jayway.awaitility.Duration.*;
+
 import com.gemstone.gemfire.IncompatibleSystemException;
-import com.gemstone.gemfire.distributed.internal.*;
-import dunit.*;
+import com.gemstone.gemfire.distributed.internal.DM;
+import com.gemstone.gemfire.distributed.internal.DistributionConfig;
+import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
+import com.gemstone.gemfire.distributed.internal.membership.InternalDistributedMember;
+import com.gemstone.gemfire.internal.lang.SystemUtils;
 
 import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.*;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+import java.util.concurrent.Callable;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.rules.ExpectedException;
 
-import com.gemstone.gemfire.distributed.internal.membership.*;
-import junit.framework.AssertionFailedError;
+import com.gemstone.gemfire.test.junit.ConditionalIgnore;
+import com.gemstone.gemfire.test.junit.categories.DistributedTest;
+import com.gemstone.gemfire.test.junit.categories.MembershipTest;
+import com.gemstone.gemfire.test.junit.rules.ConditionalIgnoreRule;
+import com.gemstone.gemfire.test.dunit.DistributedTestCase;
+import com.gemstone.gemfire.test.dunit.Host;
+import com.gemstone.gemfire.test.dunit.RMIException;
+import com.gemstone.gemfire.test.dunit.SerializableCallable;
+import com.gemstone.gemfire.test.dunit.SerializableRunnable;
+import com.gemstone.gemfire.test.dunit.VM;
 
 /**
  * Tests the functionality of the {@link DistributedMember} class.
@@ -24,137 +56,132 @@ import junit.framework.AssertionFailedError;
  * @author Kirk Lund
  * @since 5.0
  */
+@SuppressWarnings("serial")
+@Category({ DistributedTest.class, MembershipTest.class })
 public class DistributedMemberDUnitTest extends DistributedTestCase {
 
-  public DistributedMemberDUnitTest(String name) {
-    super(name);
+  private Properties config;
+  
+  @Rule
+  public final transient ExpectedException expectedException = ExpectedException.none();
+  
+  @Rule
+  public final transient ConditionalIgnoreRule ignoreRule = new ConditionalIgnoreRule();
+  
+  @BeforeClass
+  public static void beforeClass() {
+    disconnectAllFromDS();
   }
   
-  protected void sleep(long millis) {
-    try {
-      Thread.sleep(millis);
-    }
-    catch (InterruptedException e) {
-      fail("interrupted");
-    }
+  @Before
+  public void setUp() {
+    this.config = createConfig();
   }
   
+  @After
+  public void tearDown() {
+    disconnectAllFromDS();
+  }
+
   /**
-   * Tests default settings.
+   * Tests default configuration values.
    */
-  public void testDefaults() {
-    Properties config = new Properties();
-    config.setProperty(DistributionConfig.MCAST_PORT_NAME, "0"); 
-    config.setProperty(DistributionConfig.LOCATORS_NAME, ""); 
-    config.setProperty(DistributionConfig.ROLES_NAME, "");
-    config.setProperty(DistributionConfig.GROUPS_NAME, "");
-    config.setProperty(DistributionConfig.NAME_NAME, "");
+  @Test
+  public void defaultConfigShouldHaveEmptyValues() {
+    // arrange
+    this.config.setProperty(DistributionConfig.LOCATORS_NAME, ""); 
+    this.config.setProperty(DistributionConfig.ROLES_NAME, "");
+    this.config.setProperty(DistributionConfig.GROUPS_NAME, "");
+    this.config.setProperty(DistributionConfig.NAME_NAME, "");
 
-    InternalDistributedSystem system = getSystem(config);
-    try {
-      assertTrue(system.getConfig().getRoles().equals(
-          DistributionConfig.DEFAULT_ROLES));
-      assertTrue(system.getConfig().getGroups().equals(
-          DistributionConfig.DEFAULT_ROLES));
-      assertTrue(system.getConfig().getName().equals(
-          DistributionConfig.DEFAULT_NAME));
+    // act
+    final InternalDistributedSystem system = getSystem(this.config);
+    final InternalDistributedMember member = system.getDistributedMember();
 
-      DM dm = system.getDistributionManager();
-      InternalDistributedMember member = dm.getDistributionManagerId();
-      
-      Set roles = member.getRoles();
-      assertEquals(0, roles.size());
-      assertEquals("", member.getName());
-      assertEquals(Collections.emptyList(), member.getGroups());
-    } 
-    finally {
-      system.disconnect();
-    }
+    // assert
+    assertThat(system.getConfig().getRoles(), is(DistributionConfig.DEFAULT_ROLES));
+    assertThat(system.getConfig().getGroups(), is(DistributionConfig.DEFAULT_ROLES));
+    assertThat(system.getConfig().getName(), is(DistributionConfig.DEFAULT_NAME));
+    
+    assertThat(member.getRoles(), is(empty()));
+    assertThat(member.getName(), isEmptyString());
+    assertThat(member.getGroups(), is(empty()));
   }
 
-  public void testNonDefaultName() {
-    Properties config = new Properties();
-    config.setProperty(DistributionConfig.MCAST_PORT_NAME, "0"); 
-    config.setProperty(DistributionConfig.LOCATORS_NAME, ""); 
-    config.setProperty(DistributionConfig.NAME_NAME, "nondefault");
+  @Test
+  public void nameShouldBeUsed() {
+    // arrange
+    this.config.setProperty(DistributionConfig.LOCATORS_NAME, ""); 
+    this.config.setProperty(DistributionConfig.NAME_NAME, "nondefault");
 
-    InternalDistributedSystem system = getSystem(config);
-    try {
-      assertEquals("nondefault", system.getConfig().getName());
+    // act
+    final InternalDistributedSystem system = getSystem(this.config);
+    final InternalDistributedMember member = system.getDistributedMember();
 
-      DM dm = system.getDistributionManager();
-      InternalDistributedMember member = dm.getDistributionManagerId();
-      
-      assertEquals("nondefault", member.getName());
-    } 
-    finally {
-      system.disconnect();
-    }
+    // assert
+    assertThat(system.getConfig().getName(), is("nondefault"));
+    assertThat(member.getName(), is("nondefault"));
   }
 
   /**
    * Tests the configuration of many Roles and groups in one vm.
    * Confirms no runtime distinction between roles and groups.
    */
-  public void testRolesInOneVM() {
-    final String rolesProp = "A,B,C";
-    final String groupsProp = "D,E,F,G";
-    final List bothList = Arrays.asList(new String[] {"A","B","C","D","E","F","G"});
+  @Test
+  public void multipleRolesAndGroupsAreUsed() {
+    // arrange
+    final String roles = "A,B,C";
+    final String groups = "D,E,F,G";
+    final List<String> rolesAndGroups = Arrays.asList((roles+","+groups).split(","));
     
-    Properties config = new Properties();
-    config.setProperty(DistributionConfig.MCAST_PORT_NAME, "0"); 
-    config.setProperty(DistributionConfig.LOCATORS_NAME, ""); 
-    config.setProperty(DistributionConfig.ROLES_NAME, rolesProp);
-    config.setProperty(DistributionConfig.GROUPS_NAME, groupsProp);
+    this.config.setProperty(DistributionConfig.LOCATORS_NAME, ""); 
+    this.config.setProperty(DistributionConfig.ROLES_NAME, roles);
+    this.config.setProperty(DistributionConfig.GROUPS_NAME, groups);
 
-    InternalDistributedSystem system = getSystem(config);
-    try {
-      assertEquals(rolesProp, system.getConfig().getRoles());
-      assertEquals(groupsProp, system.getConfig().getGroups());
-      
-      DM dm = system.getDistributionManager();
-      InternalDistributedMember member = dm.getDistributionManagerId();
-      
-      Set roles = member.getRoles();
-      assertEquals(bothList.size(), roles.size());
-      
-      for (Iterator iter = roles.iterator(); iter.hasNext();) {
-        Role role = (Role) iter.next();
-        assertTrue(bothList.contains(role.getName()));
-      }
-      
-      assertEquals(bothList, member.getGroups());
-    } 
-    finally {
-      system.disconnect();
+    // act
+    final InternalDistributedSystem system = getSystem(this.config);
+    final InternalDistributedMember member = system.getDistributedMember();
+
+    // assert
+    assertThat(system.getConfig().getRoles(), is(roles));
+    assertThat(system.getConfig().getGroups(), is(groups));
+    assertThat(member.getRoles().size(), is(rolesAndGroups.size()));
+    for (Role role : member.getRoles()) {
+      assertThat(role.getName(), isIn(rolesAndGroups));
     }
+    assertThat(member.getGroups(), is(rolesAndGroups));
   }
 
-  public void testTwoMembersSameName() {
-    disconnectFromDS(); // or assertion on # members fails when run-dunit-tests
+  @Test
+  public void secondMemberUsingSameNameShouldFail() {
     Host.getHost(0).getVM(0).invoke(new SerializableRunnable() {
       public void run() {
-        Properties config = new Properties();
+        Properties config = createConfig();
         config.setProperty(DistributionConfig.NAME_NAME, "name0");
         getSystem(config);
       }
     });
     Host.getHost(0).getVM(1).invoke(new SerializableRunnable() {
       public void run() {
-        Properties config = new Properties();
+        Properties config = createConfig();
         config.setProperty(DistributionConfig.NAME_NAME, "name1");
         getSystem(config);
       }
     });
+    
+    expectedException.expect(RMIException.class);
+    expectedException.expectCause(isA(IncompatibleSystemException.class));
+    //expectedException.expectMessage("used the same name");
+    
     Host.getHost(0).getVM(2).invoke(new SerializableRunnable() {
       public void run() {
-        Properties config = new Properties();
+        Properties config = createConfig();
         config.setProperty(DistributionConfig.NAME_NAME, "name0");
-        try {
+//        try {
           getSystem(config);
-          fail("expected IncompatibleSystemException");
-        } catch (IncompatibleSystemException expected) {
-        }
+//          fail("expected IncompatibleSystemException");
+//        } catch (IncompatibleSystemException expected) {
+//        }
       }
     });
   }
@@ -163,17 +190,15 @@ public class DistributedMemberDUnitTest extends DistributedTestCase {
    * Tests the configuration of one unique Role in each of four vms. Verifies 
    * that each vm is aware of the other vms' Roles.
    */
-  public void testRolesInAllVMs() {  
-    disconnectAllFromDS(); // or assertion on # members fails when run-dunit-tests
-
+  @Test
+  public void allMembersShouldSeeRoles() {
     // connect all four vms...
     final String[] vmRoles = new String[] {"VM_A","VM_B","VM_C","VM_D"};
     for (int i = 0; i < vmRoles.length; i++) {
       final int vm = i;
       Host.getHost(0).getVM(vm).invoke(new SerializableRunnable() {
         public void run() {
-          //disconnectFromDS();
-          Properties config = new Properties();
+          Properties config = createConfig();
           config.setProperty(DistributionConfig.ROLES_NAME, vmRoles[vm]);
           getSystem(config);
         }
@@ -189,36 +214,23 @@ public class DistributedMemberDUnitTest extends DistributedTestCase {
           assertNotNull(sys.getConfig().getRoles());
           assertTrue(sys.getConfig().getRoles().equals(vmRoles[vm]));
           
-          DM dm = sys.getDistributionManager();
-          InternalDistributedMember self = dm.getDistributionManagerId();
+          InternalDistributedMember self = sys.getDistributedMember();
           
-          Set myRoles = self.getRoles();
+          Set<Role> myRoles = self.getRoles();
           assertEquals(1, myRoles.size());
           
           Role myRole = (Role) myRoles.iterator().next();
           assertTrue(vmRoles[vm].equals(myRole.getName()));
           
-          Set members = null;
-          for (int i = 1; i <= 3; i++) {
-            try {
-              members = dm.getOtherNormalDistributionManagerIds();
-              assertEquals(3, members.size());
-              break;
-            }
-            catch (AssertionFailedError e) {
-              if (i < 3) {
-                sleep(200);
-              } else {
-                throw e;
-              }
-            }
-          }
+          with().pollInterval(TWO_HUNDRED_MILLISECONDS).await().atMost(60, SECONDS).until( numberOfOtherMembers(), equalTo(3) );
+          // used to have a for-loop here
           
-          for (Iterator iterMembers = members.iterator(); iterMembers.hasNext();) {
-            InternalDistributedMember member = (InternalDistributedMember) iterMembers.next();
-            Set roles = member.getRoles();
+          Set<InternalDistributedMember> members = sys.getDM().getOtherNormalDistributionManagerIds();
+          for (Iterator<InternalDistributedMember> iterMembers = members.iterator(); iterMembers.hasNext();) {
+            InternalDistributedMember member = iterMembers.next();
+            Set<Role> roles = member.getRoles();
             assertEquals(1, roles.size());
-            for (Iterator iterRoles = roles.iterator(); iterRoles.hasNext();) {
+            for (Iterator<Role> iterRoles = roles.iterator(); iterRoles.hasNext();) {
               Role role = (Role) iterRoles.next();
               assertTrue(!role.getName().equals(myRole.getName()));
               boolean foundRole = false;
@@ -236,26 +248,26 @@ public class DistributedMemberDUnitTest extends DistributedTestCase {
     }
   }
 
-  private static String makeOddEvenString(int vm) {
-    return ((vm % 2) == 0) ? "EVENS" : "ODDS";
-  }
-  private static String makeGroupsString(int vm) {
-    return "" + vm + ", " + makeOddEvenString(vm);
+  private Callable<Integer> numberOfOtherMembers() {
+    return new Callable<Integer>() {
+      public Integer call() throws Exception {
+        return getSystem().getDM().getOtherNormalDistributionManagerIds().size();
+      }
+    };
   }
+  
   /**
    * Tests the configuration of one unique group in each of four vms. Verifies 
    * that each vm is aware of the other vms' groups.
    */
-  public void testGroupsInAllVMs() {  
-    disconnectFromDS(); // or assertion on # members fails when run-dunit-tests
-
+  @Test
+  public void allMembersShouldSeeGroups() {  
     // connect all four vms...
     for (int i = 0; i < 4; i++) {
       final int vm = i;
       Host.getHost(0).getVM(vm).invoke(new SerializableRunnable() {
         public void run() {
-          //disconnectFromDS();
-          Properties config = new Properties();
+          final Properties config = createConfig();
           config.setProperty(DistributionConfig.GROUPS_NAME, makeGroupsString(vm));
           getSystem(config);
         }
@@ -285,7 +297,7 @@ public class DistributedMemberDUnitTest extends DistributedTestCase {
               assertEquals(3, members.size());
               break;
             }
-            catch (AssertionFailedError e) {
+            catch (AssertionError e) {
               if (i < 3) {
                 sleep(200);
               } else {
@@ -300,8 +312,8 @@ public class DistributedMemberDUnitTest extends DistributedTestCase {
           others.removeAll(dm.getOtherNormalDistributionManagerIds());
           assertEquals(1, others.size());
           // test getGroupMembers
-          HashSet<DistributedMember> evens = new HashSet<DistributedMember>();
-          HashSet<DistributedMember> odds = new HashSet<DistributedMember>();
+          Set<DistributedMember> evens = new HashSet<DistributedMember>();
+          Set<DistributedMember> odds = new HashSet<DistributedMember>();
           boolean isEvens = true;
           for (String groupName: Arrays.asList("0", "1", "2", "3")) {
             Set<DistributedMember> gm = sys.getGroupMembers(groupName);
@@ -337,74 +349,99 @@ public class DistributedMemberDUnitTest extends DistributedTestCase {
    * Changing the id can result in bad keys in JMX and can result in numerous
    * errors in Admin/JMX tests.
    */
-  public void testGetId() {
-    Properties config = new Properties();
-    config.setProperty(DistributionConfig.MCAST_PORT_NAME, "0");
-    config.setProperty(DistributionConfig.LOCATORS_NAME, "");
-    config.setProperty(DistributionConfig.NAME_NAME, "foobar");
+  @Test
+  public void getIdShouldIdentifyMember() {
+    this.config.setProperty(DistributionConfig.LOCATORS_NAME, "");
+    this.config.setProperty(DistributionConfig.NAME_NAME, "foobar");
 
-    InternalDistributedSystem system = getSystem(config);
-    try {
-
-      DM dm = system.getDistributionManager();
-      DistributedMember member = dm.getDistributionManagerId();
-      
-      assertEquals(member.getId(), system.getMemberId());
-      assertTrue(member.getId().contains("foobar"));
-    } 
-    finally {
-      system.disconnect();
-    }
+    final InternalDistributedSystem system = getSystem(this.config);
+    final DistributedMember member = system.getDistributedMember();
+    
+    assertThat(system.getMemberId(), is(member.getId()));
+    assertThat(member.getId(), containsString("foobar"));
   }
   
-  public void testFindMemberByName() {
-    disconnectAllFromDS(); // or assertion on # members fails when run-dunit-tests
-    VM vm0 = Host.getHost(0).getVM(0);
-    VM vm1 = Host.getHost(0).getVM(1);
-    VM vm2 = Host.getHost(0).getVM(2);
+  /**
+   * TODO: move to DistributedSystem DUnit Test
+   */
+  @Test
+  public void findDistributedMembersByNameShouldReturnOneMember() {
+    final VM vm0 = Host.getHost(0).getVM(0);
+    final VM vm1 = Host.getHost(0).getVM(1);
+    final VM vm2 = Host.getHost(0).getVM(2);
+    
     final DistributedMember member0 = createSystemAndGetId(vm0, "name0");
     final DistributedMember member1 = createSystemAndGetId(vm1, "name1");
     final DistributedMember member2 = createSystemAndGetId(vm2, "name2");
-    vm0.invoke(new SerializableRunnable() {
-      public void run() {
+    
+    vm0.invoke(new SerializableCallable() { // SerializableRunnable
+      public Object call() throws Exception { // public void run() 
         DistributedSystem system = getSystem();
         assertEquals(member0, system.findDistributedMember("name0"));
         assertEquals(member1, system.findDistributedMember("name1"));
         assertEquals(member2, system.findDistributedMember("name2"));
         assertNull(system.findDistributedMember("name3"));
 
-        Set<DistributedMember> members;
-        try {
-          members = system.findDistributedMembers(InetAddress.getByName(member0.getHost()));
-          HashSet expected = new HashSet();
-          expected.add(member0);
-          expected.add(member1);
-          expected.add(member2);
-          
-          //Members will contain the locator as well. Just make sure it has
-          //the members we're looking for.
-          assertTrue("Expected" + expected + " got " + members, members.containsAll(expected));
-          assertEquals(4, members.size());
-        } catch (UnknownHostException e) {
-          fail("Unable to get IpAddress", e);
-        }
+        Set<DistributedMember> members = system.findDistributedMembers(InetAddress.getByName(member0.getHost()));
+        Set<DistributedMember> expected = new HashSet<DistributedMember>();
+        expected.add(member0);
+        expected.add(member1);
+        expected.add(member2);
+        
+        // Members will contain the locator as well. Just make sure it has the members we're looking for.
+        assertTrue("Expected" + expected + " got " + members, members.containsAll(expected));
+        assertEquals(4, members.size());
+//        } catch (UnknownHostException e) {
+//          fail("Unable to get IpAddress", e);
+//        }
+        return null;
       }
     });
   }
   
-  private DistributedMember createSystemAndGetId(VM vm, final String name) {
+  @Test
+  public void linuxSpecificTest() {
+    assumeTrue(SystemUtils.isLinux());
+    // do something that is only supported on linux
+  }
+  
+  @Test
+  @ConditionalIgnore(value="#55555: summary of bug #55555", until="2016-01-01")
+  public void someBrokenTest() {
+    throw new Error("Bug #55555");
+  }
+  
+  private DistributedMember createSystemAndGetId(final VM vm, final String name) {
     return (DistributedMember) vm.invoke(new SerializableCallable("create system and get member") {
-      
       @Override
       public Object call() throws Exception {
-        Properties config = new Properties();
+        final Properties config = createConfig();
         config.setProperty(DistributionConfig.NAME_NAME, name);
-        DistributedSystem ds = getSystem(config);
+        final DistributedSystem ds = getSystem(config);
         return ds.getDistributedMember();
       }
     });
   }
+
+  private static Properties createConfig() {
+    final Properties props = new Properties();
+    props.setProperty(DistributionConfig.MCAST_PORT_NAME, "0");
+    return props;
+  }
   
-}
+  private void sleep(final long millis) {
+    try {
+      Thread.sleep(millis);
+    } catch (InterruptedException e) {
+      fail("interrupted");
+    }
+  }
   
-
+  private static String makeOddEvenString(final int vm) {
+    return ((vm % 2) == 0) ? "EVENS" : "ODDS";
+  }
+  
+  private static String makeGroupsString(final int vm) {
+    return "" + vm + ", " + makeOddEvenString(vm);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/49b2913a/gemfire-core/src/test/java/com/gemstone/gemfire/distributed/HostedLocatorsDUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/distributed/HostedLocatorsDUnitTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/distributed/HostedLocatorsDUnitTest.java
index a0e54d5..e74e12f 100644
--- a/gemfire-core/src/test/java/com/gemstone/gemfire/distributed/HostedLocatorsDUnitTest.java
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/distributed/HostedLocatorsDUnitTest.java
@@ -1,5 +1,10 @@
 package com.gemstone.gemfire.distributed;
 
+import static com.jayway.awaitility.Awaitility.*;
+import static java.util.concurrent.TimeUnit.*;
+import static org.hamcrest.Matchers.*;
+import static org.junit.Assert.*;
+
 import java.io.File;
 import java.util.Collection;
 import java.util.HashSet;
@@ -7,6 +12,14 @@ import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.Callable;
 
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.contrib.java.lang.system.RestoreSystemProperties;
+import org.junit.experimental.categories.Category;
+import org.junit.rules.Timeout;
+
 import com.gemstone.gemfire.distributed.AbstractLauncher.Status;
 import com.gemstone.gemfire.distributed.LocatorLauncher.Builder;
 import com.gemstone.gemfire.distributed.LocatorLauncher.LocatorState;
@@ -18,10 +31,13 @@ import com.gemstone.gemfire.internal.AvailablePortHelper;
 import com.gemstone.gemfire.internal.SocketCreator;
 import com.gemstone.gemfire.internal.util.StopWatch;
 
-import dunit.DistributedTestCase;
-import dunit.Host;
-import dunit.SerializableCallable;
-import dunit.SerializableRunnable;
+import com.gemstone.gemfire.test.dunit.DistributedTestCase;
+import com.gemstone.gemfire.test.dunit.Host;
+import com.gemstone.gemfire.test.dunit.SerializableCallable;
+import com.gemstone.gemfire.test.dunit.SerializableRunnable;
+import com.gemstone.gemfire.test.junit.categories.DistributedTest;
+import com.gemstone.gemfire.test.junit.categories.MembershipTest;
+import com.gemstone.gemfire.test.junit.rules.Retry;
 
 /**
  * Extracted from LocatorLauncherLocalJUnitTest.
@@ -29,26 +45,36 @@ import dunit.SerializableRunnable;
  * @author Kirk Lund
  * @since 8.0
  */
+@SuppressWarnings("serial")
+@Category({ DistributedTest.class, MembershipTest.class })
 public class HostedLocatorsDUnitTest extends DistributedTestCase {
 
-  protected static final int TIMEOUT_MILLISECONDS = 5 * 60 * 1000; // 5 minutes
+  //protected static final int TIMEOUT_MILLISECONDS = 5 * 60 * 1000; // 5 minutes
 
   protected transient volatile int locatorPort;
   protected transient volatile LocatorLauncher launcher;
   
+  @Rule // not serializable and yet we're setting/clearing in other JVMs
+  public final transient RestoreSystemProperties restoreSystemProperties = new RestoreSystemProperties();
+  
+  @Rule
+  public final transient Timeout globalTimeout = Timeout.seconds(2 * 60 * 1000);
+  
+  @Rule
+  public final transient Retry retry = new Retry(2);
+  
+  @Before
   public void setUp() throws Exception {
     disconnectAllFromDS();
   }
   
-  public void tearDown2() throws Exception {
+  @After
+  public void tearDown() throws Exception {
     disconnectAllFromDS();
   }
   
-  public HostedLocatorsDUnitTest(String name) {
-    super(name);
-  }
-
-  public void testGetAllHostedLocators() throws Exception {
+  @Test
+  public void getAllHostedLocators() throws Exception {
     final InternalDistributedSystem system = getSystem();
     final String dunitLocator = system.getConfig().getLocators();
     assertNotNull(dunitLocator);
@@ -79,7 +105,8 @@ public class HostedLocatorsDUnitTest extends DistributedTestCase {
     
             launcher = builder.build();
             assertEquals(Status.ONLINE, launcher.start().getStatus());
-            waitForLocatorToStart(launcher, TIMEOUT_MILLISECONDS, 10, true);
+            //was: waitForLocatorToStart(launcher, TIMEOUT_MILLISECONDS, 10, true);
+            with().pollInterval(10, MILLISECONDS).await().atMost(5, MINUTES).until( isLocatorStarted() );
             return null;
           } finally {
             System.clearProperty("gemfire.locators");
@@ -154,6 +181,23 @@ public class HostedLocatorsDUnitTest extends DistributedTestCase {
     }
   }
 
+  @Test
+  public void unreliableTestWithRaceConditions() {
+    count++;
+    if (count < 2) {
+      assertThat(count, is(2)); // doomed to fail
+    }
+  }
+  
+  private Callable<Boolean> isLocatorStarted() {
+    return new Callable<Boolean>() {
+      public Boolean call() throws Exception {
+        final LocatorState LocatorState = launcher.status();
+        return (LocatorState != null && Status.ONLINE.equals(LocatorState.getStatus()));
+      }
+    };
+  }
+  
   protected void waitForLocatorToStart(final LocatorLauncher launcher, int timeout, int interval, boolean throwOnTimeout) throws Exception {
     assertEventuallyTrue("waiting for process to start: " + launcher.status(), new Callable<Boolean>() {
       @Override
@@ -176,4 +220,6 @@ public class HostedLocatorsDUnitTest extends DistributedTestCase {
     }
     assertTrue(message, done);
   }
+  
+  private static int count = 0;
 }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/49b2913a/gemfire-core/src/test/java/com/gemstone/gemfire/distributed/MembershipTestSuite.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/distributed/MembershipTestSuite.java b/gemfire-core/src/test/java/com/gemstone/gemfire/distributed/MembershipTestSuite.java
new file mode 100755
index 0000000..c96bf43
--- /dev/null
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/distributed/MembershipTestSuite.java
@@ -0,0 +1,17 @@
+package com.gemstone.gemfire.distributed;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+@RunWith(Suite.class)
+@Suite.SuiteClasses({
+  DistributedMemberDUnitTest.class,
+  HostedLocatorsDUnitTest.class,
+})
+/**
+ * Suite of tests for Membership.
+ * 
+ * @author Kirk Lund
+ */
+public class MembershipTestSuite {
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/49b2913a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/OutOfOffHeapMemoryDUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/OutOfOffHeapMemoryDUnitTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/OutOfOffHeapMemoryDUnitTest.java
index a7921ee..644d82c 100755
--- a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/OutOfOffHeapMemoryDUnitTest.java
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/OutOfOffHeapMemoryDUnitTest.java
@@ -1,16 +1,23 @@
 package com.gemstone.gemfire.internal.offheap;
 
+import static com.gemstone.gemfire.test.dunit.ExpectedExceptionString.*;
+import static com.gemstone.gemfire.test.dunit.Invoke.*;
+import static com.gemstone.gemfire.test.dunit.Wait.*;
+import static org.junit.Assert.*;
+
 import java.util.Properties;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicReference;
 
 import org.apache.logging.log4j.Logger;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
 
 import com.gemstone.gemfire.OutOfOffHeapMemoryException;
 import com.gemstone.gemfire.cache.Cache;
 import com.gemstone.gemfire.cache.Region;
 import com.gemstone.gemfire.cache.RegionShortcut;
-import com.gemstone.gemfire.cache30.CacheTestCase;
 import com.gemstone.gemfire.distributed.DistributedSystem;
 import com.gemstone.gemfire.distributed.DistributedSystemDisconnectedException;
 import com.gemstone.gemfire.distributed.internal.DistributionConfig;
@@ -21,49 +28,33 @@ import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
 import com.gemstone.gemfire.internal.cache.OffHeapTestUtil;
 import com.gemstone.gemfire.internal.logging.LogService;
 import com.gemstone.gemfire.internal.util.StopWatch;
+import com.gemstone.gemfire.test.dunit.cache.CacheTestCase;
+import com.gemstone.gemfire.test.junit.categories.DistributedTest;
 
-import dunit.Host;
-import dunit.SerializableRunnable;
+import com.gemstone.gemfire.test.dunit.Host;
+import com.gemstone.gemfire.test.dunit.SerializableRunnable;
+import com.gemstone.gemfire.test.dunit.WaitCriterion;
 
 /**
  * Test behavior of region when running out of off-heap memory.
  * 
  * @author Kirk Lund
  */
-@SuppressWarnings("serial")
+@SuppressWarnings({ "serial", "unused" })
+@Category(DistributedTest.class)
 public class OutOfOffHeapMemoryDUnitTest extends CacheTestCase {
   private static final Logger logger = LogService.getLogger();
   
   protected static final AtomicReference<Cache> cache = new AtomicReference<Cache>();
   protected static final AtomicReference<DistributedSystem> system = new AtomicReference<DistributedSystem>();
   protected static final AtomicBoolean isSmallerVM = new AtomicBoolean();
-  
-  public OutOfOffHeapMemoryDUnitTest(String name) {
-    super(name);
-  }
 
-  @Override
-  public void setUp() throws Exception {
+  @Before
+  public void setUpOutOfOffHeapMemoryDUnitTest() throws Exception {
     disconnectAllFromDS();
-    super.setUp();
-    addExpectedException(OutOfOffHeapMemoryException.class.getSimpleName());
+    addExpectedExceptionString(OutOfOffHeapMemoryException.class.getSimpleName());
   }
   
-//  public static void caseSetUp() {
-//    //disconnectAllFromDS();
-//    for (int i = 0; i < Host.getHost(0).getVMCount(); i++) {
-//      Host.getHost(0).getVM(i).invoke(new SerializableRunnable() {
-//        public void run() {
-//          InternalDistributedSystem ids = InternalDistributedSystem.getAnyInstance();
-//          if (ids != null && ids.isConnected()) {
-//            logger.warn(OutOfOffHeapMemoryDUnitTest.class.getSimpleName() + " found DistributedSystem connection from previous test: {}", ids);
-//            ids.disconnect();
-//          }
-//        }
-//      });
-//    }
-//  }
-
   @Override
   public void tearDown2() throws Exception {
     final SerializableRunnable checkOrphans = new SerializableRunnable() {
@@ -83,7 +74,6 @@ public class OutOfOffHeapMemoryDUnitTest extends CacheTestCase {
     }
   }
 
-  @SuppressWarnings("unused") // invoked by reflection from tearDown2()
   private static void cleanup() {
     disconnectFromDS();
     SimpleMemoryAllocatorImpl.freeOffHeapMemory();
@@ -121,6 +111,7 @@ public class OutOfOffHeapMemoryDUnitTest extends CacheTestCase {
     return props;
   }
   
+  @Test
   public void testSimpleOutOfOffHeapMemoryMemberDisconnects() {
     final DistributedSystem system = getSystem();
     final Cache cache = getCache();
@@ -209,6 +200,7 @@ public class OutOfOffHeapMemoryDUnitTest extends CacheTestCase {
     }
   }
   
+  @Test
   public void testOtherMembersSeeOutOfOffHeapMemoryMemberDisconnects() {
     final int vmCount = Host.getHost(0).getVMCount();
     assertEquals(4, vmCount);
@@ -301,44 +293,4 @@ public class OutOfOffHeapMemoryDUnitTest extends CacheTestCase {
       });
     }
   }
-
-//  private static void foo() {
-//    final WaitCriterion waitForDisconnect = new WaitCriterion() {
-//      public boolean done() {
-//        return cache.isClosed() && !system.isConnected() && dm.isClosed();
-//      }
-//      public String description() {
-//        return "Waiting for cache, system and dm to close";
-//      }
-//    };
-//    waitForCriterion(waitForDisconnect, 10*1000, 100, true);
-//  }
-  
-  // setUp() and caseSetUp() are commented out -- they were in place because of incompatible DistributedSystem bleed over from earlier DUnit tests
-  
-//@Override
-//public void setUp() throws Exception {
-//  super.setUp();
-//  long begin = System.currentTimeMillis();
-//  Cache gfc = null;
-//  while (gfc == null) {
-//    try {
-//      gfc = getCache();
-//      break;
-//    } catch (IllegalStateException e) {
-//      if (System.currentTimeMillis() > begin+60*1000) {
-//        fail("OutOfOffHeapMemoryDUnitTest waited too long to getCache", e);
-//      } else if (e.getMessage().contains("A connection to a distributed system already exists in this VM.  It has the following configuration")) {
-//        InternalDistributedSystem ids = InternalDistributedSystem.getAnyInstance();
-//        if (ids != null && ids.isConnected()) {
-//          ids.getLogWriter().warning("OutOfOffHeapMemoryDUnitTest found DistributedSystem connection from previous test", e);
-//          ids.disconnect();
-//        }
-//      } else {
-//        throw e;
-//      }
-//    }
-//  }
-//}
-
 }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/49b2913a/gemfire-core/src/test/java/com/gemstone/gemfire/test/catchexception/CatchExceptionDUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/test/catchexception/CatchExceptionDUnitTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/test/catchexception/CatchExceptionDUnitTest.java
new file mode 100755
index 0000000..a3fc1f1
--- /dev/null
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/test/catchexception/CatchExceptionDUnitTest.java
@@ -0,0 +1,63 @@
+package com.gemstone.gemfire.test.catchexception;
+
+import static com.googlecode.catchexception.CatchException.*;
+import static com.googlecode.catchexception.apis.BDDCatchException.when;
+import static com.googlecode.catchexception.apis.CatchExceptionHamcrestMatchers.*;
+import static org.assertj.core.api.BDDAssertions.*;
+import static org.hamcrest.Matchers.*;
+import static org.junit.Assert.*;
+import static org.hamcrest.Matchers.instanceOf;
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
+
+import org.junit.Test;
+
+import com.gemstone.gemfire.test.dunit.DistributedTestCase;
+import com.gemstone.gemfire.test.dunit.Host;
+import com.gemstone.gemfire.test.dunit.RMIException;
+import com.gemstone.gemfire.test.dunit.SerializableCallable;
+import com.gemstone.gemfire.test.dunit.VM;
+
+/**
+ * Using Catch-Exception works well for remote exceptions and asserting details
+ * about root cause of RMIExceptions in DUnit tests.
+ */
+public class CatchExceptionDUnitTest extends DistributedTestCase {
+  private static final long serialVersionUID = 1L;
+
+  private static final String REMOTE_THROW_EXCEPTION_MESSAGE = "Throwing remoteThrowException";
+
+  @Test
+  public void testRemoteInvocationWithException() {
+    Host host = Host.getHost(0);
+    VM vm = host.getVM(0);
+
+    when(vm).invoke(new ThrowBasicTestException());
+
+    then(caughtException())
+        .isInstanceOf(RMIException.class)
+        .hasCause(new BasicTestException(REMOTE_THROW_EXCEPTION_MESSAGE));
+  }
+  
+  protected static class ThrowBasicTestException extends SerializableCallable<Object> {
+    private static final long serialVersionUID = 1L;
+    
+    @Override
+    public Object call() throws Exception {
+      throw new BasicTestException(REMOTE_THROW_EXCEPTION_MESSAGE);
+    }
+  }
+  
+  protected static class BasicTestException extends RuntimeException {
+    private static final long serialVersionUID = 1L;
+
+    public BasicTestException() {
+      super();
+    }
+    
+    public BasicTestException(String message) {
+      super(message);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/49b2913a/gemfire-core/src/test/java/com/gemstone/gemfire/test/catchexception/CatchExceptionJUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/test/catchexception/CatchExceptionJUnitTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/test/catchexception/CatchExceptionJUnitTest.java
new file mode 100755
index 0000000..d197745
--- /dev/null
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/test/catchexception/CatchExceptionJUnitTest.java
@@ -0,0 +1,95 @@
+package com.gemstone.gemfire.test.catchexception;
+
+import static com.googlecode.catchexception.CatchException.*;
+import static com.googlecode.catchexception.apis.BDDCatchException.when;
+import static com.googlecode.catchexception.apis.CatchExceptionHamcrestMatchers.*;
+import static org.assertj.core.api.BDDAssertions.*;
+import static org.hamcrest.Matchers.*;
+import static org.junit.Assert.*;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Test;
+
+/**
+ * Simple unit tests exercising Catch-Exception with AssertJ, Hamcrest and JUnit.
+ */
+public class CatchExceptionJUnitTest {
+
+  @Test
+  public void catchExceptionShouldCatchException() {
+    List<?> myList = new ArrayList<Object>();
+
+    // when: we try to get the first element of the list
+    // then: catch the exception if any is thrown
+    catchException(myList).get(1);
+    
+    // then: we expect an IndexOutOfBoundsException
+    assertThat(caughtException(), is(instanceOf(IndexOutOfBoundsException.class)));
+  }
+  
+  @Test
+  public void verifyExceptionShouldCatchException() {
+    List<?> myList = new ArrayList<Object>();
+
+    // when: we try to get the first element of the list
+    // then: catch the exception if any is thrown
+    // then: we expect an IndexOutOfBoundsException
+    verifyException(myList, IndexOutOfBoundsException.class).get(1);
+  }
+  
+  @Test
+  public void whenShouldCatchExceptionAndUseAssertJAssertion() {
+    // given: an empty list
+    List<?> myList = new ArrayList<Object>();
+
+    // when: we try to get the first element of the list
+    when(myList).get(1);
+
+    // then: we expect an IndexOutOfBoundsException
+    then(caughtException())
+            .isInstanceOf(IndexOutOfBoundsException.class)
+            .hasMessage("Index: 1, Size: 0")
+            .hasNoCause();
+  }
+  
+  @Test
+  public void catchExceptionShouldCatchExceptionAndUseHamcrestAssertion() {
+    // given: an empty list
+    List<?> myList = new ArrayList<Object>();
+
+    // when: we try to get the first element of the list
+    catchException(myList).get(1);
+
+    // then: we expect an IndexOutOfBoundsException with message "Index: 1, Size: 0"
+    assertThat(caughtException(),
+      allOf(
+        instanceOf(IndexOutOfBoundsException.class),
+        hasMessage("Index: 1, Size: 0"),
+        hasNoCause()
+      )
+    );
+  }
+  
+  @Test
+  public void shouldCatchFromThrowException() throws Exception {
+    String message = "error message";
+    
+    catchException(this).throwException(message);
+    
+    assertThat(caughtException(), is(instanceOf(Exception.class)));
+  }
+  
+  @Test
+  public void shouldVerifyFromThrowException() throws Exception {
+    String message = "error message";
+
+    verifyException(this).throwException(message);
+  }
+  
+  // fails if private
+  protected void throwException(final String message) throws Exception {
+    throw new Exception(message);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/49b2913a/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/Assert.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/Assert.java b/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/Assert.java
new file mode 100755
index 0000000..a8ce347
--- /dev/null
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/Assert.java
@@ -0,0 +1,11 @@
+package com.gemstone.gemfire.test.dunit;
+
+/**
+ * Extracted from DistributedTestCase
+ */
+public class Assert extends org.junit.Assert {
+
+  public static void fail(final String message, final Throwable cause) {
+    throw new AssertionError(cause);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/49b2913a/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/AsyncInvocation.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/AsyncInvocation.java b/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/AsyncInvocation.java
new file mode 100644
index 0000000..0fdcd74
--- /dev/null
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/AsyncInvocation.java
@@ -0,0 +1,206 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.test.dunit;
+
+import java.util.concurrent.TimeoutException;
+
+import com.gemstone.gemfire.InternalGemFireError;
+import com.gemstone.gemfire.SystemFailure;
+
+// @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)
+/**
+ * <P>An <code>AsyncInvocation</code> represents the invocation of a
+ * remote invocation that executes asynchronously from its caller.  An
+ * instanceof <code>AsyncInvocation</code> provides information about
+ * the invocation such as any exception that it may have thrown.</P>
+ *
+ * <P>Because it is a <code>Thread</code>, an
+ * <code>AsyncInvocation</code> can be used as follows:</P>
+ *
+ * <PRE>
+ *   AsyncInvocation ai1 = vm.invokeAsync(Test.class, "method1");
+ *   AsyncInvocation ai2 = vm.invokeAsync(Test.class, "method2");
+ *
+ *   ai1.join();
+ *   ai2.join();
+ *
+ *   assertTrue("Exception occurred while invoking " + ai1,
+ *              !ai1.exceptionOccurred());
+ *   if (ai2.exceptionOccurred()) {
+ *     throw ai2.getException();
+ *   }
+ * </PRE>
+ *
+ * @see VM#invokeAsync(Class, String)
+ */
+public class AsyncInvocation extends Thread {
+  
+  private static final ThreadLocal returnValue = new ThreadLocal();
+
+  /** The singleton the thread group */
+  private static final ThreadGroup GROUP = new AsyncInvocationGroup();
+
+  ///////////////////// Instance Fields  /////////////////////
+
+  /** An exception thrown while this async invocation ran */
+  protected volatile Throwable exception;
+
+  /** The object (or class) that is the receiver of this asyn method
+   * invocation */
+  private Object receiver;
+
+  /** The name of the method being invoked */
+  private String methodName;
+  
+  /** The returned object if any */
+  public volatile Object returnedObj = null;
+
+  //////////////////////  Constructors  //////////////////////
+
+  /**
+   * Creates a new <code>AsyncInvocation</code>
+   *
+   * @param receiver
+   *        The object or {@link Class} on which the remote method was
+   *        invoked
+   * @param methodName
+   *        The name of the method being invoked
+   * @param work
+   *        The actual invocation of the method
+   */
+  public AsyncInvocation(Object receiver, String methodName, Runnable work) {
+    super(GROUP, work, getName(receiver, methodName));
+    this.receiver = receiver;
+    this.methodName = methodName;
+    this.exception = null;
+  }
+
+  //////////////////////  Static Methods  /////////////////////
+
+  /**
+   * Returns the name of a <code>AsyncInvocation</code> based on its
+   * receiver and method name.
+   */
+  private static String getName(Object receiver, String methodName) {
+    StringBuffer sb = new StringBuffer(methodName);
+    sb.append(" invoked on ");
+    if (receiver instanceof Class) {
+      sb.append("class ");
+      sb.append(((Class) receiver).getName());
+
+    } else {
+      sb.append("an instance of ");
+      sb.append(receiver.getClass().getName());
+    }
+
+    return sb.toString();
+  }
+
+  /////////////////////  Instance Methods  ////////////////////
+
+  /**
+   * Returns the receiver of this async method invocation
+   */
+  public Object getReceiver() {
+    return this.receiver;
+  }
+
+  /**
+   * Returns the name of the method being invoked remotely
+   */
+  public String getMethodName() {
+    return this.methodName;
+  }
+
+  /**
+   * Returns whether or not an exception occurred during this async
+   * method invocation.
+   */
+  public boolean exceptionOccurred() {
+    if (this.isAlive()) {
+      throw new InternalGemFireError("Exception status not available while thread is alive.");
+    }
+    return this.exception != null;
+  }
+
+  /**
+   * Returns the exception that was thrown during this async method
+   * invocation.
+   */
+  public Throwable getException() {
+    if (this.isAlive()) {
+      throw new InternalGemFireError("Exception status not available while thread is alive.");
+    }
+    if (this.exception instanceof RMIException) {
+      return ((RMIException) this.exception).getCause();
+
+    } else {
+      return this.exception;
+    }
+  }
+
+  //////////////////////  Inner Classes  //////////////////////
+
+  /**
+   * A <code>ThreadGroup</code> that notices when an exception occurrs
+   * during an <code>AsyncInvocation</code>.
+   */
+  private static class AsyncInvocationGroup extends ThreadGroup {
+    AsyncInvocationGroup() {
+      super("Async Invocations");
+    }
+
+    public void uncaughtException(Thread t, Throwable e) {
+      if (e instanceof VirtualMachineError) {
+        SystemFailure.setFailure((VirtualMachineError)e); // don't throw
+      }
+      if (t instanceof AsyncInvocation) {
+        ((AsyncInvocation) t).exception = e;
+      }
+    }
+  }
+  
+  public Object getResult() throws Throwable {
+    join();
+    if(this.exceptionOccurred()) {
+      throw new Exception("An exception occured during async invocation", this.exception);
+    }
+    return this.returnedObj;
+  }
+  
+  public Object getResult(long waitTime) throws Throwable {
+    join(waitTime);
+    if(this.isAlive()) {
+      throw new TimeoutException();
+    }
+    if(this.exceptionOccurred()) {
+      throw new Exception("An exception occured during async invocation", this.exception);
+    }
+    return this.returnedObj;
+  }
+
+  public Object getReturnValue() {
+    if (this.isAlive()) {
+      throw new InternalGemFireError("Return value not available while thread is alive.");
+    }
+    return this.returnedObj;
+  }
+  
+  public void run()
+  {
+    super.run();
+    this.returnedObj = returnValue.get();
+    returnValue.set(null);
+  }
+
+  static void setReturnValue(Object v) {
+    returnValue.set(v);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/49b2913a/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/BounceResult.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/BounceResult.java b/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/BounceResult.java
new file mode 100644
index 0000000..a766a2b
--- /dev/null
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/BounceResult.java
@@ -0,0 +1,20 @@
+package com.gemstone.gemfire.test.dunit;
+
+public class BounceResult {
+  private final int newPid;
+  private final RemoteDUnitVMIF newClient;
+  
+  public BounceResult(int newPid, RemoteDUnitVMIF newClient) {
+    this.newPid = newPid;
+    this.newClient = newClient;
+  }
+
+  public int getNewPid() {
+    return newPid;
+  }
+
+  public RemoteDUnitVMIF getNewClient() {
+    return newClient;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/49b2913a/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/DUnitEnv.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/DUnitEnv.java b/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/DUnitEnv.java
new file mode 100644
index 0000000..96ebd7d
--- /dev/null
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/DUnitEnv.java
@@ -0,0 +1,68 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+/**
+ * 
+ */
+package com.gemstone.gemfire.test.dunit;
+
+import java.io.File;
+import java.rmi.RemoteException;
+import java.util.Properties;
+
+/**
+ * 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.
+ * 
+ * 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.
+ *   
+ * @author dsmith
+ *
+ */
+public abstract class DUnitEnv {
+  
+  public static DUnitEnv instance = null;
+  
+  public static final DUnitEnv get() {
+    if (instance == null) {
+      try {
+        // for tests that are still being migrated to the open-source
+        // distributed unit test framework  we need to look for this
+        // old closed-source dunit environment
+        Class clazz = Class.forName("dunit.hydra.HydraDUnitEnv");
+        instance = (DUnitEnv)clazz.newInstance();
+      } catch (Exception e) {
+        throw new Error("Distributed unit test environment is not initialized");
+      }
+    }
+    return instance;
+  }
+  
+  public static void set(DUnitEnv dunitEnv) {
+    instance = dunitEnv;
+  }
+  
+  public abstract String getLocatorString();
+  
+  public abstract String getLocatorAddress();
+
+  public abstract int getLocatorPort();
+  
+  public abstract Properties getDistributedSystemProperties();
+
+  public abstract int getPid();
+
+  public abstract int getVMID();
+
+  public abstract BounceResult bounce(int pid) throws RemoteException;
+
+  public abstract File getWorkingDirectory(int pid);
+  
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/49b2913a/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/DebuggerSupport.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/DebuggerSupport.java b/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/DebuggerSupport.java
new file mode 100755
index 0000000..8d57483
--- /dev/null
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/DebuggerSupport.java
@@ -0,0 +1,20 @@
+package com.gemstone.gemfire.test.dunit;
+
+/**
+ * Extracted from DistributedTestCase. Enters infinite loop to allow debugger to attach.
+ */
+public class DebuggerSupport {
+
+  protected DebuggerSupport() {
+  }
+  
+  @SuppressWarnings("serial")
+  public static void attachDebugger(VM vm, final String msg) {
+    vm.invoke(new SerializableRunnable("Attach Debugger") {
+      public void run() {
+        com.gemstone.gemfire.internal.util.DebuggerSupport.
+        waitForJavaDebugger(msg);
+      } 
+    });
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/49b2913a/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/DistributedTestCase.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/DistributedTestCase.java b/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/DistributedTestCase.java
new file mode 100755
index 0000000..5eb3b0b
--- /dev/null
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/DistributedTestCase.java
@@ -0,0 +1,659 @@
+package com.gemstone.gemfire.test.dunit;
+
+import static com.gemstone.gemfire.test.dunit.Invoke.*;
+import static com.gemstone.gemfire.test.dunit.Wait.*;
+import static org.junit.Assert.*;
+
+import java.io.File;
+import java.net.UnknownHostException;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.logging.log4j.Logger;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.rules.TestName;
+
+import com.gemstone.gemfire.admin.internal.AdminDistributedSystemImpl;
+import com.gemstone.gemfire.cache.hdfs.internal.hoplog.HoplogConfig;
+import com.gemstone.gemfire.cache.query.QueryTestUtils;
+import com.gemstone.gemfire.cache.query.internal.QueryObserverHolder;
+import com.gemstone.gemfire.cache30.GlobalLockingDUnitTest;
+import com.gemstone.gemfire.cache30.MultiVMRegionTestCase;
+import com.gemstone.gemfire.cache30.RegionTestCase;
+import com.gemstone.gemfire.distributed.DistributedSystem;
+import com.gemstone.gemfire.distributed.internal.DistributionConfig;
+import com.gemstone.gemfire.distributed.internal.DistributionMessageObserver;
+import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
+import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem.CreationStackGenerator;
+import com.gemstone.gemfire.distributed.internal.membership.jgroup.MembershipManagerHelper;
+import com.gemstone.gemfire.internal.AvailablePort;
+import com.gemstone.gemfire.internal.InternalDataSerializer;
+import com.gemstone.gemfire.internal.InternalInstantiator;
+import com.gemstone.gemfire.internal.SocketCreator;
+import com.gemstone.gemfire.internal.admin.ClientStatsManager;
+import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
+import com.gemstone.gemfire.internal.cache.InitialImageOperation;
+import com.gemstone.gemfire.internal.cache.tier.InternalBridgeMembership;
+import com.gemstone.gemfire.internal.cache.tier.sockets.CacheServerTestUtil;
+import com.gemstone.gemfire.internal.cache.tier.sockets.ClientProxyMembershipID;
+import com.gemstone.gemfire.internal.cache.tier.sockets.DataSerializerPropogationDUnitTest;
+import com.gemstone.gemfire.internal.logging.InternalLogWriter;
+import com.gemstone.gemfire.internal.logging.LogService;
+import com.gemstone.gemfire.internal.logging.ManagerLogWriter;
+import com.gemstone.gemfire.internal.logging.log4j.LogWriterLogger;
+import com.gemstone.gemfire.management.internal.cli.LogWrapper;
+import com.gemstone.org.jgroups.Event;
+import com.gemstone.org.jgroups.JChannel;
+import com.gemstone.org.jgroups.stack.IpAddress;
+import com.gemstone.org.jgroups.stack.Protocol;
+import com.gemstone.org.jgroups.util.GemFireTracer;
+
+import com.gemstone.gemfire.test.dunit.standalone.DUnitLauncher;
+
+/**
+ * This class is the superclass of all distributed unit tests.
+ *
+ * @author David Whitlock
+ */
+@SuppressWarnings({ "deprecation", "serial", "rawtypes" })
+public abstract class DistributedTestCase implements java.io.Serializable {
+  private static final Logger logger = LogService.getLogger();
+  private static final LogWriterLogger oldLogger = LogWriterLogger.create(logger);
+
+  @Rule
+  public transient TestName testNameRule = new TestName();
+  
+  public static InternalDistributedSystem system;
+  private static Class lastSystemCreatedInTest;
+  private static Properties lastSystemProperties;
+  public static volatile String testName;
+  
+  public static final boolean logPerTest = Boolean.getBoolean("dunitLogPerTest");
+
+  /**
+   * Creates a new <code>DistributedTestCase</code> test.
+   */
+  public DistributedTestCase() {
+    DUnitLauncher.launchIfNeeded();
+  }
+
+  private static void setUpCreationStackGenerator() {
+    // the following is moved from InternalDistributedSystem to fix #51058
+    InternalDistributedSystem.TEST_CREATION_STACK_GENERATOR.set(
+    new CreationStackGenerator() {
+      @Override
+      public Throwable generateCreationStack(final DistributionConfig config) {
+        final StringBuilder sb = new StringBuilder();
+        final String[] validAttributeNames = config.getAttributeNames();
+        for (int i = 0; i < validAttributeNames.length; i++) {
+          final String attName = validAttributeNames[i];
+          final Object actualAtt = config.getAttributeObject(attName);
+          String actualAttStr = actualAtt.toString();
+          sb.append("  ");
+          sb.append(attName);
+          sb.append("=\"");
+          if (actualAtt.getClass().isArray()) {
+            actualAttStr = InternalDistributedSystem.arrayToString(actualAtt);
+          }
+          sb.append(actualAttStr);
+          sb.append("\"");
+          sb.append("\n");
+        }
+        return new Throwable("Creating distributed system with the following configuration:\n" + sb.toString());
+      }
+    });
+  }
+  
+  private static void tearDownCreationStackGenerator() {
+    InternalDistributedSystem.TEST_CREATION_STACK_GENERATOR.set(InternalDistributedSystem.DEFAULT_CREATION_STACK_GENERATOR);
+  }
+  
+  private Class getTestClass() {
+    Class clazz = getClass();
+    while (clazz.getDeclaringClass() != null) {
+      clazz = clazz.getDeclaringClass();
+    }
+    return clazz;
+  }
+  
+  /**
+   * This finds the log level configured for the test run.  It should be used
+   * when creating a new distributed system if you want to specify a log level.
+   * 
+   * @return the dunit log-level setting
+   */
+  public static String getDUnitLogLevel() { // TODO: delete
+    Properties p = DUnitEnv.get().getDistributedSystemProperties();
+    String result = p.getProperty(DistributionConfig.LOG_LEVEL_NAME);
+    if (result == null) {
+      result = ManagerLogWriter.levelToString(DistributionConfig.DEFAULT_LOG_LEVEL);
+    }
+    return result;
+  }
+
+  public final static Properties getAllDistributedSystemProperties(Properties props) { // TODO: delete
+    Properties p = DUnitEnv.get().getDistributedSystemProperties();
+    
+    // our tests do not expect auto-reconnect to be on by default
+    if (!p.contains(DistributionConfig.DISABLE_AUTO_RECONNECT_NAME)) {
+      p.put(DistributionConfig.DISABLE_AUTO_RECONNECT_NAME, "true");
+    }
+        
+    for (Iterator iter = props.entrySet().iterator();
+    iter.hasNext(); ) {
+      Map.Entry entry = (Map.Entry) iter.next();
+      String key = (String) entry.getKey();
+      Object value = entry.getValue();
+      p.put(key, value);
+    }
+    return p;
+  }
+
+  public void setSystem(Properties props, DistributedSystem ds) { // TODO: delete
+    system = (InternalDistributedSystem)ds;
+    lastSystemProperties = props;
+    lastSystemCreatedInTest = getTestClass();
+  }
+  
+  /**
+   * Returns this VM's connection to the distributed system.  If
+   * necessary, the connection will be lazily created using the given
+   * <code>Properties</code>.  Note that this method uses hydra's
+   * configuration to determine the location of log files, etc.
+   * Note: "final" was removed so that WANTestBase can override this method.
+   * This was part of the xd offheap merge.
+   *
+   * @see hydra.DistributedConnectionMgr#connect
+   * @since 3.0
+   */
+  public final InternalDistributedSystem getSystem(Properties props) {
+    // Setting the default disk store name is now done in setUp
+    if (system == null) {
+      system = InternalDistributedSystem.getAnyInstance();
+    }
+    if (system == null || !system.isConnected()) {
+      // Figure out our distributed system properties
+      Properties p = getAllDistributedSystemProperties(props);
+      lastSystemCreatedInTest = getTestClass();
+      if (logPerTest) {
+        String testMethod = getTestName();
+        String testName = lastSystemCreatedInTest.getName() + '-' + testMethod;
+        String oldLogFile = p.getProperty(DistributionConfig.LOG_FILE_NAME);
+        p.put(DistributionConfig.LOG_FILE_NAME, 
+            oldLogFile.replace("system.log", testName+".log"));
+        String oldStatFile = p.getProperty(DistributionConfig.STATISTIC_ARCHIVE_FILE_NAME);
+        p.put(DistributionConfig.STATISTIC_ARCHIVE_FILE_NAME, 
+            oldStatFile.replace("statArchive.gfs", testName+".gfs"));
+      }
+      system = (InternalDistributedSystem)DistributedSystem.connect(p);
+      lastSystemProperties = p;
+    } else {
+      boolean needNewSystem = false;
+      if(!getTestClass().equals(lastSystemCreatedInTest)) {
+        Properties newProps = getAllDistributedSystemProperties(props);
+        needNewSystem = !newProps.equals(lastSystemProperties);
+        if(needNewSystem) {
+          getLogWriter().info(
+              "Test class has changed and the new DS properties are not an exact match. "
+                  + "Forcing DS disconnect. Old props = "
+                  + lastSystemProperties + "new props=" + newProps);
+        }
+      } else {
+        Properties activeProps = system.getProperties();
+        for (Iterator iter = props.entrySet().iterator();
+        iter.hasNext(); ) {
+          Map.Entry entry = (Map.Entry) iter.next();
+          String key = (String) entry.getKey();
+          String value = (String) entry.getValue();
+          if (!value.equals(activeProps.getProperty(key))) {
+            needNewSystem = true;
+            getLogWriter().info("Forcing DS disconnect. For property " + key
+                                + " old value = " + activeProps.getProperty(key)
+                                + " new value = " + value);
+            break;
+          }
+        }
+      }
+      if(needNewSystem) {
+        // the current system does not meet our needs to disconnect and
+        // call recursively to get a new system.
+        getLogWriter().info("Disconnecting from current DS in order to make a new one");
+        disconnectFromDS();
+        getSystem(props);
+      }
+    }
+    return system;
+  }
+
+  /**
+   * 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().
+   */
+  public static boolean crashDistributedSystem(VM vm) { // TODO: move
+    return (Boolean)vm.invoke(new SerializableCallable("crash distributed system") {
+      public Object call() throws Exception {
+        DistributedSystem msys = InternalDistributedSystem.getAnyInstance();
+        crashDistributedSystem(msys);
+        return true;
+      }
+    });
+  }
+  
+  /**
+   * 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().
+   */
+  public static void crashDistributedSystem(final DistributedSystem msys) { // TODO: move
+    MembershipManagerHelper.inhibitForcedDisconnectLogging(true);
+    MembershipManagerHelper.playDead(msys);
+    JChannel c = MembershipManagerHelper.getJChannel(msys);
+    Protocol udp = c.getProtocolStack().findProtocol("UDP");
+    udp.stop();
+    udp.passUp(new Event(Event.EXIT, new RuntimeException("killing member's ds")));
+    try {
+      MembershipManagerHelper.getJChannel(msys).waitForClose();
+    }
+    catch (InterruptedException ie) {
+      Thread.currentThread().interrupt();
+      // attempt rest of work with interrupt bit set
+    }
+    MembershipManagerHelper.inhibitForcedDisconnectLogging(false);
+    WaitCriterion wc = new WaitCriterion() {
+      public boolean done() {
+        return !msys.isConnected();
+      }
+      public String description() {
+        return "waiting for distributed system to finish disconnecting: " + msys;
+      }
+    };
+//    try {
+      waitForCriterion(wc, 10000, 1000, true);
+//    } finally {
+//      dumpMyThreads(getLogWriter());
+//    }
+  }
+
+  private String getDefaultDiskStoreName() { // TODO: move
+    String vmid = System.getProperty("vmid");
+    return "DiskStore-"  + vmid + "-"+ getTestClass().getCanonicalName() + "." + getTestName();
+  }
+
+  /**
+   * Returns this VM's connection to the distributed system.  If
+   * necessary, the connection will be lazily created using the
+   * <code>Properties</code> returned by {@link
+   * #getDistributedSystemProperties}.
+   *
+   * @see #getSystem(Properties)
+   *
+   * @since 3.0
+   */
+  public final InternalDistributedSystem getSystem() {
+    return getSystem(this.getDistributedSystemProperties());
+  }
+
+  /**
+   * Returns a loner distributed system that isn't connected to other
+   * vms
+   * 
+   * @since 6.5
+   */
+  public final InternalDistributedSystem getLonerSystem() {
+    Properties props = this.getDistributedSystemProperties();
+    props.put(DistributionConfig.MCAST_PORT_NAME, "0");
+    props.put(DistributionConfig.LOCATORS_NAME, "");
+    return getSystem(props);
+  }
+  
+  /**
+   * Returns a loner distributed system in combination with enforceUniqueHost
+   * and redundancyZone properties.
+   * Added specifically to test scenario of defect #47181.
+   */
+  public final InternalDistributedSystem getLonerSystemWithEnforceUniqueHost() {
+    Properties props = this.getDistributedSystemProperties();
+    props.put(DistributionConfig.MCAST_PORT_NAME, "0");
+    props.put(DistributionConfig.LOCATORS_NAME, "");
+    props.put(DistributionConfig.ENFORCE_UNIQUE_HOST_NAME, "true");
+    props.put(DistributionConfig.REDUNDANCY_ZONE_NAME, "zone1");
+    return getSystem(props);
+  }
+
+  /**
+   * Returns an mcast distributed system that is connected to other
+   * vms using a random mcast port.
+   */
+  public final InternalDistributedSystem getMcastSystem() {
+    Properties props = this.getDistributedSystemProperties();
+    int port = AvailablePort.getRandomAvailablePort(AvailablePort.JGROUPS);
+    props.put(DistributionConfig.MCAST_PORT_NAME, ""+port);
+    props.put(DistributionConfig.MCAST_TTL_NAME, "0");
+    props.put(DistributionConfig.LOCATORS_NAME, "");
+    return getSystem(props);
+  }
+
+  /**
+   * Returns an mcast distributed system that is connected to other
+   * vms using the given mcast port.
+   */
+  public final InternalDistributedSystem getMcastSystem(int jgroupsPort) {
+    Properties props = this.getDistributedSystemProperties();
+    props.put(DistributionConfig.MCAST_PORT_NAME, ""+jgroupsPort);
+    props.put(DistributionConfig.MCAST_TTL_NAME, "0");
+    props.put(DistributionConfig.LOCATORS_NAME, "");
+    return getSystem(props);
+  }
+
+  /**
+   * Returns whether or this VM is connected to a {@link
+   * DistributedSystem}.
+   */
+  public final boolean isConnectedToDS() {
+    return system != null && system.isConnected();
+  }
+
+  /**
+   * Returns a <code>Properties</code> object used to configure a
+   * connection to a {@link
+   * com.gemstone.gemfire.distributed.DistributedSystem}.
+   * Unless overridden, this method will return an empty
+   * <code>Properties</code> object.
+   *
+   * @since 3.0
+   */
+  public Properties getDistributedSystemProperties() {
+    return new Properties();
+  }
+
+  /**
+   * Sets up the test (noop).
+   */
+  @Before
+  public final void setUpDistributedTestCase() throws Exception {
+    setUpCreationStackGenerator();
+    testName = getName();
+    System.setProperty(HoplogConfig.ALLOW_LOCAL_HDFS_PROP, "true");
+    
+    if (testName != null) {
+      GemFireCacheImpl.setDefaultDiskStoreName(getDefaultDiskStoreName());
+      String baseDefaultDiskStoreName = getTestClass().getCanonicalName() + "." + getTestName();
+      for (int h = 0; h < Host.getHostCount(); h++) {
+        Host host = Host.getHost(h);
+        for (int v = 0; v < host.getVMCount(); v++) {
+          VM vm = host.getVM(v);
+          String vmDefaultDiskStoreName = "DiskStore-" + h + "-" + v + "-" + baseDefaultDiskStoreName;
+          vm.invoke(DistributedTestCase.class, "perVMSetUp", new Object[] {testName, vmDefaultDiskStoreName});
+        }
+      }
+    }
+    System.out.println("\n\n[setup] START TEST " + getClass().getSimpleName()+"."+testName+"\n\n");
+  }
+
+  public static void perVMSetUp(String name, String defaultDiskStoreName) { // TODO: move
+    setTestName(name);
+    GemFireCacheImpl.setDefaultDiskStoreName(defaultDiskStoreName);
+    System.setProperty(HoplogConfig.ALLOW_LOCAL_HDFS_PROP, "true");    
+  }
+  
+  public static void setTestName(String name) {
+    testName = name;
+  }
+  
+  public static String getTestName() {
+    return testName;
+  }
+
+  /**
+   * For logPerTest to work, we have to disconnect from the DS, but all
+   * subclasses do not call super.tearDown(). To prevent this scenario
+   * this method has been declared final. Subclasses must now override
+   * {@link #tearDown2()} instead.
+   * @throws Exception
+   */
+  @After
+  public final void tearDownDistributedTestCase() throws Exception {
+    tearDownCreationStackGenerator();
+    tearDown2();
+    realTearDown();
+    tearDownAfter();
+  }
+
+  /**
+   * Tears down the test. This method is called by the final {@link #tearDown()} method and should be overridden to
+   * perform actual test cleanup and release resources used by the test.  The tasks executed by this method are
+   * performed before the DUnit test framework using Hydra cleans up the client VMs.
+   * <p/>
+   * @throws Exception if the tear down process and test cleanup fails.
+   * @see #tearDown
+   * @see #tearDownAfter()
+   */
+  // TODO rename this method to tearDownBefore and change the access modifier to protected!
+  public void tearDown2() throws Exception { // TODO: rename
+  }
+
+  protected void realTearDown() throws Exception {
+    if (logPerTest) {
+      disconnectFromDS();
+      invokeInEveryVM(DistributedTestCase.class, "disconnectFromDS");
+    }
+    cleanupAllVms();
+  }
+  
+  /**
+   * Tears down the test.  Performs additional tear down tasks after the DUnit tests framework using Hydra cleans up
+   * the client VMs.  This method is called by the final {@link #tearDown()} method and should be overridden to perform
+   * post tear down activities.
+   * <p/>
+   * @throws Exception if the test tear down process fails.
+   * @see #tearDown()
+   * @see #tearDown2()
+   */
+  protected void tearDownAfter() throws Exception {
+  }
+
+  public static void cleanupAllVms()
+  {
+    cleanupThisVM();
+    invokeInEveryVM(DistributedTestCase.class, "cleanupThisVM");
+    invokeInLocator(new SerializableRunnable() {
+      public void run() {
+        DistributionMessageObserver.setInstance(null);
+        unregisterInstantiatorsInThisVM();
+      }
+    });
+    DUnitLauncher.closeAndCheckForSuspects();
+  }
+
+
+  private static void cleanupThisVM() {
+    IpAddress.resolve_dns = true;
+    SocketCreator.resolve_dns = true;
+    InitialImageOperation.slowImageProcessing = 0;
+    DistributionMessageObserver.setInstance(null);
+    QueryTestUtils.setCache(null);
+    CacheServerTestUtil.clearCacheReference();
+    RegionTestCase.preSnapshotRegion = null;
+    GlobalLockingDUnitTest.region_testBug32356 = null;
+    LogWrapper.close();
+    ClientProxyMembershipID.system = null;
+    MultiVMRegionTestCase.CCRegion = null;
+    InternalBridgeMembership.unregisterAllListeners();
+    ClientStatsManager.cleanupForTests();
+    unregisterInstantiatorsInThisVM();
+    GemFireTracer.DEBUG = Boolean.getBoolean("DistributionManager.DEBUG_JAVAGROUPS");
+    Protocol.trace = GemFireTracer.DEBUG;
+    DistributionMessageObserver.setInstance(null);
+    QueryObserverHolder.reset();
+    if (InternalDistributedSystem.systemAttemptingReconnect != null) {
+      InternalDistributedSystem.systemAttemptingReconnect.stopReconnecting();
+    }
+    ExpectedExceptionString ex;
+    while((ex = ExpectedExceptionString.poll()) != null) {
+      ex.remove();
+    }
+  }
+  
+  public static void unregisterAllDataSerializersFromAllVms() // TODO: move
+  {
+    unregisterDataSerializerInThisVM();
+    invokeInEveryVM(new SerializableRunnable() {
+      public void run() {
+        unregisterDataSerializerInThisVM();
+      }
+    });
+    invokeInLocator(new SerializableRunnable() {
+      public void run() {
+        unregisterDataSerializerInThisVM();
+      }
+    });
+  }
+
+  public static void unregisterInstantiatorsInThisVM() { // TODO: move
+    // unregister all the instantiators
+    InternalInstantiator.reinitialize();
+    assertEquals(0, InternalInstantiator.getInstantiators().length);
+  }
+  
+  public static void unregisterDataSerializerInThisVM() // TODO: move
+  {
+    DataSerializerPropogationDUnitTest.successfullyLoadedTestDataSerializer = false;
+    // unregister all the Dataserializers
+    InternalDataSerializer.reinitialize();
+    // ensure that all are unregistered
+    assertEquals(0, InternalDataSerializer.getSerializers().length);
+  }
+
+
+  protected static void disconnectAllFromDS() {
+    disconnectFromDS();
+    invokeInEveryVM(DistributedTestCase.class,
+                    "disconnectFromDS");
+  }
+
+  /**
+   * Disconnects this VM from the distributed system
+   */
+  public static void disconnectFromDS() {
+    testName = null;
+    GemFireCacheImpl.testCacheXml = null;
+    if (system != null) {
+      system.disconnect();
+      system = null;
+    }
+    
+    for (;;) {
+      DistributedSystem ds = InternalDistributedSystem.getConnectedInstance();
+      if (ds == null) {
+        break;
+      }
+      try {
+        ds.disconnect();
+      }
+      catch (Exception e) {
+        // ignore
+      }
+    }
+    
+    {
+      AdminDistributedSystemImpl ads = 
+          AdminDistributedSystemImpl.getConnectedInstance();
+      if (ads != null) {// && ads.isConnected()) {
+        ads.disconnect();
+      }
+    }
+  }
+
+  /**
+   * Strip the package off and gives just the class name.
+   * Needed because of Windows file name limits.
+   */
+  private String getShortClassName() {
+    String result = this.getClass().getName();
+    int idx = result.lastIndexOf('.');
+    if (idx != -1) {
+      result = result.substring(idx+1);
+    }
+    return result;
+  }
+  
+  /** get the host name to use for a server cache in client/server dunit
+   * testing
+   * @param host
+   * @return the host name
+   */
+  public static String getServerHostName(Host host) { // TODO: move
+    return System.getProperty("gemfire.server-bind-address") != null?
+        System.getProperty("gemfire.server-bind-address")
+        : host.getHostName();
+  }
+
+  /** get the IP literal name for the current host, use this instead of  
+   * "localhost" to avoid IPv6 name resolution bugs in the JDK/machine config.
+   * @return an ip literal, this method honors java.net.preferIPvAddresses
+   */
+  public static String getIPLiteral() { // TODO: move
+    try {
+      return SocketCreator.getLocalHost().getHostAddress();
+    } catch (UnknownHostException e) {
+      throw new Error("problem determining host IP address", e);
+    }
+  }
+ 
+ 
+  /**
+   * Get the port that the standard dunit locator is listening on.
+   * @return
+   */
+  public static int getDUnitLocatorPort() { // TODO: move
+    return DUnitEnv.get().getLocatorPort();
+  }
+    
+  public String getName() {
+    return this.testNameRule.getMethodName();
+  }
+  
+  /**
+   * Returns a unique name for this test method.  It is based on the
+   * name of the class as well as the name of the method.
+   */
+  public String getUniqueName() {
+    return getClass().getSimpleName() + "_" + getName();
+  }
+
+  /**
+   * Returns a <code>LogWriter</code> for logging information
+   * @deprecated Use a static logger from the log4j2 LogService.getLogger instead.
+   */
+  @Deprecated
+  public static InternalLogWriter getLogWriter() { // TODO: delete
+    return oldLogger;
+  }
+
+  /** 
+   * Delete locator state files.  Use this after getting a random port
+   * to ensure that an old locator state file isn't picked up by the
+   * new locator you're starting.
+   * 
+   * @param ports
+   */
+  public static void deleteLocatorStateFile(final int... ports) { // TODO: move
+    for (int i=0; i<ports.length; i++) {
+      final File stateFile = new File("locator"+ports[i]+"state.dat");
+      if (stateFile.exists()) {
+        stateFile.delete();
+      }
+    }
+  }
+  
+}


Mime
View raw message