[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