[jboss-cvs] JBossAS SVN: r58933 - branches/Branch_4_2/testsuite/src/main/org/jboss/test/cluster/test
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Fri Dec 8 13:25:49 EST 2006
Author: jerrygauth
Date: 2006-12-08 13:25:48 -0500 (Fri, 08 Dec 2006)
New Revision: 58933
Modified:
branches/Branch_4_2/testsuite/src/main/org/jboss/test/cluster/test/DRMTestCase.java
Log:
JBAS-2560, JBAS-2470 - use GossipRouter to simulate merges
Modified: branches/Branch_4_2/testsuite/src/main/org/jboss/test/cluster/test/DRMTestCase.java
===================================================================
--- branches/Branch_4_2/testsuite/src/main/org/jboss/test/cluster/test/DRMTestCase.java 2006-12-08 16:29:56 UTC (rev 58932)
+++ branches/Branch_4_2/testsuite/src/main/org/jboss/test/cluster/test/DRMTestCase.java 2006-12-08 18:25:48 UTC (rev 58933)
@@ -26,19 +26,20 @@
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
+import java.util.List;
import java.util.Vector;
-import java.util.List;
-import java.util.HashSet;
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.MBeanServerInvocationHandler;
+import javax.management.Notification;
import javax.management.ObjectName;
-import javax.management.Notification;
import junit.framework.Test;
+import org.apache.log4j.Logger;
import org.jboss.test.JBossClusteredTestCase;
import org.jboss.test.cluster.drm.IReplicants;
import org.jboss.test.cluster.drm.MockHAPartition;
@@ -46,11 +47,14 @@
import org.jboss.ha.framework.interfaces.DistributedReplicantManager;
import org.jboss.ha.framework.interfaces.DistributedReplicantManager.ReplicantListener;
import org.jboss.ha.framework.server.DistributedReplicantManagerImpl;
+import org.jboss.ha.framework.server.HAPartitionImpl;
import org.jboss.jmx.adaptor.rmi.RMIAdaptor;
import org.jboss.jmx.adaptor.rmi.RMIAdaptorExt;
import org.jboss.jmx.adaptor.rmi.RMINotificationListener;
+import org.jgroups.Channel;
+import org.jgroups.JChannel;
+import org.jgroups.stack.GossipRouter;
import org.jgroups.stack.IpAddress;
-import org.apache.log4j.Logger;
import EDU.oswego.cs.dl.util.concurrent.Semaphore;
@@ -62,6 +66,21 @@
*/
public class DRMTestCase extends JBossClusteredTestCase
{
+ private static final String SERVICEA = "serviceA";
+ private static final String SERVICEB = "serviceB";
+
+ protected static final String CHANNEL_PROPS =
+ "TUNNEL(router_port=4747;router_host=localhost;loopback=true):" +
+ "PING(timeout=1000;num_initial_members=2;gossip_host=localhost;gossip_port=4747):" +
+ "MERGE2(min_interval=3000;max_interval=5000):" +
+ "FD(timeout=1000;max_tries=2;shun=false):" +
+ "pbcast.NAKACK(gc_lag=50;retransmit_timeout=600,1200,2400,4800):" +
+ "UNICAST(timeout=600,1200,2400):" +
+ "pbcast.STABLE(desired_avg_gossip=20000):" +
+ "pbcast.GMS(join_timeout=5000;join_retry_timeout=2000;" +
+ "print_local_addr=false;shun=false):" +
+ "pbcast.STATE_TRANSFER";
+
static class TestListener extends UnicastRemoteObject
implements RMINotificationListener
{
@@ -583,7 +602,9 @@
/**
* Tests the functionality of isMasterReplica(), also testing merge
- * handling.
+ * handling. This test creates and manipulates two HAPartition instances in memory
+ * so it doesn't require a server deployment. The partition instances communicate via
+ * a GossipRouter. The router is stopped and restarted to simulate a merge condition.
*
* TODO move this test out of the testsuite and into the cluster module
* itself, since it doesn't rely on the container.
@@ -592,116 +613,148 @@
*/
public void testIsMasterReplica() throws Exception
{
+ MBeanServer mbeanServer1 = null;
+ MBeanServer mbeanServer2 = null;
+ JChannel channel1 = null;
+ JChannel channel2 = null;
+ GossipRouter router = null;
log.debug("+++ testIsMasterReplica()");
-
- MBeanServer mbeanServer =
- MBeanServerFactory.createMBeanServer("mockPartition");
- try {
- ClusterNode localAddress = new ClusterNode(new IpAddress("127.0.0.1", 12345));
- MockHAPartition partition = new MockHAPartition(localAddress);
-
- DistributedReplicantManagerImpl drm =
- new DistributedReplicantManagerImpl(partition, mbeanServer);
- drm.init();
+ try
+ {
+ String partitionName = "DRMTestCasePartition";
+ log.info("DRMTestCase.testIsMasterReplica() - starting GossipRouter");
+ router = new GossipRouter(4747, "localhost");
+ router.start();
- // Create a fake view for the MockHAPartition
+ mbeanServer1 = MBeanServerFactory.createMBeanServer("DRMTestCaseServer1");
+ channel1 = createTestChannel(CHANNEL_PROPS);
+ HAPartitionImpl partition1 = createTestPartition(partitionName, channel1, mbeanServer1, "DRMTestCaseNode1");
+
+ mbeanServer2 = MBeanServerFactory.createMBeanServer("DRMTestCaseServer2");
+ channel2 = createTestChannel(CHANNEL_PROPS);
+ HAPartitionImpl partition2 = createTestPartition(partitionName, channel2, mbeanServer2, "DRMTestCaseNode2");
+
+ DistributedReplicantManager drm1 = partition1.getDistributedReplicantManager();
+ DistributedReplicantManager drm2 = partition2.getDistributedReplicantManager();
- Vector remoteAddresses = new Vector();
- for (int i = 1; i < 5; i++)
- remoteAddresses.add(new ClusterNode(new IpAddress("127.0.0.1", 12340 + i)));
+ // confirm that each partition contains two nodes
+ assertEquals("Partition1 should contain two nodes; ", 2, partition1.getCurrentView().size());
+ assertEquals("Partition2 should contain two nodes; ", 2, partition2.getCurrentView().size());
- Vector allNodes = new Vector(remoteAddresses);
- allNodes.add(localAddress);
- partition.setCurrentViewClusterNodes(allNodes);
+ drm1.add(SERVICEA, "valueA1");
+ drm2.add(SERVICEA, "valueA2");
+ drm2.add(SERVICEB, "valueB2");
+
+ // test that only one node is the master replica for serviceA
+ assertTrue("ServiceA must have a master replica",
+ drm1.isMasterReplica(SERVICEA) || drm2.isMasterReplica(SERVICEA));
+ assertTrue("ServiceA must have a single master replica",
+ drm1.isMasterReplica(SERVICEA) != drm2.isMasterReplica(SERVICEA));
+
+ // ServiceB should only be a master replica on partition2
+ assertFalse("ServiceB should not be a master replica on partition1",
+ drm1.isMasterReplica(SERVICEB));
+ assertTrue("ServiceB must have a master replica on partition2",
+ drm2.isMasterReplica(SERVICEB));
- // Pass fake state to DRMImpl
-
- HashMap replicants = new HashMap();
- ArrayList remoteResponses = new ArrayList();
- for (int i = 0; i < remoteAddresses.size(); i++)
- {
- ClusterNode node = (ClusterNode) remoteAddresses.elementAt(i);
- Integer replicant = new Integer(i + 1);
- replicants.put(node.getName(), replicant);
- HashMap localReplicant = new HashMap();
- localReplicant.put("Mock", replicant);
- remoteResponses.add(new Object[] {node.getName(), localReplicant});
- }
- HashMap services = new HashMap();
- services.put("Mock", replicants);
+ // confirm that each partition contains correct DRM replicants for services A and B
+ assertEquals("Partition1 should contain two DRM replicants for serviceA; ",
+ 2, drm1.lookupReplicants(SERVICEA).size());
+ assertEquals("Partition2 should contain two DRM replicants for serviceA; ",
+ 2, drm2.lookupReplicants(SERVICEA).size());
+ assertEquals("Partition1 should contain one DRM replicant for serviceB; ",
+ 1, drm1.lookupReplicants(SERVICEB).size());
+ assertEquals("Partition2 should contain one DRM replicant for serviceB; ",
+ 1, drm2.lookupReplicants(SERVICEB).size());
+
+ // simulate a split of the partition
+ router.stop();
+ sleepThread(10000);
- int hash = 0;
- for (int i = 1; i < 5; i++)
- hash += (new Integer(i)).hashCode();
+ // confirm that each partition contains one node
+ assertEquals("Partition1 should contain one node after split; ",
+ 1, partition1.getCurrentView().size());
+ assertEquals("Partition2 should contain one node after split; ",
+ 1, partition2.getCurrentView().size());
+
+ // confirm that each node is a master replica for serviceA after the split
+ assertTrue("ServiceA should be a master replica on partition1 after split",
+ drm1.isMasterReplica(SERVICEA));
+ assertTrue("ServiceA should be a master replica on partition2 after split",
+ drm2.isMasterReplica(SERVICEA));
- HashMap intraviewIds = new HashMap();
- intraviewIds.put("Mock", new Integer(hash));
-
- partition.setRemoteReplicants(remoteResponses);
+ // ServiceB should still only be a master replica on partition2 after split
+ assertFalse("ServiceB should not be a master replica on partition1 after split",
+ drm1.isMasterReplica(SERVICEB));
+ assertTrue("ServiceB must have a master replica on partition2 after split",
+ drm2.isMasterReplica(SERVICEB));
- drm.setCurrentState(new Object[] {services, intraviewIds });
+ // Remove ServiceA replicant from partition1
+ drm1.remove(SERVICEA);
- drm.start();
+ // test that this node is not the master replica
+ assertFalse("partition1 is not master replica after dropping ServiceA replicant",
+ drm1.isMasterReplica(SERVICEA));
- // add a local replicant
+ //Restore the local replicant
+ drm1.add(SERVICEA, "valueA1a");
- drm.add("Mock", new Integer(5));
-
- // test that this node is not the master replica
-
- assertFalse("Local node is not master after startup",
- drm.isMasterReplica("Mock"));
-
- // simulate a split where this node is the coord
-
- Vector localOnly = new Vector();
- localOnly.add(localAddress);
-
- partition.setCurrentViewClusterNodes(localOnly);
- partition.setRemoteReplicants(new ArrayList());
-
- drm.membershipChanged(remoteAddresses, new Vector(), localOnly);
-
- // test that this node is the master replica
-
- assertTrue("Local node is master after split", drm.isMasterReplica("Mock"));
-
- // Remove our local replicant
-
- drm.remove("Mock");
-
- // test that this node is not the master replica
-
- assertFalse("Local node is not master after dropping replicant",
- drm.isMasterReplica("Mock"));
-
- // Restore the local replicant
-
- drm.add("Mock", new Integer(5));
-
// simulate a merge
+ router.start();
+ // it seems to take more than 10 seconds for the merge to take effect
+ sleepThread(15000);
- Vector mergeGroups = new Vector();
- mergeGroups.add(remoteAddresses);
- mergeGroups.add(localOnly);
+ // confirm that each partition contains two nodes again
+ assertEquals("Partition1 should contain two nodes after merge; ",
+ 2, partition1.getCurrentView().size());
+ assertEquals("Partition2 should contain two nodes after merge; ",
+ 2, partition2.getCurrentView().size());
- partition.setCurrentViewClusterNodes(allNodes);
- partition.setRemoteReplicants(remoteResponses);
+ // test that only one node is the master replica for serviceA after merge
+ assertTrue("ServiceA must have a master replica after merge",
+ drm1.isMasterReplica(SERVICEA) || drm2.isMasterReplica(SERVICEA));
+ assertTrue("ServiceA must have a single master replica after merge",
+ drm1.isMasterReplica(SERVICEA) != drm2.isMasterReplica(SERVICEA));
+
+ // ServiceB should only be a master replica on partition2 after merge
+ assertFalse("ServiceB should not be a master replica on partition1 after merge",
+ drm1.isMasterReplica(SERVICEB));
+ assertTrue("ServiceB must have a master replica on partition2 after merge",
+ drm2.isMasterReplica(SERVICEB));
- drm.membershipChangedDuringMerge(new Vector(), remoteAddresses,
- allNodes, mergeGroups);
+ // confirm that each partition contains correct DRM replicants for services A and B after merge
+ assertEquals("Partition1 should contain two DRM replicants for serviceA after merge; ",
+ 2, drm1.lookupReplicants(SERVICEA).size());
+ assertEquals("Partition2 should contain two DRM replicants for serviceA after merge; ",
+ 2, drm2.lookupReplicants(SERVICEA).size());
+ assertEquals("Partition1 should contain one DRM replicant for serviceB after merge; ",
+ 1, drm1.lookupReplicants(SERVICEB).size());
+ assertEquals("Partition2 should contain one DRM replicant for serviceB after merge; ",
+ 1, drm2.lookupReplicants(SERVICEB).size());
- // Merge processing is done asynchronously, so pause a bit
- sleepThread(100);
-
- // test that this node is not the master replica
-
- assertFalse("Local node is not master after merge",
- drm.isMasterReplica("Mock"));
+ partition1.closePartition();
+ partition2.closePartition();
}
- finally {
- MBeanServerFactory.releaseMBeanServer(mbeanServer);
+ finally
+ {
+ log.info("DRMTestCase.testIsMasterReplica() - cleaning up resources");
+ if (mbeanServer1 != null)
+ MBeanServerFactory.releaseMBeanServer(mbeanServer1);
+ if (mbeanServer2 != null)
+ MBeanServerFactory.releaseMBeanServer(mbeanServer2);
+ if (channel1 != null)
+ {
+ channel1.disconnect();
+ channel1.close();
+ }
+ if (channel2 != null)
+ {
+ channel2.disconnect();
+ channel2.close();
+ }
+ if (router != null)
+ router.stop();
}
}
@@ -1214,6 +1267,31 @@
else
return new ArrayList(toMask);
}
+
+ private JChannel createTestChannel(String props) throws Exception
+ {
+ JChannel channel = new JChannel(props);
+ channel.setOpt(Channel.AUTO_RECONNECT, Boolean.TRUE);
+ channel.setOpt(Channel.AUTO_GETSTATE, Boolean.TRUE);
+ return channel;
+ }
+
+ private HAPartitionImpl createTestPartition(String partitionName, JChannel channel,
+ MBeanServer server, String nodeName) throws Exception
+ {
+ // initialize HAPartition replicating logic from org.jboss.ha.framework.server.ClusterPartition
+ HAPartitionImpl partition = new HAPartitionImpl(partitionName, channel, false, server);
+ // suppress JNDI binding else second instance will fail with NameAlreadyBound exception
+ partition.setBindIntoJndi(false);
+ partition.init();
+ HashMap staticNodeName = new java.util.HashMap();
+ staticNodeName.put("additional_data", nodeName.getBytes());
+ channel.down(new org.jgroups.Event(org.jgroups.Event.CONFIG, staticNodeName));
+ channel.getProtocolStack().flushEvents();
+ channel.connect(partitionName);
+ partition.startPartition();
+ return partition;
+ }
private static void sleepThread(long millis)
{
More information about the jboss-cvs-commits
mailing list