[jboss-cvs] JBossAS SVN: r64237 - in trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg: test and 1 other directory.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Mon Jul 23 23:27:28 EDT 2007
Author: bstansberry at jboss.com
Date: 2007-07-23 23:27:28 -0400 (Mon, 23 Jul 2007)
New Revision: 64237
Added:
trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/
trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/DRMTestCase.java
trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/FamilyClusterInfoUnitTestCase.java
trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/HAInvokerUnitTestCase.java
trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/HAServiceMBeanSupportUnitTestCase.java
trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/HASingletonControllerUnitTestCase.java
trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/HASingletonElectionPolicyTestCase.java
trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/HASingletonSupportUnitTestCase.java
trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/PartitionRestartUnitTestCase.java
trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/RPCTestCase.java
Log:
[JBAS-4552] Move cluster tests into cluster package
[JBAS-4553] Reorg cluster tests to prevent unnecessary repetition
Added: trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/DRMTestCase.java
===================================================================
--- trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/DRMTestCase.java (rev 0)
+++ trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/DRMTestCase.java 2007-07-24 03:27:28 UTC (rev 64237)
@@ -0,0 +1,1333 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.test.cluster.defaultcfg.test;
+
+import java.rmi.RemoteException;
+import java.rmi.server.UnicastRemoteObject;
+import java.security.SecureRandom;
+import java.util.ArrayList;
+import java.util.Iterator;
+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.ObjectName;
+import javax.management.Notification;
+
+import junit.framework.Test;
+
+import org.jboss.cache.config.Configuration;
+import org.jboss.cache.config.RuntimeConfig;
+import org.jboss.cache.jmx.CacheJmxWrapper;
+import org.jboss.ha.framework.interfaces.ClusterNode;
+import org.jboss.ha.framework.interfaces.DistributedReplicantManager;
+import org.jboss.ha.framework.interfaces.DistributedReplicantManager.ReplicantListener;
+import org.jboss.ha.framework.server.ClusterPartition;
+import org.jboss.ha.framework.server.ClusterPartitionConfig;
+import org.jboss.ha.framework.server.DistributedReplicantManagerImpl;
+import org.jboss.ha.framework.server.DistributedStateImpl;
+import org.jboss.ha.framework.server.JChannelFactory;
+import org.jboss.jmx.adaptor.rmi.RMIAdaptor;
+import org.jboss.jmx.adaptor.rmi.RMIAdaptorExt;
+import org.jboss.jmx.adaptor.rmi.RMINotificationListener;
+import org.jboss.logging.Logger;
+import org.jboss.test.JBossClusteredTestCase;
+import org.jboss.test.cluster.hapartition.drm.IReplicants;
+import org.jboss.test.cluster.testutil.MockHAPartition;
+import org.jgroups.stack.GossipRouter;
+import org.jgroups.stack.IpAddress;
+
+
+import EDU.oswego.cs.dl.util.concurrent.Semaphore;
+
+/** Tests of the DistributedReplicantManagerImpl
+ *
+ * @author Scott.Stark at jboss.org
+ * @author Brian.Stansberry at jboss.com
+ * @version $Revision$
+ */
+public class DRMTestCase extends JBossClusteredTestCase
+{
+ private static final String SERVICEA = "serviceA";
+ private static final String SERVICEB = "serviceB";
+
+ static class TestListener extends UnicastRemoteObject
+ implements RMINotificationListener
+ {
+ private static final long serialVersionUID = 1;
+ private Logger log;
+
+ public TestListener(Logger log) throws RemoteException
+ {
+ this.log = log;
+ }
+ public void handleNotification(Notification notification, Object handback)
+ throws RemoteException
+ {
+ log.info("handleNotification, "+notification);
+ }
+ }
+
+ /**
+ * Thread that will first register a DRM ReplicantLister that synchronizes
+ * on the test class' lock object, and then calls DRM add or remove,
+ * causing the thread to block if the lock object's monitor is held.
+ */
+ static class BlockingListenerThread extends Thread
+ implements DistributedReplicantManager.ReplicantListener
+ {
+ private DistributedReplicantManagerImpl drm;
+ private String nodeName;
+ private boolean add;
+ private boolean blocking;
+ private Exception ex;
+
+ BlockingListenerThread(DistributedReplicantManagerImpl drm,
+ boolean add,
+ String nodeName)
+ {
+ this.drm = drm;
+ this.add =add;
+ this.nodeName = nodeName;
+ drm.registerListener("TEST", this);
+ }
+
+ public void replicantsChanged(String key, List newReplicants, int newReplicantsViewId)
+ {
+ blocking = true;
+ synchronized(lock)
+ {
+ blocking = false;
+ }
+ }
+
+ public void run()
+ {
+ try
+ {
+ if (add)
+ {
+ if (nodeName == null)
+ drm.add("TEST", "local-replicant");
+ else
+ drm._add("TEST", nodeName, "remote-replicant");
+ }
+ else
+ {
+ if (nodeName == null)
+ drm.remove("TEST");
+ else
+ drm._remove("TEST", nodeName);
+ }
+ }
+ catch (Exception e)
+ {
+ ex = e;
+ }
+ }
+
+ public boolean isBlocking()
+ {
+ return blocking;
+ }
+
+ public Exception getException()
+ {
+ return ex;
+ }
+
+ }
+
+ /**
+ * Thread that registers and then unregisters a DRM ReplicantListener.
+ */
+ static class RegistrationThread extends Thread
+ {
+ private DistributedReplicantManager drm;
+ private boolean registered = false;
+ private boolean unregistered = true;
+
+ RegistrationThread(DistributedReplicantManager drm)
+ {
+ this.drm = drm;
+ }
+
+ public void run()
+ {
+ NullListener listener = new NullListener();
+ drm.registerListener("DEADLOCK", listener);
+ registered = true;
+ drm.unregisterListener("DEADLOCK", listener);
+ unregistered = true;
+ }
+
+ public boolean isRegistered()
+ {
+ return registered;
+ }
+
+ public boolean isUnregistered()
+ {
+ return unregistered;
+ }
+
+ }
+
+ /**
+ * A DRM ReplicantListener that does nothing.
+ */
+ static class NullListener
+ implements DistributedReplicantManager.ReplicantListener
+ {
+ public void replicantsChanged(String key, List newReplicants,
+ int newReplicantsViewId)
+ {
+ // no-op
+ }
+ }
+
+ /**
+ * DRM ReplicantListener that mimics the HASingletonDeployer service
+ * by deploying/undeploying a service if it's notified that by that DRM
+ * that it is the master replica for its key.
+ */
+ static class MockHASingletonDeployer
+ implements DistributedReplicantManager.ReplicantListener
+ {
+ DistributedReplicantManager drm;
+ MockDeployer deployer;
+ String key;
+ boolean master = false;
+ NullListener deploymentListener = new NullListener();
+ Exception ex;
+ Logger log;
+ Object mutex = new Object();
+
+ MockHASingletonDeployer(MockDeployer deployer, String key, Logger log)
+ {
+ this.drm = deployer.getDRM();
+ this.deployer = deployer;
+ this.key = key;
+ this.log = log;
+ }
+
+ public void replicantsChanged(String key,
+ List newReplicants,
+ int newReplicantsViewId)
+ {
+ if (this.key.equals(key))
+ {
+ synchronized(mutex)
+ {
+ boolean nowMaster = drm.isMasterReplica(key);
+
+ try
+ {
+ if (!master && nowMaster) {
+ log.debug(Thread.currentThread().getName() +
+ " Deploying " + key);
+ deployer.deploy(key + "A", key, deploymentListener);
+ }
+ else if (master && !nowMaster) {
+ log.debug(Thread.currentThread().getName() +
+ " undeploying " + key);
+ deployer.undeploy(key + "A", deploymentListener);
+ }
+ else
+ {
+ log.debug(Thread.currentThread().getName() +
+ " -- no status change in " + key +
+ " -- master = " + master);
+ }
+ master = nowMaster;
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ if (ex == null)
+ ex = e;
+ }
+ }
+ }
+ }
+
+ public Exception getException()
+ {
+ return ex;
+ }
+
+ }
+
+ /**
+ * Thread the repeatedly deploys and undeploys a MockHASingletonDeployer.
+ */
+ static class DeployerThread extends Thread
+ {
+ Semaphore semaphore;
+ MockDeployer deployer;
+ DistributedReplicantManager.ReplicantListener listener;
+ String key;
+ Exception ex;
+ int count = -1;
+ Logger log;
+
+ DeployerThread(MockDeployer deployer,
+ String key,
+ DistributedReplicantManager.ReplicantListener listener,
+ Semaphore semaphore,
+ Logger log)
+ {
+ super("Deployer " + key);
+ this.deployer = deployer;
+ this.listener = listener;
+ this.key = key;
+ this.semaphore = semaphore;
+ this.log = log;
+ }
+
+ public void run()
+ {
+ boolean acquired = false;
+ try
+ {
+ acquired = semaphore.attempt(60000);
+ if (!acquired)
+ throw new Exception("Cannot acquire semaphore");
+ SecureRandom random = new SecureRandom();
+ for (count = 0; count < LOOP_COUNT; count++)
+ {
+ deployer.deploy(key, "JGroups", listener);
+
+ sleepThread(random.nextInt(50));
+ deployer.undeploy(key, listener);
+ }
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ ex = e;
+ }
+ finally
+ {
+ if (acquired)
+ semaphore.release();
+ }
+ }
+
+ public Exception getException()
+ {
+ return ex;
+ }
+
+ public int getCount()
+ {
+ return count;
+ }
+ }
+
+ /**
+ * Thread that mimics the JGroups up-handler thread that calls into the DRM.
+ * Repeatedly and randomly calls adds or removes a replicant for a set
+ * of keys.
+ */
+ static class JGroupsThread extends Thread
+ {
+ Semaphore semaphore;
+ DistributedReplicantManagerImpl drm;
+ String[] keys;
+ String nodeName;
+ Exception ex;
+ int count = -1;
+ int weightFactor;
+
+ JGroupsThread(DistributedReplicantManagerImpl drm,
+ String[] keys,
+ String nodeName,
+ Semaphore semaphore)
+ {
+ super("JGroups");
+ this.drm = drm;
+ this.keys = keys;
+ this.semaphore = semaphore;
+ this.nodeName = nodeName;
+ this.weightFactor = (int) 2.5 * keys.length;
+ }
+
+ public void run()
+ {
+ boolean acquired = false;
+ try
+ {
+ acquired = semaphore.attempt(60000);
+ if (!acquired)
+ throw new Exception("Cannot acquire semaphore");
+ boolean[] added = new boolean[keys.length];
+ SecureRandom random = new SecureRandom();
+
+ for (count = 0; count < weightFactor * LOOP_COUNT; count++)
+ {
+ int pos = random.nextInt(keys.length);
+ if (added[pos])
+ {
+ drm._remove(keys[pos], nodeName);
+ added[pos] = false;
+ }
+ else
+ {
+ drm._add(keys[pos], nodeName, "");
+ added[pos] = true;
+ }
+ sleepThread(random.nextInt(30));
+ }
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ ex = e;
+ }
+ finally
+ {
+ if (acquired)
+ semaphore.release();
+ }
+ }
+
+ public Exception getException()
+ {
+ return ex;
+ }
+
+ public int getCount()
+ {
+ return (count / weightFactor);
+ }
+
+ }
+
+ /**
+ * Mocks the deployer of a service that registers/unregisters DRM listeners
+ * and replicants. Only allows a single thread of execution, a la the
+ * org.jboss.system.ServiceController.
+ */
+ static class MockDeployer
+ {
+ DistributedReplicantManager drm;
+
+ MockDeployer(DistributedReplicantManager drm)
+ {
+ this.drm = drm;
+ }
+
+ void deploy(String key, String replicant,
+ DistributedReplicantManager.ReplicantListener listener)
+ throws Exception
+ {
+ synchronized(this)
+ {
+ drm.registerListener(key, listener);
+ drm.add(key, replicant);
+ sleepThread(10);
+ }
+ }
+
+ void undeploy(String key,
+ DistributedReplicantManager.ReplicantListener listener)
+ throws Exception
+ {
+ synchronized(this)
+ {
+ drm.remove(key);
+ drm.unregisterListener(key, listener);
+ sleepThread(10);
+ }
+ }
+
+ DistributedReplicantManager getDRM()
+ {
+ return drm;
+ }
+ }
+
+ /** ReplicantListener that caches the list of replicants */
+ static class CachingListener implements ReplicantListener
+ {
+ List replicants = null;
+ boolean clean = true;
+
+ public void replicantsChanged(String key, List newReplicants,
+ int newReplicantsViewId)
+ {
+ this.replicants = newReplicants;
+ if (clean && newReplicants != null)
+ {
+ int last = Integer.MIN_VALUE;
+ for (Iterator iter = newReplicants.iterator(); iter.hasNext(); )
+ {
+ int cur = ((Integer) iter.next()).intValue();
+ if (last >= cur)
+ {
+ clean = false;
+ break;
+ }
+
+ last = cur;
+ }
+ }
+ }
+
+ }
+
+ private static Object lock = new Object();
+ private static int LOOP_COUNT = 30;
+
+ public static Test suite() throws Exception
+ {
+ Test t1 = getDeploySetup(DRMTestCase.class, "drm-tests.sar");
+ return t1;
+ }
+
+ public DRMTestCase(String name)
+ {
+ super(name);
+ }
+
+ public void testStateReplication()
+ throws Exception
+ {
+ log.debug("+++ testStateReplication");
+ log.info("java.rmi.server.hostname="+System.getProperty("java.rmi.server.hostname"));
+ RMIAdaptor[] adaptors = getAdaptors();
+ String[] servers = super.getServers();
+ RMIAdaptorExt server0 = (RMIAdaptorExt) adaptors[0];
+ log.info("server0: "+server0);
+ ObjectName clusterService = new ObjectName("jboss:service=DefaultPartition");
+ Vector view0 = (Vector) server0.getAttribute(clusterService, "CurrentView");
+ log.info("server0: CurrentView, "+view0);
+ log.debug("+++ testStateReplication 1");
+ ObjectName drmService = new ObjectName("jboss.test:service=DRMTestCase");
+ IReplicants drm0 = (IReplicants)
+ MBeanServerInvocationHandler.newProxyInstance(server0, drmService,
+ IReplicants.class, true);
+ log.debug("+++ testStateReplication 2");
+ log.info(MBeanServerInvocationHandler.class.getProtectionDomain());
+ TestListener listener = new TestListener(log);
+ server0.addNotificationListener(drmService, listener, null, null);
+ log.info("server0 addNotificationListener");
+ log.debug("+++ testStateReplication 3");
+ String address = (String) drm0.lookupLocalReplicant();
+ log.debug("+++ testStateReplication 4");
+ log.info("server0: lookupLocalReplicant: "+address);
+ assertTrue("server0: address("+address+") == server0("+servers[0]+")",
+ address.equals(servers[0]));
+
+ RMIAdaptorExt server1 = (RMIAdaptorExt) adaptors[1];
+ log.info("server1: "+server1);
+ Vector view1 = (Vector) server1.getAttribute(clusterService, "CurrentView");
+ log.info("server1: CurrentView, "+view1);
+ IReplicants drm1 = (IReplicants)
+ MBeanServerInvocationHandler.newProxyInstance(server1, drmService,
+ IReplicants.class, true);
+ server1.addNotificationListener(drmService, listener, null, null);
+ log.info("server1 addNotificationListener");
+ address = (String) drm1.lookupLocalReplicant();
+ log.info("server1: lookupLocalReplicant: "+address);
+ assertTrue("server1: address("+address+") == server1("+servers[1]+")",
+ address.equals(servers[1]));
+
+ List replicants0 = drm0.lookupReplicants();
+ List replicants1 = drm1.lookupReplicants();
+ assertTrue("size of replicants0 == replicants1)",
+ replicants0.size() == replicants1.size());
+ HashSet testSet = new HashSet(replicants0);
+ for(int n = 0; n < replicants0.size(); n ++)
+ {
+ Object entry = replicants1.get(n);
+ assertTrue("replicants0 contains:"+entry, testSet.contains(entry));
+ }
+
+ //
+ for(int n = 0; n < 10; n ++)
+ {
+ drm0.add("key"+n, "data"+n+".0");
+ drm1.add("key"+n, "data"+n+".1");
+ }
+ for(int n = 0; n < 10; n ++)
+ {
+ String key = "key"+n;
+ log.info("key: "+key);
+ replicants0 = drm0.lookupReplicants(key);
+ replicants1 = drm1.lookupReplicants(key);
+ log.info("replicants0: "+replicants0);
+ log.info("replicants1: "+replicants1);
+ HashSet testSet0 = new HashSet(replicants0);
+ HashSet testSet1 = new HashSet(replicants1);
+ assertTrue("size of replicants0 == replicants1)",
+ replicants0.size() == replicants1.size());
+ Object entry = drm0.lookupLocalReplicant(key);
+ log.info("drm0.lookupLocalReplicant, key="+key+", entry="+entry);
+ assertTrue("replicants0 contains:"+entry, testSet0.contains(entry));
+ assertTrue("replicants1 contains:"+entry, testSet1.contains(entry));
+ entry = drm1.lookupLocalReplicant(key);
+ log.info("drm1.lookupLocalReplicant, key="+key+", entry="+entry);
+ assertTrue("replicants0 contains:"+entry, testSet0.contains(entry));
+ assertTrue("replicants1 contains:"+entry, testSet1.contains(entry));
+ }
+
+ for(int n = 0; n < 10; n ++)
+ drm0.remove("key"+n);
+
+ server0.removeNotificationListener(drmService, listener);
+ server1.removeNotificationListener(drmService, listener);
+ }
+
+ /**
+ * Tests the functionality of isMasterReplica(), also testing merge
+ * 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.
+ *
+ * @throws Exception
+ */
+ public void testIsMasterReplica() throws Exception
+ {
+ GossipRouter router = null;
+ log.debug("+++ testIsMasterReplica()");
+
+ try
+ {
+ String partitionName = "DRMTestCasePartition";
+ String muxFile = "jgroups-multiplexer.sar/META-INF/multiplexer-stacks.xml";
+ String stackName = "tunnel";
+
+ log.info("DRMTestCase.testIsMasterReplica() - starting GossipRouter");
+ // router characteristics here must match the definition in the stack configuration
+ router = new GossipRouter(12001, "127.0.0.1");
+ router.start();
+ Thread.sleep(10000);
+
+ Configuration cacheConfig1 = new Configuration();
+ cacheConfig1.setMultiplexerStack(stackName);
+ RuntimeConfig cacheRuntimeConfig1 = new RuntimeConfig();
+ JChannelFactory factory1 = new JChannelFactory();
+ factory1.setMultiplexerConfig(muxFile);
+ factory1.setNamingServicePort(1099);
+ cacheRuntimeConfig1.setMuxChannelFactory(factory1);
+ cacheConfig1.setRuntimeConfig(cacheRuntimeConfig1);
+ CacheJmxWrapper wrapper1 = new CacheJmxWrapper();
+ wrapper1.setConfiguration(cacheConfig1);
+ wrapper1.create();
+ wrapper1.start();
+
+ DistributedStateImpl ds1 = new DistributedStateImpl();
+ ds1.setClusteredCache(wrapper1.getCache());
+
+ ClusterPartitionConfig config1 = new ClusterPartitionConfig();
+ config1.setPartitionName(partitionName);
+ config1.setNodeUniqueId("DRMTestCaseNode1");
+ config1.setClusteredCache(wrapper1.getCache());
+ config1.setDistributedState(ds1);
+ config1.setStateTransferTimeout(30000);
+ config1.setMethodCallTimeout(60000);
+ ClusterPartition partition1 = new ClusterPartition(config1);
+ partition1.setBindIntoJndi(false);
+ partition1.create();
+ partition1.start();
+ Thread.sleep(10000);
+
+ Configuration cacheConfig2 = new Configuration();
+ cacheConfig2.setMultiplexerStack(stackName);
+ RuntimeConfig cacheRuntimeConfig2 = new RuntimeConfig();
+ JChannelFactory factory2 = new JChannelFactory();
+ factory2.setMultiplexerConfig(muxFile);
+ factory2.setNamingServicePort(1099);
+ cacheRuntimeConfig2.setMuxChannelFactory(factory2);
+ cacheConfig2.setRuntimeConfig(cacheRuntimeConfig2);
+ CacheJmxWrapper wrapper2 = new CacheJmxWrapper();
+ wrapper2.setConfiguration(cacheConfig2);
+ wrapper2.create();
+ wrapper2.start();
+
+ DistributedStateImpl ds2 = new DistributedStateImpl();
+ ds2.setClusteredCache(wrapper2.getCache());
+
+ ClusterPartitionConfig config2 = new ClusterPartitionConfig();
+ config2.setPartitionName(partitionName);
+ config2.setNodeUniqueId("DRMTestCaseNode2");
+ config2.setClusteredCache(wrapper2.getCache());
+ config2.setDistributedState(ds2);
+ config2.setStateTransferTimeout(30000);
+ config2.setMethodCallTimeout(60000);
+ ClusterPartition partition2 = new ClusterPartition(config2);
+ partition2.setBindIntoJndi(false);
+ partition2.create();
+ partition2.start();
+ Thread.sleep(10000);
+
+ DistributedReplicantManager drm1 = partition1.getDistributedReplicantManager();
+ DistributedReplicantManager drm2 = partition2.getDistributedReplicantManager();
+
+ // 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());
+
+ 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));
+
+ // 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
+ log.info("DRMTestCase.testIsMasterReplica() - stopping GossipRouter");
+ router.stop();
+ sleepThread(15000);
+
+ // 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));
+
+ // 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));
+
+ // Remove ServiceA replicant from partition1
+ drm1.remove(SERVICEA);
+
+ // test that this node is not the master replica
+ assertFalse("partition1 is not master replica after dropping ServiceA replicant",
+ drm1.isMasterReplica(SERVICEA));
+
+ //Restore the local replicant
+ drm1.add(SERVICEA, "valueA1a");
+
+ // simulate a merge
+ log.info("DRMTestCase.testIsMasterReplica() - restarting GossipRouter");
+ router.start();
+ // it seems to take more than 15 seconds for the merge to take effect
+ sleepThread(30000);
+
+ assertTrue(router.isStarted());
+
+ // 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());
+
+ // 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));
+
+ // 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());
+
+ partition1.stop();
+ partition2.stop();
+ }
+ finally
+ {
+ log.info("DRMTestCase.testIsMasterReplica() - cleaning up resources");
+ if (router != null)
+ router.stop();
+ }
+ }
+
+ /**
+ * Tests that one thread blocking in DRM.notifyKeyListeners() does not
+ * prevent other threads registering/unregistering listeners. JBAS-2539
+ *
+ * TODO move this test out of the testsuite and into the cluster module
+ * itself, since it doesn't rely on the container.
+ *
+ * @throws Exception
+ */
+ public void testKeyListenerDeadlock() throws Exception
+ {
+ log.debug("+++ testKeyListenerDeadlock()");
+
+ 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);
+
+ drm.create();
+
+ // Create a fake view for the MockHAPartition
+
+ Vector remoteAddresses = new Vector();
+ for (int i = 1; i < 5; i++)
+ remoteAddresses.add(new ClusterNode(new IpAddress("127.0.0.1", 12340 + i)));
+
+ Vector allNodes = new Vector(remoteAddresses);
+ allNodes.add(localAddress);
+ partition.setCurrentViewClusterNodes(allNodes);
+
+ drm.start();
+
+ BlockingListenerThread blt =
+ new BlockingListenerThread(drm, true, null);
+
+ // Hold the lock monitor so the test thread can't acquire it
+ // This keeps the blocking thread alive.
+ synchronized(lock) {
+ // Spawn a thread that will change a key and then block on the
+ // notification back to itself
+ blt.start();
+
+ sleepThread(50);
+
+ assertTrue("Test thread is alive", blt.isAlive());
+ assertTrue("Test thread is blocking", blt.isBlocking());
+
+ RegistrationThread rt = new RegistrationThread(drm);
+ rt.start();
+
+ sleepThread(50);
+
+ assertTrue("No deadlock on listener registration", rt.isRegistered());
+
+ assertTrue("No deadlock on listener unregistration", rt.isUnregistered());
+
+ assertNull("No exception in deadlock tester", blt.getException());
+
+ assertTrue("Test thread is still blocking", blt.isBlocking());
+ assertTrue("Test thread is still alive", blt.isAlive());
+ }
+
+ drm.unregisterListener("TEST", blt);
+
+ sleepThread(50);
+
+ // Test going through remove
+ blt = new BlockingListenerThread(drm, false, null);
+
+ // Hold the lock monitor so the test thread can't acquire it
+ // This keeps the blocking thread alive.
+ synchronized(lock) {
+ // Spawn a thread that will change a key and then block on the
+ // notification back to itself
+ blt.start();
+
+ sleepThread(50);
+
+ assertTrue("Test thread is alive", blt.isAlive());
+ assertTrue("Test thread is blocking", blt.isBlocking());
+
+ RegistrationThread rt = new RegistrationThread(drm);
+ rt.start();
+
+ sleepThread(50);
+
+ assertTrue("No deadlock on listener registration", rt.isRegistered());
+
+ assertTrue("No deadlock on listener unregistration", rt.isUnregistered());
+
+ assertNull("No exception in deadlock tester", blt.getException());
+
+ assertTrue("Test thread is still blocking", blt.isBlocking());
+ assertTrue("Test thread is still alive", blt.isAlive());
+ }
+ }
+ finally {
+ MBeanServerFactory.releaseMBeanServer(mbeanServer);
+ }
+ }
+
+
+ /**
+ * Tests that remotely-originated calls don't block.
+ *
+ * TODO move this test out of the testsuite and into the cluster module
+ * itself, since it doesn't rely on the container.
+ *
+ * @throws Exception
+ */
+ public void testRemoteCallBlocking() throws Exception
+ {
+ log.debug("+++ testRemoteCallBlocking()");
+
+ 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);
+
+ drm.create();
+
+ // Create a fake view for the MockHAPartition
+
+ Vector remoteAddresses = new Vector();
+ for (int i = 1; i < 5; i++)
+ remoteAddresses.add(new ClusterNode(new IpAddress("127.0.0.1", 12340 + i)));
+
+ Vector allNodes = new Vector(remoteAddresses);
+ allNodes.add(localAddress);
+ partition.setCurrentViewClusterNodes(allNodes);
+
+ drm.start();
+
+ String sender = ((ClusterNode)remoteAddresses.get(0)).getName();
+ BlockingListenerThread blt =
+ new BlockingListenerThread(drm, true, sender);
+
+ // Hold the lock monitor so the test thread can't acquire it
+ // This keeps the blocking thread alive.
+ synchronized(lock) {
+ // Spawn a thread that will change a key and then block on the
+ // notification back to itself
+ blt.start();
+
+ sleepThread(50);
+
+ assertFalse("JGroups thread is not alive", blt.isAlive());
+ assertTrue("Async handler thread is blocking", blt.isBlocking());
+
+ assertNull("No exception in JGroups thread", blt.getException());
+ }
+
+ drm.unregisterListener("TEST", blt);
+
+ sleepThread(50);
+
+ // Test going through remove
+ blt = new BlockingListenerThread(drm, false, sender);
+
+ // Hold the lock monitor so the test thread can't acquire it
+ // This keeps the blocking thread alive.
+ synchronized(lock) {
+ // Spawn a thread that will change a key and then block on the
+ // notification back to itself
+ blt.start();
+
+ sleepThread(50);
+
+ assertFalse("JGroups thread is not alive", blt.isAlive());
+ assertTrue("Async handler thread is blocking", blt.isBlocking());
+
+ assertNull("No exception in JGroups thread", blt.getException());
+ }
+ }
+ finally {
+ MBeanServerFactory.releaseMBeanServer(mbeanServer);
+ }
+ }
+
+ /**
+ * Tests that one thread blocking in DRM.notifyKeyListeners() does not
+ * prevent other threads that use different keys adding/removing
+ * replicants. JBAS-2169
+ *
+ * TODO move this test out of the testsuite and into the cluster module
+ * itself, since it doesn't rely on the container.
+ *
+ * @throws Exception
+ */
+ public void testNonConflictingAddRemoveDeadlock() throws Exception
+ {
+
+ log.debug("+++ testNonConflictingAddRemoveDeadlock()");
+
+ addRemoveDeadlockTest(false);
+ }
+
+ /**
+ * Tests that one thread blocking in DRM.notifyKeyListeners() does not
+ * prevent other threads that use the same keys adding/removing
+ * replicants. JBAS-1151
+ *
+ * NOTE: This test basically demonstrates a small race condition that can
+ * happen with the way HASingletonSupport's startService() method is
+ * implemented (actually HAServiceMBeanSupport, but relevant in the case
+ * of subclass HASingletonSupport, and in particular in its use in the
+ * HASingletonDeployer service). However, since the test doesn't actually
+ * use the relevant code, but rather uses mock objects that work the same
+ * way, this test is disabled -- its purpose has been achieved. JIRA issue
+ * JBAS-1151 tracks the real problem; when it's resolved we'll create a test
+ * case against the real code that proves that fact.
+ *
+ * TODO move this test out of the testsuite and into the cluster module
+ * itself, since it doesn't rely on the container.
+ *
+ * @throws Exception
+ */
+ public void badtestConflictingAddRemoveDeadlock() throws Exception
+ {
+ log.debug("+++ testConflictingAddRemoveDeadlock()");
+
+ addRemoveDeadlockTest(true);
+ }
+
+ private void addRemoveDeadlockTest(boolean conflicting) throws Exception
+ {
+ String[] keys = { "A", "B", "C", "D", "E" };
+ int count = keys.length;
+
+ 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);
+
+ drm.create();
+
+ // Create a fake view for the MockHAPartition
+
+ Vector remoteAddresses = new Vector();
+ ClusterNode remote = new ClusterNode(new IpAddress("127.0.0.1", 12341));
+ remoteAddresses.add(remote);
+
+ Vector allNodes = new Vector(remoteAddresses);
+ allNodes.add(localAddress);
+ partition.setCurrentViewClusterNodes(allNodes);
+
+ drm.start();
+
+ MockDeployer deployer = new MockDeployer(drm);
+
+ if (!conflicting)
+ {
+ // Register a MockHASingletonDeployer, but since we're in
+ // non-conflicting mode, the DeployerThreads won't deal with it
+ MockHASingletonDeployer listener =
+ new MockHASingletonDeployer(deployer, "HASingleton", log);
+
+ drm.registerListener("HASingleton", listener);
+ drm.add("HASingleton", "HASingleton");
+ }
+
+ // Create a semaphore to gate the threads and acquire all its permits
+ Semaphore semaphore = new Semaphore(count + 1);
+ for (int i = 0; i <= count; i++)
+ semaphore.acquire();
+
+ DeployerThread[] deployers = new DeployerThread[keys.length];
+ for (int i = 0; i < count; i++)
+ {
+ DistributedReplicantManager.ReplicantListener listener = null;
+ if (conflicting)
+ {
+ listener = new MockHASingletonDeployer(deployer, keys[i], log);
+ }
+ else
+ {
+ listener = new NullListener();
+ }
+ deployers[i] = new DeployerThread(deployer, keys[i], listener, semaphore, log);
+ deployers[i].start();
+ }
+
+ String[] jgKeys = keys;
+ if (!conflicting)
+ {
+ // The JGroups thread also deals with the MockHASingletonDeployer
+ // key that the DeployerThreads don't
+ jgKeys = new String[keys.length + 1];
+ System.arraycopy(keys, 0, jgKeys, 0, keys.length);
+ jgKeys[keys.length] = "HASingleton";
+ }
+ JGroupsThread jgThread = new JGroupsThread(drm, jgKeys, remote.getName(), semaphore);
+ jgThread.start();
+
+ // Launch the threads
+ semaphore.release(count + 1);
+
+ boolean reacquired = false;
+ try
+ {
+ // Give the threads 5 secs to acquire the semaphore
+ long maxElapsed = System.currentTimeMillis() + 5000;
+ for (int i = 0; i < keys.length; i++)
+ {
+ if (deployers[i].getCount() < 0)
+ {
+ assertTrue("Thread " + keys[i] + " started in time",
+ maxElapsed - System.currentTimeMillis() > 0);
+ sleepThread(10);
+ i--; // try again
+ }
+ }
+
+ while (jgThread.getCount() < 0)
+ {
+ assertTrue("jgThread started in time",
+ maxElapsed - System.currentTimeMillis() > 0);
+ sleepThread(10);
+ }
+ // Reaquire all the permits, thus showing the threads didn't deadlock
+
+ // Give them 500 ms per loop
+ maxElapsed = System.currentTimeMillis() + (500 * LOOP_COUNT);
+ for (int i = 0; i <= count; i++)
+ {
+ long waitTime = maxElapsed - System.currentTimeMillis();
+ assertTrue("Acquired thread " + i, semaphore.attempt(waitTime));
+ }
+
+ reacquired = true;
+
+ // Ensure there were no exceptions
+ for (int i = 0; i < keys.length; i++)
+ {
+ assertEquals("Thread " + keys[i] + " finished", LOOP_COUNT, deployers[i].getCount());
+ assertNull("Thread " + keys[i] + " saw no exceptions", deployers[i].getException());
+ }
+ assertEquals("JGroups Thread finished", LOOP_COUNT, jgThread.getCount());
+ assertNull("JGroups Thread saw no exceptions", jgThread.getException());
+ }
+ finally
+ {
+
+ if (!reacquired)
+ {
+ for (int i = 0; i < keys.length; i++)
+ {
+ if (deployers[i].getException() != null)
+ {
+ System.out.println("Exception in deployer " + i);
+ deployers[i].getException().printStackTrace(System.out);
+ }
+ else
+ {
+ System.out.println("Thread " + i + " completed " + deployers[i].getCount());
+ }
+ }
+ if (jgThread.getException() != null)
+ {
+ System.out.println("Exception in jgThread");
+ jgThread.getException().printStackTrace(System.out);
+ }
+ else
+ {
+ System.out.println("jgThread completed " + jgThread.getCount());
+ }
+ }
+
+ // Be sure the threads are dead
+ if (jgThread.isAlive())
+ {
+ jgThread.interrupt();
+ sleepThread(5);
+ printStackTrace(jgThread.getName(), jgThread.getException());
+ }
+ for (int i = 0; i < keys.length; i++)
+ {
+ if (deployers[i].isAlive())
+ {
+ deployers[i].interrupt();
+ sleepThread(5);
+ printStackTrace(deployers[i].getName(), deployers[i].getException());
+ }
+ }
+
+ }
+ }
+ finally {
+ MBeanServerFactory.releaseMBeanServer(mbeanServer);
+ }
+ }
+
+ public void testReplicantOrder() throws Exception
+ {
+ MBeanServer mbeanServer =
+ MBeanServerFactory.createMBeanServer("mockPartitionA");
+ try {
+
+ // Create a fake view for the MockHAPartition
+ ClusterNode[] nodes = new ClusterNode[5];
+ String[] names = new String[nodes.length];
+ Integer[] replicants = new Integer[nodes.length];
+ Vector allNodes = new Vector();
+ for (int i = 0; i < nodes.length; i++)
+ {
+ nodes[i] = new ClusterNode(new IpAddress("127.0.0.1", 12340 + i));
+ allNodes.add(nodes[i]);
+ names[i] = nodes[i].getName();
+ replicants[i] = new Integer(i);
+ }
+
+ MockHAPartition partition = new MockHAPartition(nodes[2]);
+ partition.setCurrentViewClusterNodes(allNodes);
+
+ DistributedReplicantManagerImpl drm =
+ new DistributedReplicantManagerImpl(partition);
+ drm.create();
+ drm.start();
+
+ CachingListener listener = new CachingListener();
+ drm.registerListener("TEST", listener);
+
+ SecureRandom random = new SecureRandom();
+ boolean[] added = new boolean[nodes.length];
+ List lookup = null;
+ for (int i = 0; i < 10; i++)
+ {
+ int node = random.nextInt(nodes.length);
+ if (added[node])
+ {
+ if (node == 2)
+ drm.remove("TEST");
+ else
+ drm._remove("TEST", nodes[node].getName());
+ added[node] = false;
+ }
+ else
+ {
+ if (node == 2)
+ drm.add("TEST", replicants[node]);
+ else
+ drm._add("TEST", nodes[node].getName(), replicants[node]);
+ added[node] = true;
+ }
+
+ // Confirm the proper order of the replicant node names
+ lookup = maskListClass(drm.lookupReplicantsNodeNames("TEST"));
+ confirmReplicantList(lookup, names, added);
+
+ // Confirm the proper order of the replicants via lookupReplicants
+ lookup = maskListClass(drm.lookupReplicants("TEST"));
+ confirmReplicantList(lookup, replicants, added);
+
+ // Confirm the listener got the same list
+// assertEquals("Listener received a correct list", lookup,
+// maskListClass(listener.replicants));
+ }
+
+ // Let the asynchronous notification thread catch up
+ sleep(25);
+
+ // Confirm all lists presented to the listener were properly ordered
+ assertTrue("Listener saw no misordered lists", listener.clean);
+
+ }
+ finally {
+ MBeanServerFactory.releaseMBeanServer(mbeanServer);
+ }
+ }
+
+ private void confirmReplicantList(List current, Object[] all, boolean[] added)
+ {
+ Iterator iter = current.iterator();
+ for (int i = 0; i < added.length; i++)
+ {
+ if (added[i])
+ {
+ assertTrue("List has more replicants", iter.hasNext());
+ assertEquals("Replicant for node " + i + " is next",
+ all[i], iter.next());
+ }
+ }
+ assertFalse("List has no extra replicants", iter.hasNext());
+ }
+
+ /** Converts the given list to an ArrayList, if it isn't already */
+ private List maskListClass(List toMask)
+ {
+ if (toMask instanceof ArrayList)
+ return toMask;
+ else if (toMask == null)
+ return new ArrayList();
+ else
+ return new ArrayList(toMask);
+ }
+
+ private static void sleepThread(long millis)
+ {
+ try
+ {
+ Thread.sleep(millis);
+ }
+ catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private static void printStackTrace(String threadName, Exception e)
+ {
+ if (e instanceof InterruptedException)
+ {
+ System.out.println("Stack trace for " + threadName);
+ e.printStackTrace(System.out);
+ System.out.println();
+ }
+ }
+
+}
Property changes on: trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/DRMTestCase.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ native
Added: trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/FamilyClusterInfoUnitTestCase.java
===================================================================
--- trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/FamilyClusterInfoUnitTestCase.java (rev 0)
+++ trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/FamilyClusterInfoUnitTestCase.java 2007-07-24 03:27:28 UTC (rev 64237)
@@ -0,0 +1,368 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2007, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.test.cluster.defaultcfg.test;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+
+import org.jboss.ha.framework.interfaces.ClusteringTargetsRepository;
+import org.jboss.ha.framework.interfaces.FamilyClusterInfo;
+
+import junit.framework.TestCase;
+
+/**
+ * Test of FamilyClusterInfoImpl.
+ *
+ * @author <a href="brian.stansberry at jboss.com">Brian Stansberry</a>
+ * @version $Revision$
+ */
+public class FamilyClusterInfoUnitTestCase extends TestCase
+{
+ private abstract class FCIChanger extends Thread
+ {
+ private boolean started;
+ private boolean stopped;
+ private Throwable caught;
+
+ protected FamilyClusterInfo fci;
+
+ FCIChanger(FamilyClusterInfo fci)
+ {
+ this.fci = fci;
+ }
+
+ abstract void update();
+
+
+ public void run()
+ {
+ try
+ {
+ started = true;
+
+ while (!stopped)
+ {
+ if (interrupted())
+ throw new InterruptedException();
+
+ update();
+ }
+
+ }
+ catch (InterruptedException ie)
+ {
+ if (!stopped)
+ caught = ie;
+ }
+ catch (Throwable t)
+ {
+ caught = t;
+ }
+ finally
+ {
+ started = false;
+ }
+ }
+
+ void beginUpdates()
+ {
+ this.start();
+ while (!started)
+ {
+ try
+ {
+ sleep(10);
+ }
+ catch (InterruptedException e)
+ {
+ caught = e;
+ }
+ }
+ }
+
+ void endUpdates()
+ {
+ if (started)
+ {
+ stopped = true;
+ try
+ {
+ this.join(250);
+ }
+ catch (InterruptedException ignored) {}
+ }
+
+ if (started)
+ interrupt();
+ }
+
+ Throwable getThrowable()
+ {
+ return caught;
+ }
+ }
+
+ private class Updater extends FCIChanger
+ {
+ private ArrayList targets = new ArrayList();
+ private int viewId;
+
+ Updater(FamilyClusterInfo fci)
+ {
+ super(fci);
+ }
+
+ void update()
+ {
+ targets.add(new Object());
+ viewId++;
+ fci.updateClusterInfo((ArrayList) targets.clone(), viewId);
+ }
+ }
+
+ private class Remover extends FCIChanger
+ {
+ Remover(FamilyClusterInfo fci)
+ {
+ super(fci);
+ }
+
+ void update()
+ {
+ List targets = fci.getTargets();
+ if (targets.size() > 0)
+ fci.removeDeadTarget(targets.get(0));
+ }
+
+ }
+
+ private class Resetter extends FCIChanger
+ {
+ Resetter(FamilyClusterInfo fci)
+ {
+ super(fci);
+ }
+
+ void update()
+ {
+ fci.resetView();
+ }
+ }
+
+ public void testSynchronization() throws Exception
+ {
+ ClusteringTargetsRepository.initTarget("testSynchronization", new ArrayList(), 0);
+ FamilyClusterInfo fci = ClusteringTargetsRepository.getFamilyClusterInfo("testSynchronization");
+
+ Updater updater = new Updater(fci);
+ Remover remover = new Remover(fci);
+ Resetter resetter = new Resetter(fci);
+
+ updater.beginUpdates();
+
+ checkFCIConsistency(fci, 150, false);
+
+ remover.beginUpdates();
+
+ checkFCIConsistency(fci, 150, true);
+
+ resetter.beginUpdates();
+
+ checkFCIConsistency(fci, 150, true);
+
+ updater.endUpdates();
+ remover.endUpdates();
+ resetter.endUpdates();
+
+ assertNull("Updater had no exceptions", updater.getThrowable());
+ assertNull("Remover had no exceptions", remover.getThrowable());
+ assertNull("Resetter had no exceptions", resetter.getThrowable());
+
+ }
+
+ public void testTargetListImmutability() throws Exception
+ {
+ ArrayList targets = new ArrayList();
+ targets.add("ONE");
+ targets.add("TWO");
+ ClusteringTargetsRepository.initTarget("testImmutability", targets, 0);
+ FamilyClusterInfo fci = ClusteringTargetsRepository.getFamilyClusterInfo("testImmutability");
+
+ List fciTargets = fci.getTargets();
+
+ // Confirm the targets are what we expect
+ assertEquals("Expected number of targets", 2, fciTargets.size());
+ assertEquals("First target as expected", "ONE", fciTargets.get(0));
+ assertEquals("Second target as expected", "TWO", fciTargets.get(1));
+
+ try
+ {
+ fciTargets.add("FAIL");
+ fail("add call did not fail");
+ }
+ catch (UnsupportedOperationException good) {}
+
+ try
+ {
+ fciTargets.addAll(targets);
+ fail("addAll call did not fail");
+ }
+ catch (UnsupportedOperationException good) {}
+
+ try
+ {
+ fciTargets.clear();
+ fail("clear call did not fail");
+ }
+ catch (UnsupportedOperationException good) {}
+
+ try
+ {
+ fciTargets.remove(0);
+ fail("remove call did not fail");
+ }
+ catch (UnsupportedOperationException good) {}
+
+ try
+ {
+ fciTargets.set(0, "FAIL");
+ fail("set call did not fail");
+ }
+ catch (UnsupportedOperationException good) {}
+
+ try
+ {
+ fciTargets.removeAll(targets);
+ fail("removeAll call did not fail");
+ }
+ catch (UnsupportedOperationException good) {}
+
+ try
+ {
+ fciTargets.retainAll(targets);
+ fail("retainAll call did not fail");
+ }
+ catch (UnsupportedOperationException good) {}
+
+ Iterator iter = fciTargets.iterator();
+ int count = 0;
+ while (iter.hasNext())
+ {
+ iter.next();
+ count++;
+ }
+ assertEquals("Correct count", 2, count);
+ try
+ {
+ iter.remove();
+ fail("Iterator.remove call did not fail");
+ }
+ catch (UnsupportedOperationException good) {}
+
+ ListIterator listIter = fciTargets.listIterator();
+ count = 0;
+ while (listIter.hasNext())
+ {
+ listIter.next();
+ count++;
+ }
+ assertEquals("Correct count", 2, count);
+ try
+ {
+ listIter.remove();
+ fail("Iterator.remove call did not fail");
+ }
+ catch (UnsupportedOperationException good) {}
+
+ while (listIter.hasPrevious())
+ {
+ listIter.previous();
+ count--;
+ }
+ assertEquals("Correct count", 0, count);
+
+ listIter = fciTargets.listIterator(1);
+ while (listIter.hasNext())
+ {
+ listIter.next();
+ count++;
+ }
+ assertEquals("Correct count", 1, count);
+ try
+ {
+ listIter.remove();
+ fail("Iterator.remove call did not fail");
+ }
+ catch (UnsupportedOperationException good) {}
+
+ while (listIter.hasPrevious())
+ {
+ listIter.previous();
+ count--;
+ }
+ assertEquals("Correct count", -1, count);
+
+ // Check the lists returned by other methods
+ fciTargets = fci.updateClusterInfo(targets, 0);
+
+ try
+ {
+ fciTargets.add("FAIL");
+ fail("add call did not fail");
+ }
+ catch (UnsupportedOperationException good) {}
+
+ fciTargets = fci.removeDeadTarget(targets.get(0));
+
+ try
+ {
+ fciTargets.add("FAIL");
+ fail("add call did not fail");
+ }
+ catch (UnsupportedOperationException good) {}
+
+ }
+
+ private void checkFCIConsistency(FamilyClusterInfo fci, int checks, boolean allowOutOfSync)
+ {
+
+ for (int i = 0; i < checks; i++)
+ {
+ synchronized (fci)
+ {
+ if (fci.currentMembershipInSyncWithViewId())
+ {
+ List targets = fci.getTargets();
+ long vid = fci.getCurrentViewId();
+ assertEquals("targets and vid match", vid, targets.size());
+ }
+ else
+ {
+ assertTrue("OK for FCI view to be out of sync", allowOutOfSync);
+ }
+ }
+ }
+
+ }
+}
Property changes on: trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/FamilyClusterInfoUnitTestCase.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ native
Added: trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/HAInvokerUnitTestCase.java
===================================================================
--- trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/HAInvokerUnitTestCase.java (rev 0)
+++ trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/HAInvokerUnitTestCase.java 2007-07-24 03:27:28 UTC (rev 64237)
@@ -0,0 +1,165 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.test.cluster.defaultcfg.test;
+
+import java.util.Properties;
+
+import javax.naming.Context;
+import javax.naming.InitialContext;
+
+import org.jboss.invocation.ServiceUnavailableException;
+import org.jboss.jmx.adaptor.rmi.RMIAdaptor;
+import org.jboss.test.JBossClusteredTestCase;
+import org.jboss.test.cluster.invokerha.HAServiceRemote;
+
+import junit.framework.Test;
+
+/**
+ * Tests for ha invoker.
+ *
+ * @author <a href="mailto:brian.stansberry at jboss.com">Brian Stansberry</a>
+ * @version $Revision$
+ */
+public class HAInvokerUnitTestCase
+ extends JBossClusteredTestCase
+{
+ private static boolean deployed0_ = true;
+ private static boolean deployed1_ = true;
+
+ public HAInvokerUnitTestCase(String name)
+ {
+ super(name);
+ }
+
+ public static Test suite()
+ throws Exception
+ {
+ return JBossClusteredTestCase.getDeploySetup(HAInvokerUnitTestCase.class, "ha-invoker.sar");
+ }
+
+// public void testUnifiedHAProxyFailover()
+// throws Exception
+// {
+// haProxyFailoverTest("jmx/HAServiceUnified");
+// }
+
+// public void testPooledHAProxyFailover()
+// throws Exception
+// {
+// haProxyFailoverTest("jmx/HAServicePooled");
+// }
+//
+ public void testJRMPHAProxyFailover()
+ throws Exception
+ {
+ haProxyFailoverTest("jmx/HAService");
+ }
+
+ private void haProxyFailoverTest(String jndiName) throws Exception
+ {
+ getLog().debug("testHAProxyFailover");
+
+ String[] urls = getNamingURLs();
+ Properties env = new Properties();
+ env.setProperty(Context.INITIAL_CONTEXT_FACTORY,
+ "org.jnp.interfaces.NamingContextFactory");
+ env.setProperty(Context.PROVIDER_URL, urls[0]);
+ Context ctx = new InitialContext(env);
+ getLog().debug("Got InitialContext with " + urls[0]);
+
+ HAServiceRemote remote = (HAServiceRemote) ctx.lookup(jndiName);
+ getLog().debug("Found " + jndiName);
+ assertEquals("Hello", remote.hello());
+ String nodeA = remote.getClusterNode();
+ assertNotNull("Got clusterNode", nodeA);
+ getLog().debug("nodeA OK");
+ // Invoke again to check it works with load balancing
+ assertFalse("Requests load balanced", nodeA.equals(remote.getClusterNode()));
+ getLog().debug("nodeA load balanced OK");
+
+ // Undeploy from one node
+ reconfigureCluster();
+
+ // Check it still works
+ try
+ {
+ assertEquals("Hello", remote.hello());
+ getLog().debug("OK after reconfigure");
+ }
+ catch (ServiceUnavailableException sue)
+ {
+ fail("Known issue JBAS-3194: " + sue.getMessage());
+ }
+ }
+
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+ configureCluster();
+ }
+
+ protected String getDeploymentName()
+ {
+ return "ha-invoker.sar";
+ }
+
+ protected void configureCluster() throws Exception
+ {
+ RMIAdaptor[] adaptors = getAdaptors();
+ String warName = getDeploymentName();
+ if (!deployed0_)
+ {
+ deploy(adaptors[0], warName);
+ getLog().debug("Deployed " + warName + " on server0");
+ deployed0_ = true;
+ }
+ if (!deployed1_)
+ {
+ deploy(adaptors[1], warName);
+ getLog().debug("Deployed " + warName + " on server1");
+ deployed1_ = true;
+ }
+
+ sleep(2000);
+ }
+
+ protected void reconfigureCluster() throws Exception
+ {
+ RMIAdaptor[] adaptors = getAdaptors();
+ if (!deployed1_)
+ {
+ deploy(adaptors[1], getDeploymentName());
+ deployed1_ = true;
+
+ sleep(2000);
+ }
+
+ if (deployed0_)
+ {
+ undeploy(adaptors[0], getDeploymentName());
+ deployed0_ = false;
+
+ sleep(2000);
+ }
+ }
+
+}
Property changes on: trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/HAInvokerUnitTestCase.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ native
Added: trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/HAServiceMBeanSupportUnitTestCase.java
===================================================================
--- trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/HAServiceMBeanSupportUnitTestCase.java (rev 0)
+++ trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/HAServiceMBeanSupportUnitTestCase.java 2007-07-24 03:27:28 UTC (rev 64237)
@@ -0,0 +1,160 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.test.cluster.defaultcfg.test;
+
+import java.util.EmptyStackException;
+
+import javax.management.AttributeChangeNotification;
+import javax.management.Notification;
+
+import junit.framework.TestCase;
+
+import org.jboss.test.cluster.haservice.HAServiceMBeanSupportTester;
+
+/**
+ *
+ * @author Ivelin Ivanov <ivelin at apache.org>
+ *
+ */
+public class HAServiceMBeanSupportUnitTestCase extends TestCase
+{
+
+ private HAServiceMBeanSupportTester haServiceMBeanSupportTester_ = null;
+
+ public HAServiceMBeanSupportUnitTestCase(String name)
+ {
+ super(name);
+ }
+
+ public void setUp()
+ {
+ haServiceMBeanSupportTester_ = new HAServiceMBeanSupportTester();
+ }
+
+
+ public void tearDown()
+ {
+ haServiceMBeanSupportTester_ = null;
+ }
+
+
+ /**
+ *
+ * messages should be sent out to both remote and local listeners.
+ *
+ */
+ public void testSendNotificationBroadcastsToClusterAndLocally()
+ {
+ Notification notification = new Notification("test.notification", "some:name=tester", 1);
+ haServiceMBeanSupportTester_.sendNotification( notification );
+
+ assertEquals("sendNotificationToLocalListeners() was not handed the original notification",
+ haServiceMBeanSupportTester_.__invokationStack__.pop(), notification );
+
+ assertEquals("method not invoked as expected",
+ haServiceMBeanSupportTester_.__invokationStack__.pop(), "sendNotificationToLocalListeners");
+
+ assertEquals("sendNotificationRemote() was not handed the original notification",
+ haServiceMBeanSupportTester_.__invokationStack__.pop(), notification );
+
+ assertEquals("method not invoked as expected",
+ haServiceMBeanSupportTester_.__invokationStack__.pop(), "sendNotificationRemote");
+ }
+
+ /**
+ *
+ * Even if the message cannot be sent out to the cluster,
+ * it should still be delivered to local listeners.
+ *
+ */
+ public void testSendNotificationAfterClusterFailureContinueWithLocal()
+ {
+ haServiceMBeanSupportTester_.__shouldSendNotificationRemoteFail__ = true;
+
+ Notification notification = new Notification("test.notification", "some:name=tester", 1);
+ haServiceMBeanSupportTester_.sendNotification( notification );
+
+ assertEquals("sendNotificationToLocalListeners() was not handed the original notification",
+ haServiceMBeanSupportTester_.__invokationStack__.pop(), notification );
+
+ assertEquals("method not invoked as expected",
+ haServiceMBeanSupportTester_.__invokationStack__.pop(), "sendNotificationToLocalListeners");
+ }
+
+ public void testSendLifecycleNotifications()
+ {
+ Notification notification = new AttributeChangeNotification(
+ haServiceMBeanSupportTester_,
+ 1, System.currentTimeMillis(), "test",
+ "State", "java.lang.Integer",
+ new Integer(0), new Integer(1)
+ );
+
+ haServiceMBeanSupportTester_.setSendRemoteLifecycleNotifications(false);
+
+ haServiceMBeanSupportTester_.sendNotification( notification );
+
+ assertEquals("sendNotificationToLocalListeners() was handed the original notification",
+ haServiceMBeanSupportTester_.__invokationStack__.pop(), notification );
+
+ assertEquals("method invoked as expected",
+ haServiceMBeanSupportTester_.__invokationStack__.pop(), "sendNotificationToLocalListeners");
+
+ try
+ {
+ haServiceMBeanSupportTester_.__invokationStack__.pop();
+ fail("sendNotificationRemote() was not handed the original notification");
+ }
+ catch (EmptyStackException good) {}
+
+ haServiceMBeanSupportTester_.setSendRemoteLifecycleNotifications(true);
+ haServiceMBeanSupportTester_.setSendLocalLifecycleNotifications(false);
+
+ haServiceMBeanSupportTester_.sendNotification( notification );
+
+ assertEquals("sendNotificationRemote() was handed the original notification",
+ haServiceMBeanSupportTester_.__invokationStack__.pop(), notification );
+
+ assertEquals("method invoked as expected",
+ haServiceMBeanSupportTester_.__invokationStack__.pop(), "sendNotificationRemote");
+
+ try
+ {
+ haServiceMBeanSupportTester_.__invokationStack__.pop();
+ fail("sendNotificationToLocalListeners() was not handed the original notification");
+ }
+ catch (EmptyStackException good) {}
+ }
+
+ public void testServiceHAName() throws Exception
+ {
+ assertEquals("Default name correct", HAServiceMBeanSupportTester.SERVICE_NAME,
+ haServiceMBeanSupportTester_.getServiceHAName());
+
+ haServiceMBeanSupportTester_.setServiceHAName("Test");
+
+ assertEquals("Specified name correct", "Test",
+ haServiceMBeanSupportTester_.getServiceHAName());
+ }
+
+}
Property changes on: trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/HAServiceMBeanSupportUnitTestCase.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ native
Added: trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/HASingletonControllerUnitTestCase.java
===================================================================
--- trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/HASingletonControllerUnitTestCase.java (rev 0)
+++ trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/HASingletonControllerUnitTestCase.java 2007-07-24 03:27:28 UTC (rev 64237)
@@ -0,0 +1,154 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.test.cluster.defaultcfg.test;
+
+import javax.management.ObjectName;
+
+import junit.framework.TestCase;
+
+import org.jboss.test.cluster.hasingleton.HASingletonControllerTester;
+
+/**
+ * HASingletonController tests
+ *
+ * @author Ivelin Ivanov <ivelin at jboss.org>
+ * @version $Revision$
+ */
+public class HASingletonControllerUnitTestCase extends TestCase
+{
+ private HASingletonControllerTester singletonControllerTester = null;
+
+ public HASingletonControllerUnitTestCase(String name)
+ {
+ super(name);
+ }
+
+ public void setUp()
+ {
+ singletonControllerTester = new HASingletonControllerTester();
+ }
+
+
+ public void tearDown()
+ {
+ singletonControllerTester = null;
+ }
+
+ public void testSetValidTargetName() throws Exception
+ {
+ ObjectName someSingletonService = new ObjectName("jboss:service=HASingletonMBeanExample");
+ singletonControllerTester.setTargetName(someSingletonService);
+
+ assertEquals("setTargetName() failed", singletonControllerTester.getTargetName(), someSingletonService);
+ }
+
+ public void testSetTargetStartMethod()
+ {
+ String someMethod = "startTheSingleton";
+ singletonControllerTester.setTargetStartMethod(someMethod);
+
+ assertEquals("setTargetStartMethod() failed", singletonControllerTester.getTargetStartMethod(), someMethod);
+ }
+
+ public void testSetTargetStartMethodArgument()
+ {
+ String someArgument = "aStartValue";
+ singletonControllerTester.setTargetStartMethodArgument(someArgument);
+
+ assertEquals("setTargetStartMethodArgument() failed", singletonControllerTester.getTargetStartMethodArgument(), someArgument);
+ }
+
+ public void testSetTargetStopMethodArgument()
+ {
+ String someArgument = "aSopValue";
+ singletonControllerTester.setTargetStopMethodArgument(someArgument);
+
+ assertEquals("setTargetStopMethodArgument() failed", singletonControllerTester.getTargetStopMethodArgument(), someArgument);
+ }
+
+ /* HASingletonController can now start without a target/method set.
+ * We can use the produced notifications to start/stop other services
+ * by setting a dependency on a Barrier mbean, see JBAS-2626
+ public void testSetNullOrBlankStartTargetName()
+ {
+ String someMethod = "";
+ singletonControllerTester.setTargetStartMethod(someMethod);
+
+ assertEquals("setTargetStartMethod() failed to set default value", singletonControllerTester.getTargetStartMethod(), "startSingleton");
+
+ someMethod = null;
+ singletonControllerTester.setTargetStartMethod(someMethod);
+
+ assertEquals("setTargetStartMethod() failed to set default value", singletonControllerTester.getTargetStartMethod(), "startSingleton");
+ }
+ */
+
+ public void testSetTargetStopMethod()
+ {
+ String someMethod = "stopTheSingleton";
+ singletonControllerTester.setTargetStopMethod(someMethod);
+
+ assertEquals("setTargetStartMethod() failed", singletonControllerTester.getTargetStopMethod(), someMethod);
+ }
+
+ /* HASingletonController can now start without a target/method set.
+ * We can use the produced notifications to start/stop other services
+ * by setting a dependency on a Barrier mbean, see JBAS-2626
+ public void testSetNullOrBlankStopTargetName()
+ {
+ String someMethod = "";
+ singletonControllerTester.setTargetStopMethod(someMethod);
+
+ assertEquals("setTargetStartMethod() failed to set default value", singletonControllerTester.getTargetStopMethod(), "stopSingleton");
+
+ someMethod = null;
+ singletonControllerTester.setTargetStopMethod(someMethod);
+
+ assertEquals("setTargetStartMethod() failed to set default value", singletonControllerTester.getTargetStopMethod(), "stopSingleton");
+ }
+ */
+
+ public void testStartSingleton() throws Exception
+ {
+ ObjectName serviceName = new ObjectName("jboss:service=HASingletonMBeanExample");
+ singletonControllerTester.setTargetName(serviceName);
+ singletonControllerTester.setTargetStartMethod("startTheSingleton");
+
+ singletonControllerTester.startSingleton();
+
+ assertEquals("method not invoked as expected",
+ singletonControllerTester.__invokationStack__.pop(), "invokeMBeanMethod:jboss:service=HASingletonMBeanExample.startTheSingleton");
+ }
+
+ public void testStopSingleton() throws Exception
+ {
+ ObjectName serviceName = new ObjectName("jboss:service=HASingletonMBeanExample");
+ singletonControllerTester.setTargetName(serviceName);
+ singletonControllerTester.setTargetStopMethod("stopTheSingleton");
+
+ singletonControllerTester.stopSingleton();
+
+ assertEquals("method not invoked as expected",
+ singletonControllerTester.__invokationStack__.pop(), "invokeMBeanMethod:jboss:service=HASingletonMBeanExample.stopTheSingleton");
+ }
+
+}
Property changes on: trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/HASingletonControllerUnitTestCase.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ native
Added: trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/HASingletonElectionPolicyTestCase.java
===================================================================
--- trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/HASingletonElectionPolicyTestCase.java (rev 0)
+++ trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/HASingletonElectionPolicyTestCase.java 2007-07-24 03:27:28 UTC (rev 64237)
@@ -0,0 +1,106 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.test.cluster.defaultcfg.test;
+
+import javax.management.ObjectName;
+
+import junit.framework.Test;
+
+import org.jboss.jmx.adaptor.rmi.RMIAdaptor;
+import org.jboss.test.JBossClusteredTestCase;
+
+/**
+ * Unit tests for HASingletonElectionPolicy.
+ * The testing deployment is under resources/ha/electionpolicy.
+ *
+ * @author <a href="mailto:Alex.Fu at novell.com">Alex Fu</a>
+ * @author Brian Stansberry
+ * @version $Revision$
+ *
+ */
+public class HASingletonElectionPolicyTestCase extends JBossClusteredTestCase
+{
+ public HASingletonElectionPolicyTestCase(String name)
+ {
+ super(name);
+ }
+
+ public static Test suite() throws Exception
+ {
+ // Refer to jboss-service.xml under resources/ha/electionpolicy
+ return getDeploySetup(HASingletonElectionPolicyTestCase.class, "ha-electionpolicy-beans.xml");
+ }
+
+ public void testElectionPolicy() throws Exception
+ {
+ // Get MBeanServerConnections
+ RMIAdaptor[] adaptors = this.getAdaptors();
+ int size = adaptors.length;
+ assertTrue(size == 2); // cluster size must be 2 for 3rd policy test
+
+ // First policy is to elect the oldest node (position = 0)
+ {
+ ObjectName mbean = new ObjectName("jboss.examples:service=HASingletonMBeanExample_1");
+
+ Boolean n1 = (Boolean)adaptors[0].getAttribute(mbean, "MasterNode");
+ Boolean n2 = (Boolean)adaptors[size - 1].getAttribute(mbean, "MasterNode");
+
+ assertEquals(Boolean.TRUE, n1);
+ assertEquals(Boolean.FALSE, n2);
+ }
+
+ // Second policy is the youngest (position = -1)
+ {
+ ObjectName mbean = new ObjectName("jboss.examples:service=HASingletonMBeanExample_2");
+
+ Boolean n1 = (Boolean)adaptors[0].getAttribute(mbean, "MasterNode");
+ Boolean n2 = (Boolean)adaptors[size - 1].getAttribute(mbean, "MasterNode");
+
+ assertEquals(Boolean.FALSE, n1);
+ assertEquals(Boolean.TRUE, n2);
+ }
+
+ // 3rd policy is the 2nd oldest (position = 1)
+ {
+ ObjectName mbean = new ObjectName("jboss.examples:service=HASingletonMBeanExample_3");
+
+ Boolean n1 = (Boolean)adaptors[0].getAttribute(mbean, "MasterNode");
+ Boolean n2 = (Boolean)adaptors[1].getAttribute(mbean, "MasterNode");
+
+ assertEquals(Boolean.FALSE, n1);
+ assertEquals(Boolean.TRUE, n2);
+ }
+
+ // 4th policy is not set, default is oldest
+ {
+ ObjectName mbean = new ObjectName("jboss.examples:service=HASingletonMBeanExample_4");
+
+ Boolean n1 = (Boolean)adaptors[0].getAttribute(mbean, "MasterNode");
+ Boolean n2 = (Boolean)adaptors[size - 1].getAttribute(mbean, "MasterNode");
+
+ assertEquals(Boolean.TRUE, n1);
+ assertEquals(Boolean.FALSE, n2);
+ }
+
+ return;
+ }
+}
Property changes on: trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/HASingletonElectionPolicyTestCase.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ native
Added: trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/HASingletonSupportUnitTestCase.java
===================================================================
--- trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/HASingletonSupportUnitTestCase.java (rev 0)
+++ trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/HASingletonSupportUnitTestCase.java 2007-07-24 03:27:28 UTC (rev 64237)
@@ -0,0 +1,150 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.test.cluster.defaultcfg.test;
+
+import java.util.ArrayList;
+
+import junit.framework.TestCase;
+
+import org.jboss.test.cluster.hasingleton.HASingletonSupportTester;
+
+
+public class HASingletonSupportUnitTestCase extends TestCase
+{
+
+ private HASingletonSupportTester singletonSupportTester = null;
+
+ public HASingletonSupportUnitTestCase(String testCaseName)
+ {
+ super(testCaseName);
+ }
+
+
+ public void setUp()
+ {
+ singletonSupportTester = new HASingletonSupportTester();
+ }
+
+ public void tearDown()
+ {
+ singletonSupportTester = null;
+ }
+
+ public void testStartService() throws Exception
+ {
+ singletonSupportTester.start();
+
+ // test that the correct start sequence was followed correctly
+ assertEquals("method not invoked as expected",
+ singletonSupportTester.__invokationStack__.pop(), "registerDRMListener");
+ assertEquals("method not invoked as expected",
+ singletonSupportTester.__invokationStack__.pop(), "registerRPCHandler");
+ assertEquals("method not invoked as expected",
+ singletonSupportTester.__invokationStack__.pop(), "setupPartition");
+
+ }
+
+ public void testStopService() throws Exception
+ {
+ singletonSupportTester.start();
+ singletonSupportTester.stop();
+
+ assertEquals("method not invoked as expected",
+ singletonSupportTester.__invokationStack__.pop(), "unregisterRPCHandler");
+ assertEquals("method not invoked as expected",
+ singletonSupportTester.__invokationStack__.pop(), "unregisterDRMListener");
+
+ }
+
+ public void testBecomeMasterNode() throws Exception
+ {
+ singletonSupportTester.start();
+
+ // register DRM Listener is expected to call back
+ singletonSupportTester.__isDRMMasterReplica__ = true;
+ singletonSupportTester.partitionTopologyChanged( new ArrayList(2), 1);
+
+ // test whether it was elected
+ assertTrue("expected to become master", singletonSupportTester.isMasterNode());
+
+ // test whether the election sequence was followed correctly
+ assertEquals("method not invoked as expected",
+ singletonSupportTester.__invokationStack__.pop(), "startSingleton");
+ //assertEquals("method not invoked as expected",
+ // singletonSupportTester.__invokationStack__.pop(), "callMethodOnCluster:_stopOldMaster");
+ assertEquals("method not invoked as expected",
+ singletonSupportTester.__invokationStack__.pop(), "makeThisNodeMaster");
+ }
+
+ public void testBecomeSlaveNodeWithAnotherMaster() throws Exception
+ {
+ singletonSupportTester.start();
+
+ boolean savedIsMasterNode = singletonSupportTester.isMasterNode();
+
+ // register DRM Listener is expected to call back
+ singletonSupportTester.__isDRMMasterReplica__ = false;
+ singletonSupportTester.partitionTopologyChanged(new ArrayList(2), 1);
+
+ // this call back should not change the master/slave status
+ assertEquals("expected to be still in old master/slave state", singletonSupportTester.isMasterNode(), savedIsMasterNode );
+
+ // the new master is expected to call back
+ singletonSupportTester._stopOldMaster();
+
+ if (savedIsMasterNode)
+ {
+ assertEquals("this node was the old master, but method not invoked as expected",
+ singletonSupportTester.__invokationStack__.pop(), "stopSingleton");
+ }
+
+ // now it should be slave
+ assertTrue("expected to be slave", !singletonSupportTester.isMasterNode());
+
+ }
+
+ public void testStopOnlyNode() throws Exception
+ {
+ singletonSupportTester.start();
+
+ // register DRM Listener is expected to call back
+ singletonSupportTester.__isDRMMasterReplica__ = true;
+ singletonSupportTester.partitionTopologyChanged( new ArrayList(2), 1);
+
+ // test whether it was elected for master
+ assertTrue("expected to become master", singletonSupportTester.isMasterNode());
+
+ singletonSupportTester.stop();
+
+ // register DRM Listener is expected to call back
+ singletonSupportTester.__isDRMMasterReplica__ = false;
+ // since the only node (this one) in the partition is now removed, the replicants list should be empty
+ singletonSupportTester.partitionTopologyChanged(new ArrayList(0), 1);
+
+ assertTrue("expected to have made a call to _stopOldMater(), thus become slave", !singletonSupportTester.isMasterNode() );
+
+ assertEquals("method not invoked as expected",
+ singletonSupportTester.__invokationStack__.pop(), "stopSingleton");
+
+ }
+
+}
Property changes on: trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/HASingletonSupportUnitTestCase.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ native
Added: trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/PartitionRestartUnitTestCase.java
===================================================================
--- trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/PartitionRestartUnitTestCase.java (rev 0)
+++ trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/PartitionRestartUnitTestCase.java 2007-07-24 03:27:28 UTC (rev 64237)
@@ -0,0 +1,143 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+
+package org.jboss.test.cluster.defaultcfg.test;
+
+import java.util.Properties;
+
+import javax.management.ObjectName;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+
+import junit.framework.Test;
+
+import org.jboss.jmx.adaptor.rmi.RMIAdaptor;
+import org.jboss.test.JBossClusteredTestCase;
+import org.jboss.test.cluster.ejb2.basic.interfaces.NodeAnswer;
+import org.jboss.test.cluster.ejb2.basic.interfaces.StatefulSession;
+import org.jboss.test.testbean.interfaces.StatefulSessionHome;
+
+/**
+ * Tests that a restart of ClusterPartition works properly.
+ *
+ * @author <a href="mailto://brian.stansberry@jboss.com">Brian Stansberry</a>
+ * @version $Revision$
+ */
+public class PartitionRestartUnitTestCase extends JBossClusteredTestCase
+{
+ /**
+ * Create a new PartitionRestartUnitTestCase.
+ *
+ * @param name
+ */
+ public PartitionRestartUnitTestCase(String name)
+ {
+ super(name);
+ }
+
+ public static Test suite() throws Exception
+ {
+ Test t1 = JBossClusteredTestCase.getDeploySetup(PartitionRestartUnitTestCase.class, "partition-restart-beans.xml, partition-restart.jar");
+ return t1;
+ }
+
+ public void testStatefulBeanFailover()
+ throws Exception
+ {
+ getLog().debug("testStatefulBeanFailover");
+
+ RMIAdaptor[] adaptors = this.getAdaptors();
+
+ String[] urls = getNamingURLs();
+ Properties env = new Properties();
+ env.setProperty(Context.INITIAL_CONTEXT_FACTORY,
+ "org.jnp.interfaces.NamingContextFactory");
+ env.setProperty(Context.PROVIDER_URL, urls[0]);
+ Context ctx = new InitialContext(env);
+ getLog().debug("OK");
+
+ getLog().debug("");
+ getLog().debug("Looking up the home nextgen.StatefulSession...");
+ StatefulSessionHome statefulSessionHome =
+ (StatefulSessionHome) ctx.lookup("nextgen_StatefulSession");
+ if (statefulSessionHome!= null ) getLog().debug("ok");
+ getLog().debug("Calling create on StatefulSessionHome...");
+ StatefulSession statefulSession =
+ (StatefulSession)statefulSessionHome.create("Bupple-Dupple");
+ assertTrue("statefulSessionHome.create() != null", statefulSession != null);
+ getLog().debug("ok");
+
+ NodeAnswer node1 = statefulSession.getNodeState ();
+ getLog ().debug (node1);
+
+ // Now we switch to the other node, simulating a failure on node 1
+ //
+ System.setProperty ("JBossCluster-DoFail", "once");
+ NodeAnswer node2 = statefulSession.getNodeState ();
+ getLog ().debug (node2);
+
+ assertTrue ("Failover has occured", !node1.nodeId.equals (node2.nodeId));
+
+ assertTrue ("Value is identical on replicated node",
+ "Bupple-Dupple".equals (node1.answer) &&
+ node1.answer.equals (node2.answer) );
+
+ // Stop and restart the ClusterPartition on node1
+ restartPartition(adaptors[0]);
+
+ // Let the cluster stabilize
+ sleep(2000);
+
+ // we change our name to see if it replicates to node 1
+ //
+ statefulSession.setName ("Changed");
+
+ // now we travel back to node 1
+ System.setProperty ("JBossCluster-DoFail", "once");
+ node1 = statefulSession.getNodeState ();
+ getLog ().debug (node1);
+
+ assertTrue ("Failover has occured", !node1.nodeId.equals (node2.nodeId));
+
+ assertTrue ("Value is identical on replicated node", "Changed".equals (node1.answer) );
+
+ statefulSession.remove();
+ getLog().debug("ok");
+ }
+
+
+ protected void restartPartition(RMIAdaptor adaptor) throws Exception
+ {
+ ObjectName partition = new ObjectName("jboss:service=RestartPartition");
+
+ Object[] params = new Object[0];
+ String[] types = new String[0];
+ adaptor.invoke(partition, "stop", params, types);
+
+ sleep(2000);
+
+ adaptor.invoke(partition, "start", params, types);
+
+ sleep(2000);
+ }
+
+}
Property changes on: trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/PartitionRestartUnitTestCase.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ native
Added: trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/RPCTestCase.java
===================================================================
--- trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/RPCTestCase.java (rev 0)
+++ trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/RPCTestCase.java 2007-07-24 03:27:28 UTC (rev 64237)
@@ -0,0 +1,316 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2007, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.test.cluster.defaultcfg.test;
+
+import java.util.ArrayList;
+import javax.management.ObjectName;
+
+import junit.framework.Test;
+
+import org.jboss.jmx.adaptor.rmi.RMIAdaptor;
+import org.jboss.jmx.adaptor.rmi.RMIAdaptorExt;
+import org.jboss.test.JBossClusteredTestCase;
+import org.jboss.test.cluster.hapartition.rpc.Person;
+import org.jboss.test.cluster.hapartition.rpc.PersonQuery;
+
+/** Tests of clustered RPC calls
+ *
+ * @author Jerry Gauthier
+ * @version $Revision$
+ */
+public class RPCTestCase extends JBossClusteredTestCase
+{
+ // must match service names in rpc-tests.sar
+ private static final String RPC_SERVICE = "jboss.test:service=RPCTestCase";
+ private static final String RPC_ONENODE_SERVICE = "jboss.test:service=RPCOneNodeTestCase";
+ private static final String RPC_CLASSLOADER_SERVICE = "jboss.test:service=RPCClassLoaderTestCase";
+ private static final String RPC_ONENODE_CLASSLOADER_SERVICE = "jboss.test:service=RPCOneNodeClassLoaderTestCase";
+
+ public static Test suite() throws Exception
+ {
+ Test t1 = getDeploySetup(RPCTestCase.class, "rpc-tests.sar, rpc-cl-tests.sar");
+ return t1;
+ }
+
+ public RPCTestCase(String name)
+ {
+ super(name);
+ }
+
+ public void testMethodOnCluster() throws Exception
+ {
+ log.debug("+++ testMethodOnCluster");
+
+ RMIAdaptor[] adaptors = getAdaptors();
+ RMIAdaptorExt server0 = (RMIAdaptorExt) adaptors[0];
+ ObjectName rpcService = new ObjectName(RPC_SERVICE);
+
+ Object obj0 = server0.invoke(rpcService, "runRetrieveAll", null, null);
+ assertNotNull("expected ArrayList as result type, got null", obj0);
+ assertTrue( "expected ArrayList as result type, got " +obj0.getClass().getName(), obj0 instanceof ArrayList);
+ ArrayList responses = (ArrayList)obj0;
+
+ // there should be two Person responses, the attributes should differ
+ assertEquals("Result should contain two responses; ", 2, responses.size());
+ for (int i = 0; i < responses.size(); i++)
+ {
+ Object response = responses.get(i);
+ if (response instanceof Exception)
+ fail("received exception response: " + ((Exception)response).toString());
+ assertTrue("expected Person as response type, got " +response.getClass().getName(), response instanceof Person);
+ }
+ Person person0 = (Person)responses.get(0);
+ Person person1 = (Person)responses.get(1);
+ assertFalse("expected different person names, got " + person0.getName(),
+ person0.getName().equals(person1.getName()));
+
+ }
+
+ public void testParmMethodOnCluster() throws Exception
+ {
+ log.debug("+++ testParmMethodOnCluster");
+
+ RMIAdaptor[] adaptors = getAdaptors();
+ RMIAdaptorExt server1 = (RMIAdaptorExt) adaptors[1];
+ ObjectName rpcService = new ObjectName(RPC_SERVICE);
+
+ // try using a custom class as parameter
+ String employer = "WidgetsRUs";
+ PersonQuery query = new PersonQuery();
+ query.setEmployer(employer);
+ Object[] parms = new Object[]{query};
+ String[] types = new String[]{PersonQuery.class.getName()};
+
+ Object obj1 = server1.invoke(rpcService, "runRetrieveQuery", parms, types);
+ assertNotNull("expected ArrayList as result type, got null", obj1);
+ assertTrue( "expected ArrayList as result type, got " +obj1.getClass().getName(), obj1 instanceof ArrayList);
+ ArrayList responses = (ArrayList)obj1;
+
+ // there should be two responses, a Person and a null value
+ assertEquals("Result should contain two responses; ", 2, responses.size());
+ for (int i = 0; i < responses.size(); i++)
+ {
+ Object response = responses.get(i);
+ if (response instanceof Exception)
+ fail("received exception response: " + ((Exception)response).toString());
+ if (response != null)
+ {
+ assertTrue("expected Person as response type, got " +response.getClass().getName(), response instanceof Person);
+ String respEmpl = ((Person)response).getEmployer();
+ assertTrue("expected " + employer + " as selected response value, got " + respEmpl,
+ (employer.equalsIgnoreCase(respEmpl)));
+ }
+ }
+
+ }
+
+ public void testAsynchMethodOnCluster() throws Exception
+ {
+ log.debug("+++ testAsynchMethodOnCluster");
+
+ RMIAdaptor[] adaptors = getAdaptors();
+ RMIAdaptorExt server0 = (RMIAdaptorExt) adaptors[0];
+ RMIAdaptorExt server1 = (RMIAdaptorExt) adaptors[1];
+ ObjectName rpcService = new ObjectName(RPC_SERVICE);
+
+ // this will set the 'notified' attribute to true for all Person objects in RPCUser
+ server0.invoke(rpcService, "runNotifyAllAsynch", null, null);
+ Thread.sleep(5000);
+
+ // confirm the attribute has been set successfully on each node
+ Object obj1 = server1.invoke(rpcService, "runRetrieveAll", null, null);
+ assertNotNull("expected ArrayList as result type, got null", obj1);
+ assertTrue( "expected ArrayList as result type, got " +obj1.getClass().getName(), obj1 instanceof ArrayList);
+ ArrayList responses = (ArrayList)obj1;
+
+ // there should be two Person responses, the 'notified' attribute should be true
+ assertEquals("Result should contain two responses; ", 2, responses.size());
+ for (int i = 0; i < responses.size(); i++)
+ {
+ Object response = responses.get(i);
+ if (response instanceof Exception)
+ fail("received exception response: " + ((Exception)response).toString());
+ assertTrue("expected Person as response type, got " +response.getClass().getName(), response instanceof Person);
+ Person person = (Person)response;
+ assertTrue("expected true as response value, got false for " + person.getName(),
+ (person.getNotified() == true));
+
+ }
+ }
+
+ public void testMethodOnCoordinatorNode() throws Exception
+ {
+ log.debug("+++ testMethodOnCoordinatorNode");
+
+ RMIAdaptor[] adaptors = getAdaptors();
+ RMIAdaptorExt server0 = (RMIAdaptorExt) adaptors[0];
+ ObjectName rpcService = new ObjectName(RPC_SERVICE);
+
+ Object obj0 = server0.invoke(rpcService, "runRetrieveFromCoordinator", null, null);
+ assertNotNull("expected ArrayList as result type, got null", obj0);
+ assertTrue( "expected ArrayList as result type, got " +obj0.getClass().getName(), obj0 instanceof ArrayList);
+ ArrayList responses = (ArrayList)obj0;
+
+ // there should be one Person response
+ assertEquals("Result should contain one response; ", 1, responses.size());
+ Object response = responses.get(0);
+ if (response instanceof Exception)
+ fail("received exception response: " + ((Exception)response).toString());
+ assertTrue("expected Person as response type, got " +response.getClass().getName(), response instanceof Person);
+
+ String employer = "WidgetsRUs";
+ String respEmpl = ((Person)response).getEmployer();
+ assertTrue("expected " + employer + " as selected response value, got " + respEmpl,
+ (employer.equalsIgnoreCase(respEmpl)));
+ }
+
+ public void testMethodOnOneNode() throws Exception
+ {
+ log.debug("+++ testMethodOnOneNode");
+
+ RMIAdaptor[] adaptors = getAdaptors();
+ RMIAdaptorExt server0 = (RMIAdaptorExt) adaptors[0];
+ ObjectName rpcService = new ObjectName(RPC_ONENODE_SERVICE);
+
+ Object obj0 = server0.invoke(rpcService, "runRetrieveAll", null, null);
+ assertNotNull("expected ArrayList as result type, got null", obj0);
+ assertTrue( "expected ArrayList as result type, got " +obj0.getClass().getName(), obj0 instanceof ArrayList);
+ ArrayList responses = (ArrayList)obj0;
+
+ // there should be one response as the service is only registered on one node
+ assertEquals("Result should contain one response; ", 1, responses.size());
+ for (int i = 0; i < responses.size(); i++)
+ {
+ Object response = responses.get(i);
+ if (response instanceof Exception)
+ fail("received exception response: " + ((Exception)response).toString());
+ assertTrue("expected Person as response type, got " +response.getClass().getName(), response instanceof Person);
+ }
+
+ }
+
+ public void testClassLoaderParmMethodOnOneNode() throws Exception
+ {
+ log.debug("+++ testClassLoaderParmMethodOnOneNode");
+
+ RMIAdaptor[] adaptors = getAdaptors();
+ RMIAdaptorExt server1 = (RMIAdaptorExt) adaptors[1];
+ ObjectName rpcService = new ObjectName(RPC_ONENODE_CLASSLOADER_SERVICE);
+
+ // try using a custom class as parameter
+ String employer = "WidgetsRUs";
+ PersonQuery query = new PersonQuery();
+ query.setEmployer(employer);
+ Object[] parms = new Object[]{query};
+ String[] types = new String[]{PersonQuery.class.getName()};
+
+ Object obj1 = server1.invoke(rpcService, "runRetrieveQuery", parms, types);
+ assertNotNull("expected ArrayList as result type, got null", obj1);
+ assertTrue( "expected ArrayList as result type, got " +obj1.getClass().getName(), obj1 instanceof ArrayList);
+ ArrayList responses = (ArrayList)obj1;
+
+ // there should be one response as the service is only registered on one node
+ assertEquals("Result should contain one response; ", 1, responses.size());
+ for (int i = 0; i < responses.size(); i++)
+ {
+ Object response = responses.get(i);
+ if (response instanceof Exception)
+ fail("received exception response: " + ((Exception)response).toString());
+ if (response != null)
+ {
+ assertTrue("expected Person as response type, got " +response.getClass().getName(), response instanceof Person);
+ String respEmpl = ((Person)response).getEmployer();
+ assertTrue("expected " + employer + " as selected response value, got " + respEmpl,
+ (employer.equalsIgnoreCase(respEmpl)));
+ }
+ }
+
+ }
+
+ public void testClassLoaderParmMethodOnCluster() throws Exception
+ {
+ log.debug("+++ testClassLoaderParmMethodOnCluster");
+
+ RMIAdaptor[] adaptors = getAdaptors();
+ RMIAdaptorExt server1 = (RMIAdaptorExt) adaptors[1];
+ ObjectName rpcService = new ObjectName(RPC_CLASSLOADER_SERVICE);
+
+ // try using a custom class as parameter
+ String employer = "WidgetsRUs";
+ PersonQuery query = new PersonQuery();
+ query.setEmployer(employer);
+ Object[] parms = new Object[]{query};
+ String[] types = new String[]{PersonQuery.class.getName()};
+
+ Object obj1 = server1.invoke(rpcService, "runRetrieveQuery", parms, types);
+ assertNotNull("expected ArrayList as result type, got null", obj1);
+ assertTrue( "expected ArrayList as result type, got " +obj1.getClass().getName(), obj1 instanceof ArrayList);
+ ArrayList responses = (ArrayList)obj1;
+
+ // there should be two responses, a Person and a null value
+ assertEquals("Result should contain two responses; ", 2, responses.size());
+ for (int i = 0; i < responses.size(); i++)
+ {
+ Object response = responses.get(i);
+ if (response instanceof Exception)
+ fail("received exception response: " + ((Exception)response).toString());
+ if (response != null)
+ {
+ assertTrue("expected Person as response type, got " +response.getClass().getName(), response instanceof Person);
+ String respEmpl = ((Person)response).getEmployer();
+ assertTrue("expected " + employer + " as selected response value, got " + respEmpl,
+ (employer.equalsIgnoreCase(respEmpl)));
+ }
+ }
+
+ }
+
+ public void testClassLoaderMethodOnCluster() throws Exception
+ {
+ log.debug("+++ testClassLoaderMethodOnCluster");
+
+ RMIAdaptor[] adaptors = getAdaptors();
+ RMIAdaptorExt server0 = (RMIAdaptorExt) adaptors[0];
+ ObjectName rpcService = new ObjectName(RPC_CLASSLOADER_SERVICE);
+
+ Object obj0 = server0.invoke(rpcService, "runRetrieveAll", null, null);
+ assertNotNull("expected ArrayList as result type, got null", obj0);
+ assertTrue( "expected ArrayList as result type, got " +obj0.getClass().getName(), obj0 instanceof ArrayList);
+ ArrayList responses = (ArrayList)obj0;
+
+ // there should be two Person responses, the attributes should differ
+ assertEquals("Result should contain two responses; ", 2, responses.size());
+ for (int i = 0; i < responses.size(); i++)
+ {
+ Object response = responses.get(i);
+ if (response instanceof Exception)
+ fail("received exception response: " + ((Exception)response).toString());
+ assertTrue("expected Person as response type, got " +response.getClass().getName(), response instanceof Person);
+ }
+ Person person0 = (Person)responses.get(0);
+ Person person1 = (Person)responses.get(1);
+ assertFalse("expected different person names, got " + person0.getName(),
+ person0.getName().equals(person1.getName()));
+
+ }
+
+}
Property changes on: trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/test/RPCTestCase.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ native
More information about the jboss-cvs-commits
mailing list