[jboss-cvs] JBossAS SVN: r66971 - trunk/testsuite/src/main/org/jboss/test/cluster/invokerha.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Mon Nov 12 14:10:13 EST 2007
Author: galder.zamarreno at jboss.com
Date: 2007-11-12 14:10:13 -0500 (Mon, 12 Nov 2007)
New Revision: 66971
Added:
trunk/testsuite/src/main/org/jboss/test/cluster/invokerha/AbstractInvokerHaUnitTestCase.java
trunk/testsuite/src/main/org/jboss/test/cluster/invokerha/InvokerHaInfrastructure.java
trunk/testsuite/src/main/org/jboss/test/cluster/invokerha/InvokerHaTransactionalMockUtils.java
trunk/testsuite/src/main/org/jboss/test/cluster/invokerha/UnifiedInvokerHaMockUtils.java
trunk/testsuite/src/main/org/jboss/test/cluster/invokerha/UnifiedInvokerHaUnitTestCase.java
Log:
[JBAS-4950] Standalone unit tests created for invokers in general and particularly for unified invokers as well as some helper classes for mocking purpouses.
Added: trunk/testsuite/src/main/org/jboss/test/cluster/invokerha/AbstractInvokerHaUnitTestCase.java
===================================================================
--- trunk/testsuite/src/main/org/jboss/test/cluster/invokerha/AbstractInvokerHaUnitTestCase.java (rev 0)
+++ trunk/testsuite/src/main/org/jboss/test/cluster/invokerha/AbstractInvokerHaUnitTestCase.java 2007-11-12 19:10:13 UTC (rev 66971)
@@ -0,0 +1,192 @@
+/*
+ * 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.invokerha;
+
+import java.rmi.server.UID;
+import java.util.WeakHashMap;
+
+import javax.transaction.Transaction;
+
+import org.jboss.ha.framework.interfaces.LoadBalancePolicy;
+import org.jboss.invocation.Invocation;
+import org.jboss.invocation.Invoker;
+import org.jboss.logging.Logger;
+import org.jboss.test.cluster.invokerha.InvokerHaInfrastructure.InvokerHaFactory;
+import org.jboss.test.cluster.invokerha.InvokerHaInfrastructure.TraceRoundRobin;
+import org.jboss.test.cluster.invokerha.InvokerHaTransactionalMockUtils.MockTransaction;
+
+import junit.framework.TestCase;
+
+/**
+ * Base class for invoker related tests that do not run within AS.
+ *
+ * @author <a href="mailto:galder.zamarreno at jboss.com">Galder Zamarreno</a>
+ */
+public abstract class AbstractInvokerHaUnitTestCase extends TestCase
+{
+ private static final Logger log = Logger.getLogger(AbstractInvokerHaUnitTestCase.class);
+
+ protected InvokerHaInfrastructure infrastructure;
+
+ protected InvokerHaTransactionalMockUtils transactionalMockUtils;
+
+ protected void setUp(int serverCount, InvokerHaFactory invokerHaFactory) throws Exception
+ {
+ super.setUp();
+
+ transactionalMockUtils = new InvokerHaTransactionalMockUtils();
+
+ infrastructure = invokerHaFactory.getInvokerHaInfrastructure(2);
+
+ infrastructure.registerManagedObjects();
+
+ infrastructure.deployServers();
+
+ infrastructure.createDateTimeTeller();
+ infrastructure.createSystemTimeTeller();
+
+ infrastructure.deployDateTimeTeller();
+ infrastructure.deploySystemTimeTeller();
+ }
+
+ @Override
+ protected void tearDown() throws Exception
+ {
+ super.tearDown();
+
+ infrastructure.unregisterManagedObjects();
+
+ infrastructure.undeployDateTimeTeller();
+ infrastructure.undeploySystemTimeTeller();
+
+ infrastructure.undeployServers();
+ }
+
+ protected InvokerHaInfrastructure createInvokerHaInfrastructure(int serverCount, InvokerHaFactory invokerHaFactory)
+ {
+ return new InvokerHaInfrastructure(serverCount, invokerHaFactory);
+ }
+
+ protected void successfulCalls(Class<? extends LoadBalancePolicy> policyClass, WeakHashMap txFailoverAuthorizations)
+ {
+ try
+ {
+ UID uid;
+
+ /* Create a proxy instances retrieved from the first server */
+ Invoker timeTellerProxy = infrastructure.createDateTimeTellerProxy(0, policyClass);
+ Invoker systemTimeProxy = infrastructure.createSystemTimeTellerProxy(0, policyClass);
+
+// Commented because tx failover maps are still mapped on tx rather than
+// transaction propagation context. Once it's keyed on tpc, these tests
+// will be enabled.
+//
+// /* Simulate client user transaction */
+// uid = new UID();
+// transactionalMockUtils.getTpcf().setUid(uid);
+// callsWithinTransaction(3, timeTellerProxy, systemTimeProxy, null, policyClass, txFailoverAuthorizations);
+//
+// if (newProxiesInBetweenTransactions)
+// {
+// timeTellerProxy = infrastructure.createDateTimeTellerProxy(0, policyClass);
+// systemTimeProxy = infrastructure.createDateTimeTellerProxy(0, policyClass);
+// }
+
+ /* Simulate transaction interceptor */
+ uid = new UID();
+ Transaction tx = new MockTransaction();
+ transactionalMockUtils.getTpcf().setUid(uid);
+ transactionalMockUtils.getTpci().setTransaction(tx);
+ callsWithinTransaction(3, timeTellerProxy, systemTimeProxy, tx, policyClass, txFailoverAuthorizations);
+ }
+ catch(Exception e)
+ {
+ /* catching to log the error properly (JUnit in eclipse does not show
+ * correctly exceptions from invokers) and fail */
+ log.error("error", e);
+ fail();
+ }
+ }
+
+ protected void callsWithinTransaction(int numberPairCalls,
+ Invoker timeTellerProxy,
+ Invoker systemTimeProxy,
+ Transaction tx,
+ Class<? extends LoadBalancePolicy> policyClass,
+ WeakHashMap txFailoverAuthorizations) throws Exception
+ {
+ Invocation inv;
+ Object chosenTarget;
+ Object prevChosenTargetDateTimeTeller = null;
+ Object prevChosenTargetSystemTimeTeller = null;
+
+ for (int i = 0; i < numberPairCalls; i++)
+ {
+ /* create invocation to date time teller */
+ inv = infrastructure.createDateTimeTellerInvocation(tx);
+ /* invoke on proxy passing the invocation */
+ log.debug(timeTellerProxy.invoke(inv));
+
+ assertEquals(0, inv.getAsIsValue("FAILOVER_COUNTER"));
+ chosenTarget = inv.getTransientValue("TEST_CHOSEN_TARGET");
+ assertNotNull(chosenTarget);
+ /* if tx was null, invocation's tx should be null after invocation. */
+ assertEquals(tx, inv.getTransaction());
+ /* check chosen target with previously chosen target, if there's any */
+ if (policyClass.equals(TraceRoundRobin.class))
+ {
+ prevChosenTargetDateTimeTeller = checkRoundRobin(i, chosenTarget, prevChosenTargetDateTimeTeller);
+ }
+
+ assertTrue("transaction should have reached the server", txFailoverAuthorizations.containsKey(tx));
+
+ /* create invocation to system time teller */
+ inv = infrastructure.createSystemTimeTellerInvocation(tx);
+ log.debug(systemTimeProxy.invoke(inv));
+
+ assertEquals(0, inv.getAsIsValue("FAILOVER_COUNTER"));
+ chosenTarget = inv.getTransientValue("TEST_CHOSEN_TARGET");
+ assertNotNull(chosenTarget);
+ assertEquals(tx, inv.getTransaction());
+ if (policyClass.equals(TraceRoundRobin.class))
+ {
+ prevChosenTargetSystemTimeTeller = checkRoundRobin(i, chosenTarget, prevChosenTargetSystemTimeTeller);
+ }
+ assertTrue("transaction should have reached the server", txFailoverAuthorizations.containsKey(tx));
+
+ }
+ }
+
+ protected Object checkRoundRobin(int callIndex, Object chosenTarget, Object prevChosenTarget)
+ {
+ if (callIndex != 0)
+ {
+ /* in round robin, previous chosen target must be different to the
+ * current one, unless there's only one node in the cluster, but we're
+ * not testing that here. */
+ assertNotSame(prevChosenTarget, chosenTarget);
+ }
+
+ return chosenTarget;
+ }
+
+}
Added: trunk/testsuite/src/main/org/jboss/test/cluster/invokerha/InvokerHaInfrastructure.java
===================================================================
--- trunk/testsuite/src/main/org/jboss/test/cluster/invokerha/InvokerHaInfrastructure.java (rev 0)
+++ trunk/testsuite/src/main/org/jboss/test/cluster/invokerha/InvokerHaInfrastructure.java 2007-11-12 19:10:13 UTC (rev 66971)
@@ -0,0 +1,490 @@
+/*
+ * 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.invokerha;
+
+import java.io.Serializable;
+import java.lang.management.ManagementFactory;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import javax.management.MBeanServer;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+import javax.transaction.Transaction;
+
+import org.jboss.ha.framework.interfaces.FamilyClusterInfo;
+import org.jboss.ha.framework.interfaces.HAPartition;
+import org.jboss.ha.framework.interfaces.HARMIClient;
+import org.jboss.ha.framework.interfaces.LoadBalancePolicy;
+import org.jboss.ha.framework.interfaces.RoundRobin;
+import org.jboss.ha.framework.server.HATarget;
+import org.jboss.invocation.Invocation;
+import org.jboss.invocation.Invoker;
+import org.jboss.invocation.InvokerHA;
+import org.jboss.logging.Logger;
+import org.jboss.system.Registry;
+
+/**
+ * Infrastructure class that encapsulates the simulated deployment of
+ * servers or invoker endpoints and mbeans that receive the invocations.
+ *
+ * @author <a href="mailto:galder.zamarreno at jboss.com">Galder Zamarreno</a>
+ */
+public class InvokerHaInfrastructure
+{
+ private static final Logger log = Logger.getLogger(InvokerHaInfrastructure.class);
+
+ /**
+ * MBeanServer instance. This is not gonna run in Java 1.4.x, so we can
+ * safely assume that we can use Java's MBeanServer.
+ */
+ private static final MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+
+ private InvokerHaFactory invokerHaFactory;
+
+ private final ObjectName dateTimeTellerON;
+
+ private final ObjectName systemTimeTellerON;
+
+ private final Integer dateTimeTellerONHashCode;
+
+ private final Integer systemTimeTellerONHashCode;
+
+ private final int serverCount;
+
+ private List<? extends InvokerHA> replicants;
+
+ private List<ObjectName> invokerONs;
+
+ /**
+ * Create a new InvokerHaInfrastructure.
+ *
+ * @param serverCount number of invoker endpoints to create
+ * @param invokerHaFactory invoker ha factory class implementation
+ */
+ public InvokerHaInfrastructure(int serverCount, InvokerHaFactory invokerHaFactory)
+ {
+ this.serverCount = serverCount;
+ this.invokerHaFactory = invokerHaFactory;
+
+ try
+ {
+ /* initialise ObjectNames and hashcodes */
+ dateTimeTellerON = new ObjectName("com.acme.mbeans:type=DateTimeTeller");
+ systemTimeTellerON = new ObjectName("com.acme.mbeans:type=SystemTimeTeller");
+ dateTimeTellerONHashCode = new Integer(dateTimeTellerON.hashCode());
+ systemTimeTellerONHashCode = new Integer(systemTimeTellerON.hashCode());
+
+ /* create a list of object names for the invoker endpoints */
+ invokerONs = new ArrayList<ObjectName>(this.serverCount);
+ for (int i = 0; i < serverCount; i++)
+ {
+ invokerONs.add(new ObjectName("com.acme.invokers:type=" + this.invokerHaFactory.getInvokerTypeName() + "-Server" + (i + 1)));
+ }
+ }
+ catch (MalformedObjectNameException mone)
+ {
+ throw new IllegalArgumentException("invalid object name", mone);
+ }
+ }
+
+ /**
+ * Binds ObjectName hash code with the ObjectName which is used by the
+ * invoker. We just do it once cos both servers are in the same VM.
+ */
+ public void registerManagedObjects()
+ {
+ Registry.bind(dateTimeTellerONHashCode, dateTimeTellerON);
+ Registry.bind(systemTimeTellerONHashCode, systemTimeTellerON);
+ }
+
+ /**
+ * Create a list of invoker ha instances, called the replicants, and
+ * register the list with the mbean server.
+ */
+ public void deployServers() throws Exception
+ {
+ List<InvokerHA> replicantServers = new ArrayList<InvokerHA>(serverCount);
+
+ /* create n invoker instances that emulate n AS servers */
+ for (int i =0; i < serverCount; i++)
+ {
+ InvokerHA server = invokerHaFactory.createInvokerHAServer("Server", i + 1);
+ /* add invoker as replicant */
+ replicantServers.add(server);
+
+ System.out.println(i);
+
+ mbs.registerMBean(server, invokerONs.get(i));
+ }
+
+ replicants = replicantServers;
+ }
+
+ /**
+ * Create new instance of DateTimeTeller and register it with the
+ * MBeanServer. Note that a single instance is created and both server
+ * invokers point to this instance behind the scenes. This simplifies
+ * testing.
+ */
+ public DateTimeTeller createDateTimeTeller() throws Exception
+ {
+ DateTimeTeller dateTimeTellerMBean = new DateTimeTeller();
+ mbs.registerMBean(dateTimeTellerMBean, dateTimeTellerON);
+ return dateTimeTellerMBean;
+ }
+
+ /**
+ * Create new instance of SystemTimeTeller and register it with the
+ * MBeanServer. Note that a single instance is created and both server
+ * invokers point to this instance behind the scenes. This simplifies
+ * testing.
+ */
+ public SystemTimeTeller createSystemTimeTeller() throws Exception
+ {
+ SystemTimeTeller systemTimeTellerMBean = new SystemTimeTeller();
+ mbs.registerMBean(systemTimeTellerMBean, systemTimeTellerON);
+ return systemTimeTellerMBean;
+ }
+
+ /**
+ * Deploy date time teller mbean in each server, or invoker endpoint,
+ * creating a mock HATarget with the list of replicants and associating the
+ * mbean's object name with the HATarget instance.
+ */
+ public void deployDateTimeTeller() throws Exception
+ {
+ deploy(replicants, dateTimeTellerON, "DateTimeTellerReplicant");
+ }
+
+ /**
+ * Deploy system time teller mbean in each server, or invoker endpoint,
+ * creating a mock HATarget with the list of replicants and associating the
+ * mbean's object name with the HATarget instance.
+ */
+ public void deploySystemTimeTeller() throws Exception
+ {
+ deploy(replicants, systemTimeTellerON, "SystemTimeTellerReplicant");
+ }
+
+ /**
+ * Create a proxy to date time teller bean.
+ *
+ * @param serverIndex invoker endpoint from which to return the proxy
+ * @param policyClass load balance policy to use in the proxy
+ * @return
+ * @throws Exception
+ */
+ public Invoker createDateTimeTellerProxy(int serverIndex, Class<? extends LoadBalancePolicy> policyClass) throws Exception
+ {
+ InvokerHA server = replicants.get(serverIndex);
+ return server.createProxy(dateTimeTellerON, policyClass.newInstance(), "UnitTestPartition/DateTimeTellerMBean");
+ }
+
+ /**
+ * Create a proxy to system time teller bean.
+ *
+ * @param serverIndex invoker endpoint from which to return the proxy
+ * @param policyClass load balance policy to use in the proxy
+ * @return
+ * @throws Exception
+ */
+ public Invoker createSystemTimeTellerProxy(int serverIndex, Class<? extends LoadBalancePolicy> policyClass) throws Exception
+ {
+ InvokerHA server = replicants.get(serverIndex);
+ return server.createProxy(systemTimeTellerON, policyClass.newInstance(), "UnitTestPartition/SystemTimeTellerMBean");
+ }
+
+ /**
+ * Create a new invocation for date time teller mbean
+ *
+ * @param tx instance of Transaction. If tx is null, transaction is not
+ * added to invocation, which is useful to replicate transactions starting
+ * in non managed environments.
+ * @return
+ */
+ public Invocation createDateTimeTellerInvocation(Transaction tx)
+ {
+ return createInvocation(tx, dateTimeTellerONHashCode);
+ }
+
+ /**
+ * Create a new invocation for system time teller mbean
+ *
+ * @param tx instance of Transaction. If tx is null, transaction is not
+ * added to invocation, which is useful to replicate transactions starting
+ * in non managed environments.
+ * @return
+ */
+ public Invocation createSystemTimeTellerInvocation(Transaction tx)
+ {
+ return createInvocation(tx, systemTimeTellerONHashCode);
+ }
+
+ /**
+ * Unbind mbean object name hashcodes from JMX registry.
+ */
+ public void unregisterManagedObjects()
+ {
+ /* Unregister from the JMX registry */
+ Registry.unbind(dateTimeTellerONHashCode);
+ Registry.unbind(systemTimeTellerONHashCode);
+ }
+
+ /**
+ * Unregister date time teller mbean object name from each invoker endpoint
+ * and from the mbean server.
+ */
+ public void undeployDateTimeTeller() throws Exception
+ {
+ undeploy(replicants, dateTimeTellerON);
+ }
+
+ /**
+ * Unregister system time teller mbean object name from each invoker endpoint
+ * and from the mbean server.
+ */
+ public void undeploySystemTimeTeller() throws Exception
+ {
+ undeploy(replicants, systemTimeTellerON);
+ }
+
+ /**
+ * Unregister invoker endpoints from mbean server.
+ */
+ public void undeployServers() throws Exception
+ {
+ for (int i = 0; i < serverCount; i++)
+ {
+ mbs.unregisterMBean(invokerONs.get(i));
+ }
+ }
+
+ /**
+ * Simulate the deployment of an mbean in a list of invoker endpoints.
+ *
+ * @param replicants list of invoker endpoints
+ * @param targetName object name of the mbean to deploy
+ * @param replicantName replicant name
+ * @throws Exception
+ */
+ protected void deploy(List<? extends InvokerHA> replicants, ObjectName targetName, String replicantName) throws Exception
+ {
+ for(InvokerHA replicant : replicants)
+ {
+ /* create ha-target in the server with the list of replicants and register
+ * it with the MBeanServer. */
+ HATarget target = new MockHATarget(null, replicantName, null, 2);
+ target.replicantsChanged(null, replicants, 0);
+ replicant.registerBean(targetName, target);
+ }
+ }
+
+ /**
+ * Simulate the undeployment of an mbean from a list of invoker endpoints.
+ *
+ * @param replicants list of invoker endpoints
+ * @param targetName object name of the mbean to deploy
+ * @throws Exception
+ */
+ protected void undeploy(List<? extends InvokerHA> replicants, ObjectName targetName) throws Exception
+ {
+ for(InvokerHA replicant : replicants)
+ {
+ replicant.unregisterBean(targetName);
+ }
+
+ mbs.unregisterMBean(targetName);
+ }
+
+ /**
+ * Create invocation with optional transaction instance for the target mbean
+ * with the given hashcode.
+ *
+ * @param tx instance of transaction
+ * @param hashCode hashcode of object name of the mbean
+ * @return
+ */
+ private Invocation createInvocation(Transaction tx, Integer hashCode)
+ {
+ Invocation inv = new Invocation();
+ inv.setObjectName(hashCode);
+ if (tx != null)
+ {
+ inv.setTransaction(tx);
+ }
+ return inv;
+ }
+
+ /** Interfaces **/
+
+ /**
+ * Factory interface to be implemented by different type of invokers
+ * available, i.e. jrmp, unified, pooled...etc.
+ */
+ public interface InvokerHaFactory
+ {
+ /**
+ * Returns the invoker type name
+ *
+ * @return String representing the invoker type
+ */
+ String getInvokerTypeName();
+
+ /**
+ * Return invoker ha instructure instance associated with this invoker.
+ *
+ * @param serverCount number of invocation endpoints, or simulated cluster nodes
+ * @return InvokerHaInfrastructure instance of infrastructure
+ */
+ InvokerHaInfrastructure getInvokerHaInfrastructure(int serverCount);
+
+ /**
+ * Creates an instance of invoker endpoint.
+ *
+ * @param serverName name of invoker endpoint
+ * @param serverNumber invoker endpoint number
+ * @return
+ */
+ InvokerHA createInvokerHAServer(String serverName, int serverNumber);
+ }
+
+ /**
+ * Date time teller mbean interface
+ */
+ public interface DateTimeTellerMBean
+ {
+ Object invoke(Invocation invocation) throws Exception;
+ }
+
+ /**
+ * Systemr time teller mbean interface
+ */
+ public interface SystemTimeTellerMBean
+ {
+ Object invoke(Invocation invocation) throws Exception;
+ }
+
+ /** Classes **/
+
+ public class DateTimeTeller implements DateTimeTellerMBean
+ {
+ public Object invoke(Invocation invocation) throws Exception
+ {
+ /* returns a Date representation of the current time */
+ return new Date(System.currentTimeMillis());
+ }
+ }
+
+ public class SystemTimeTeller implements SystemTimeTellerMBean
+ {
+ public Object invoke(Invocation invocation) throws Exception
+ {
+ /* returns a long (milliseconds) representation of the current time */
+ return System.currentTimeMillis();
+ }
+ }
+
+ /**
+ * MockHATarget class that avoids using DistributedReplicantManager in any
+ * way. The unit test will force changes in the composition of replicants,
+ * that avoids the need of replicant manager or listener.
+ */
+ public class MockHATarget extends HATarget
+ {
+ public MockHATarget(HAPartition partition, String replicantName, Serializable target, int allowInvocations) throws Exception
+ {
+ super(partition, replicantName, target, allowInvocations);
+ }
+
+ /**
+ * No-op to avoid DistributedReplicantManager being set up at within the
+ * super's constructor.
+ */
+ @Override
+ public void updateHAPartition(HAPartition partition) throws Exception
+ {
+ }
+ }
+
+ /**
+ * Load balance policy based on a delegate pattern that tracks down the
+ * chosen target for the invocation and puts it in the transient payload.
+ * This allows for UTs to inspect the content and potentially check whether
+ * load balance policies are working correctly.
+ *
+ * @author <a href="mailto:galder.zamarreno at jboss.com">Galder Zamarreno</a>
+ */
+ public static class TraceLoadBalancePolicy implements LoadBalancePolicy
+ {
+ /** The serialVersionUID */
+ private static final long serialVersionUID = 3089456214843995414L;
+
+ /** Load balance policy to delegate to */
+ private LoadBalancePolicy delegateTo;
+
+ public TraceLoadBalancePolicy(LoadBalancePolicy delegateTo)
+ {
+ this.delegateTo = delegateTo;
+ }
+
+ public Object chooseTarget(FamilyClusterInfo clusterFamily)
+ {
+ return delegateTo.chooseTarget(clusterFamily);
+ }
+
+ public Object chooseTarget(FamilyClusterInfo clusterFamily, Invocation routingDecision)
+ {
+ Object chosenTarget = delegateTo.chooseTarget(clusterFamily, routingDecision);
+
+ /* put chosen target in the transient payload */
+ routingDecision.getTransientPayload().put("TEST_CHOSEN_TARGET", chosenTarget);
+ log.debug("chosen target: " + chosenTarget);
+ return chosenTarget;
+ }
+
+ public void init(HARMIClient father)
+ {
+ delegateTo.init(father);
+ }
+ }
+
+ /**
+ * Trace load balance policy specific for round robin. This allows for non
+ * argument construction of such load balance policy, which makes it testing
+ * cleaner. We just pass the load balance policy class and we use reflection
+ * to create a new instance.
+ *
+ * @author <a href="mailto:galder.zamarreno at jboss.com">Galder Zamarreno</a>
+ */
+ public static class TraceRoundRobin extends TraceLoadBalancePolicy
+ {
+ /** The serialVersionUID */
+ private static final long serialVersionUID = -8583420254744619692L;
+
+ public TraceRoundRobin()
+ {
+ super(new RoundRobin());
+ }
+ }
+}
Added: trunk/testsuite/src/main/org/jboss/test/cluster/invokerha/InvokerHaTransactionalMockUtils.java
===================================================================
--- trunk/testsuite/src/main/org/jboss/test/cluster/invokerha/InvokerHaTransactionalMockUtils.java (rev 0)
+++ trunk/testsuite/src/main/org/jboss/test/cluster/invokerha/InvokerHaTransactionalMockUtils.java 2007-11-12 19:10:13 UTC (rev 66971)
@@ -0,0 +1,158 @@
+/*
+ * 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.invokerha;
+
+import java.rmi.server.UID;
+
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.HeuristicRollbackException;
+import javax.transaction.RollbackException;
+import javax.transaction.Synchronization;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.xa.XAResource;
+
+import org.jboss.tm.TransactionPropagationContextFactory;
+import org.jboss.tm.TransactionPropagationContextImporter;
+import org.jboss.tm.TransactionPropagationContextUtil;
+
+/**
+ * Transactional mock utils for non managed invoker ha unit tests.
+ *
+ * @author <a href="mailto:galder.zamarreno at jboss.com">Galder Zamarreno</a>
+ */
+public class InvokerHaTransactionalMockUtils
+{
+ private MockTransactionPropagationContextFactory tpcf;
+
+ private MockTransactionPropagationContextImporter tpci;
+
+ public InvokerHaTransactionalMockUtils()
+ {
+ tpcf = createTransactionPropagationContextFactory();
+ tpci = createTransactionPropagationContextImporter();
+ }
+
+ public MockTransactionPropagationContextFactory getTpcf()
+ {
+ return tpcf;
+ }
+
+ public MockTransactionPropagationContextImporter getTpci()
+ {
+ return tpci;
+ }
+
+ protected MockTransactionPropagationContextFactory createTransactionPropagationContextFactory()
+ {
+ /* Set the TPC factory so that the invoker proxy can generate a tpc */
+ MockTransactionPropagationContextFactory tpcf = new MockTransactionPropagationContextFactory();
+ TransactionPropagationContextUtil.setTPCFactory(tpcf);
+ return tpcf;
+ }
+
+ protected MockTransactionPropagationContextImporter createTransactionPropagationContextImporter()
+ {
+ MockTransactionPropagationContextImporter tpci = new MockTransactionPropagationContextImporter();
+ TransactionPropagationContextUtil.setTPCImporter(tpci);
+ return tpci;
+ }
+
+ /** Classes **/
+
+ public static class MockTransactionPropagationContextFactory implements TransactionPropagationContextFactory
+ {
+ private UID uid;
+
+ public Object getTransactionPropagationContext()
+ {
+ return uid;
+ }
+
+ public Object getTransactionPropagationContext(Transaction tx)
+ {
+ return null;
+ }
+
+ public void setUid(UID uid)
+ {
+ this.uid = uid;
+ }
+
+ public UID getUid()
+ {
+ return uid;
+ }
+ }
+
+ public static class MockTransactionPropagationContextImporter implements TransactionPropagationContextImporter
+ {
+ private Transaction transaction;
+
+ public Transaction importTransactionPropagationContext(Object tpc)
+ {
+ return transaction;
+ }
+
+ public void setTransaction(Transaction transaction)
+ {
+ this.transaction = transaction;
+ }
+ }
+
+ public static class MockTransaction implements Transaction
+ {
+ public void commit() throws RollbackException, HeuristicMixedException, HeuristicRollbackException,
+ SecurityException, SystemException
+ {
+ }
+
+ public boolean delistResource(XAResource xaRes, int flag) throws IllegalStateException, SystemException
+ {
+ return false;
+ }
+
+ public boolean enlistResource(XAResource xaRes) throws RollbackException, IllegalStateException, SystemException
+ {
+ return false;
+ }
+
+ public int getStatus() throws SystemException
+ {
+ return 0;
+ }
+
+ public void registerSynchronization(Synchronization sync) throws RollbackException, IllegalStateException,
+ SystemException
+ {
+ }
+
+ public void rollback() throws IllegalStateException, SystemException
+ {
+ }
+
+ public void setRollbackOnly() throws IllegalStateException, SystemException
+ {
+ }
+ }
+
+}
Added: trunk/testsuite/src/main/org/jboss/test/cluster/invokerha/UnifiedInvokerHaMockUtils.java
===================================================================
--- trunk/testsuite/src/main/org/jboss/test/cluster/invokerha/UnifiedInvokerHaMockUtils.java (rev 0)
+++ trunk/testsuite/src/main/org/jboss/test/cluster/invokerha/UnifiedInvokerHaMockUtils.java 2007-11-12 19:10:13 UTC (rev 66971)
@@ -0,0 +1,276 @@
+/*
+ * 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.invokerha;
+
+import java.lang.management.ManagementFactory;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import javax.management.MBeanServer;
+import javax.net.SocketFactory;
+
+import org.jboss.ha.framework.interfaces.LoadBalancePolicy;
+import org.jboss.invocation.Invocation;
+import org.jboss.invocation.Invoker;
+import org.jboss.invocation.MarshalledInvocation;
+import org.jboss.invocation.unified.interfaces.UnifiedInvokerHAProxy;
+import org.jboss.invocation.unified.server.UnifiedInvokerHA;
+import org.jboss.remoting.Client;
+import org.jboss.remoting.ConnectionFailedException;
+import org.jboss.remoting.InvocationRequest;
+import org.jboss.remoting.InvokerLocator;
+import org.jboss.remoting.ServerInvoker;
+import org.jboss.remoting.callback.InvokerCallbackHandler;
+import org.jboss.remoting.marshal.Marshaller;
+import org.jboss.remoting.marshal.UnMarshaller;
+import org.jboss.remoting.transport.ClientInvoker;
+import org.jboss.tm.TransactionPropagationContextFactory;
+import org.jboss.tm.TransactionPropagationContextUtil;
+
+/**
+ * Helper class with all remoting related mock implementations that allow
+ * direct invocations from proxy to invoker.
+ *
+ * @author <a href="mailto:galder.zamarreno at jboss.com">Galder Zamarreno</a>
+ */
+public class UnifiedInvokerHaMockUtils
+{
+ public static class MockUnifiedInvokerHA extends UnifiedInvokerHA
+ {
+ private String name;
+
+ private InvokerLocator locator;
+
+ public MockUnifiedInvokerHA(String name)
+ {
+ this.name = name;
+ }
+
+ @Override
+ public String toString()
+ {
+ return name;
+ }
+
+ public void setLocator(InvokerLocator locator)
+ {
+ this.locator = locator;
+ }
+
+ public InvokerLocator getLocator()
+ {
+ return locator;
+ }
+
+ @Override
+ protected Invoker createProxy(boolean isStrictRMIException, ArrayList targets,
+ LoadBalancePolicy policy, String proxyFamilyName, long viewId)
+ {
+ /* default invoker locator that will later be replaced by what the
+ * load balance policy decides */
+ return new MockUnifiedInvokerHAProxy(locator, isStrictRMIException, targets, policy, proxyFamilyName, viewId);
+ }
+
+ @Override
+ public MBeanServer getServer()
+ {
+ return ManagementFactory.getPlatformMBeanServer();
+ }
+ }
+
+ public static class MockUnifiedInvokerHAProxy extends UnifiedInvokerHAProxy
+ {
+
+ public MockUnifiedInvokerHAProxy(InvokerLocator locator, boolean isStrictRMIException, ArrayList targets,
+ LoadBalancePolicy policy, String proxyFamilyName, long viewId)
+ {
+ super(locator, isStrictRMIException, targets, policy, proxyFamilyName, viewId);
+ }
+
+ @Override
+ protected Client createClient(InvokerLocator locator, String subSystem) throws Exception
+ {
+ return ((MockInvokerLocator)locator).getClient();
+ }
+
+ }
+
+ public static class MockInvokerLocator extends InvokerLocator
+ {
+ /** The serialVersionUID */
+ private static final long serialVersionUID = 8641387521254685628L;
+
+ /* client that will be returned when locator is initialised */
+ private MockClient client;
+
+ public MockInvokerLocator(String host, int port, MockClient client)
+ {
+ super("unittest", host, port, "mock", null);
+ this.client = client;
+ }
+
+ public MockClient getClient()
+ {
+ return client;
+ }
+ }
+
+ public static class MockClient extends Client
+ {
+ /** underlying invoker target */
+ private MockUnifiedInvokerHA invoker;
+
+ public MockClient(MockUnifiedInvokerHA invoker)
+ {
+ this.invoker = invoker;
+ }
+
+ @Override
+ public void connect() throws Exception
+ {
+ /* do nothing on connect for unit tests */
+ }
+
+ @Override
+ public ClientInvoker getInvoker()
+ {
+ return new MockClientInvoker(invoker.getLocator());
+ }
+
+ @Override
+ public Object invoke(Object param, Map metadata) throws Throwable
+ {
+ /* Down the call stack in Remoting's Client.invoke, marshaller is
+ * called which via org.jboss.invocation.unified.marshall.InvocationMarshaller
+ * sets the transaction progagation context.
+ *
+ * As we're mocking Remoting's Client.invoke behaivour, we set the
+ * transaction progagation context manually in the mock class.
+ *
+ * Not ideal, as I try avoiding production code in UTs as much as
+ * possible, but makes the mock implementation a lot simpler.
+ */
+ Invocation inv = (Invocation) param;
+ MarshalledInvocation marshInv = new MarshalledInvocation(inv);
+ marshInv.setTransactionPropagationContext(getTransactionPropagationContext());
+
+ return invoker.invoke(new InvocationRequest("", "", marshInv,
+ metadata, null, null));
+ }
+
+ public Object getTransactionPropagationContext()
+ {
+ TransactionPropagationContextFactory tpcFactory = TransactionPropagationContextUtil.getTPCFactoryClientSide();
+ return (tpcFactory == null) ? null : tpcFactory.getTransactionPropagationContext();
+ }
+ }
+
+ public static class MockClientInvoker implements ClientInvoker
+ {
+ private InvokerLocator locator;
+
+ public MockClientInvoker(InvokerLocator locator)
+ {
+ this.locator = locator;
+ }
+
+ public InvokerLocator getLocator()
+ {
+ return locator;
+ }
+
+ public String addClientLocator(String sessionId, InvokerCallbackHandler callbackhandler, InvokerLocator locator)
+ {
+ return null;
+ }
+
+ public void connect() throws ConnectionFailedException
+ {
+ }
+
+ public void disconnect()
+ {
+ }
+
+ public void establishLease(String sessionID, Map configuration, long leasePeriod) throws Throwable
+ {
+ }
+
+ public InvokerLocator getClientLocator(String listenerId)
+ {
+ return null;
+ }
+
+ public List getClientLocators(String sessionId, InvokerCallbackHandler handler)
+ {
+ return null;
+ }
+
+ public long getLeasePeriod(String sessionID)
+ {
+ return 0;
+ }
+
+ public Marshaller getMarshaller()
+ {
+ return null;
+ }
+
+ public SocketFactory getSocketFactory()
+ {
+ return null;
+ }
+
+ public UnMarshaller getUnMarshaller()
+ {
+ return null;
+ }
+
+ public Object invoke(InvocationRequest in) throws Throwable
+ {
+ return null;
+ }
+
+ public boolean isConnected()
+ {
+ return false;
+ }
+
+ public void setMarshaller(Marshaller marshaller)
+ {
+ }
+
+ public void setSocketFactory(SocketFactory socketFactory)
+ {
+ }
+
+ public void setUnMarshaller(UnMarshaller unmarshaller)
+ {
+ }
+
+ public void terminateLease(String sessionID, int disconnectTimeout)
+ {
+ }
+ }
+
+}
Added: trunk/testsuite/src/main/org/jboss/test/cluster/invokerha/UnifiedInvokerHaUnitTestCase.java
===================================================================
--- trunk/testsuite/src/main/org/jboss/test/cluster/invokerha/UnifiedInvokerHaUnitTestCase.java (rev 0)
+++ trunk/testsuite/src/main/org/jboss/test/cluster/invokerha/UnifiedInvokerHaUnitTestCase.java 2007-11-12 19:10:13 UTC (rev 66971)
@@ -0,0 +1,125 @@
+/*
+ * 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.invokerha;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.management.ObjectName;
+
+import org.jboss.ha.framework.server.HATarget;
+import org.jboss.invocation.InvokerHA;
+import org.jboss.invocation.unified.interfaces.UnifiedInvokerHAProxy;
+import org.jboss.remoting.InvokerLocator;
+import org.jboss.test.cluster.invokerha.InvokerHaInfrastructure.InvokerHaFactory;
+import org.jboss.test.cluster.invokerha.InvokerHaInfrastructure.TraceRoundRobin;
+import org.jboss.test.cluster.invokerha.UnifiedInvokerHaMockUtils.MockClient;
+import org.jboss.test.cluster.invokerha.UnifiedInvokerHaMockUtils.MockInvokerLocator;
+import org.jboss.test.cluster.invokerha.UnifiedInvokerHaMockUtils.MockUnifiedInvokerHA;
+
+/**
+ * Unit test case for unified invoker ha proxy and invoker at the other side.
+ * Remoting and transactional layer have been mocked as the intention of these
+ * tests is not to test the remoting code nor checking the behaivour of a real
+ * transaction manager.
+ *
+ * @author <a href="mailto:galder.zamarreno at jboss.com">Galder Zamarreno</a>
+ */
+public class UnifiedInvokerHaUnitTestCase extends AbstractInvokerHaUnitTestCase
+{
+ @Override
+ protected void setUp() throws Exception
+ {
+ setUp(2, new UnifiedInvokerHaFactory());
+ }
+
+ @Override
+ protected void tearDown() throws Exception
+ {
+ super.tearDown();
+ }
+
+ public void testSuccessfulCallsRoundRobin() throws Exception
+ {
+ successfulCalls(TraceRoundRobin.class, UnifiedInvokerHAProxy.txFailoverAuthorizations);
+ }
+
+ /** Classes **/
+
+ /**
+ * Unified invoker ha factory.
+ */
+ public class UnifiedInvokerHaFactory implements InvokerHaFactory
+ {
+ public String getInvokerTypeName()
+ {
+ return "UnifiedInvokerHA";
+ }
+
+ public InvokerHaInfrastructure getInvokerHaInfrastructure(int serverCount)
+ {
+ return new UnifiedInvokerHaInfrastructure(serverCount, this);
+ }
+
+ public InvokerHA createInvokerHAServer(String serverName, int serverNumber)
+ {
+ MockUnifiedInvokerHA invoker = new MockUnifiedInvokerHA(getInvokerTypeName() + "-" + serverName + "-" + serverNumber);
+ MockClient client = new MockClient(invoker);
+ MockInvokerLocator locator = new MockInvokerLocator("127.0.0.1", serverNumber, client);
+ invoker.setLocator(locator);
+
+ return invoker;
+ }
+ }
+
+ /**
+ * Unified invoker specific infrastructure class.
+ */
+ public class UnifiedInvokerHaInfrastructure extends InvokerHaInfrastructure
+ {
+ public UnifiedInvokerHaInfrastructure(int serverCount, InvokerHaFactory invokerHaFactory)
+ {
+ super(serverCount, invokerHaFactory);
+ }
+
+ @Override
+ protected void deploy(List<? extends InvokerHA> replicants, ObjectName targetName, String replicantName)
+ throws Exception
+ {
+ /* convert replicant list into an InvokerLocator list */
+ List<InvokerLocator> locators = new ArrayList<InvokerLocator>(replicants.size());
+ for (InvokerHA replicant : replicants)
+ {
+ locators.add(((MockUnifiedInvokerHA)replicant).getLocator());
+ }
+
+ for(InvokerHA replicant : replicants)
+ {
+ /* create ha-target in first server with the list of replicants and register
+ * it with the MBeanServer. */
+ HATarget target = new MockHATarget(null, replicantName, null, 2);
+ target.replicantsChanged(null, locators, 0);
+ replicant.registerBean(targetName, target);
+ }
+ }
+ }
+}
More information about the jboss-cvs-commits
mailing list