[jboss-cvs] JBossAS SVN: r67033 - in branches/Branch_4_2/testsuite/src/main/org/jboss/test/cluster: invokerha and 1 other directory.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Tue Nov 13 13:14:12 EST 2007


Author: galder.zamarreno at jboss.com
Date: 2007-11-13 13:14:12 -0500 (Tue, 13 Nov 2007)
New Revision: 67033

Added:
   branches/Branch_4_2/testsuite/src/main/org/jboss/test/cluster/invokerha/
   branches/Branch_4_2/testsuite/src/main/org/jboss/test/cluster/invokerha/AbstractInvokerHaUnitTestCase.java
   branches/Branch_4_2/testsuite/src/main/org/jboss/test/cluster/invokerha/InvokerHaInfrastructure.java
   branches/Branch_4_2/testsuite/src/main/org/jboss/test/cluster/invokerha/InvokerHaTransactionalMockUtils.java
   branches/Branch_4_2/testsuite/src/main/org/jboss/test/cluster/invokerha/UnifiedInvokerHaMockUtils.java
   branches/Branch_4_2/testsuite/src/main/org/jboss/test/cluster/invokerha/UnifiedInvokerHaUnitTestCase.java
Log:
[JBAS-4950] Package created for invoker ha tests as well as standalone unit tests created for ha invokers in general and particularly for unified invokers. Some helper classes for mocking purpouses added too.

Added: branches/Branch_4_2/testsuite/src/main/org/jboss/test/cluster/invokerha/AbstractInvokerHaUnitTestCase.java
===================================================================
--- branches/Branch_4_2/testsuite/src/main/org/jboss/test/cluster/invokerha/AbstractInvokerHaUnitTestCase.java	                        (rev 0)
+++ branches/Branch_4_2/testsuite/src/main/org/jboss/test/cluster/invokerha/AbstractInvokerHaUnitTestCase.java	2007-11-13 18:14:12 UTC (rev 67033)
@@ -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: branches/Branch_4_2/testsuite/src/main/org/jboss/test/cluster/invokerha/InvokerHaInfrastructure.java
===================================================================
--- branches/Branch_4_2/testsuite/src/main/org/jboss/test/cluster/invokerha/InvokerHaInfrastructure.java	                        (rev 0)
+++ branches/Branch_4_2/testsuite/src/main/org/jboss/test/cluster/invokerha/InvokerHaInfrastructure.java	2007-11-13 18:14:12 UTC (rev 67033)
@@ -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: branches/Branch_4_2/testsuite/src/main/org/jboss/test/cluster/invokerha/InvokerHaTransactionalMockUtils.java
===================================================================
--- branches/Branch_4_2/testsuite/src/main/org/jboss/test/cluster/invokerha/InvokerHaTransactionalMockUtils.java	                        (rev 0)
+++ branches/Branch_4_2/testsuite/src/main/org/jboss/test/cluster/invokerha/InvokerHaTransactionalMockUtils.java	2007-11-13 18:14:12 UTC (rev 67033)
@@ -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: branches/Branch_4_2/testsuite/src/main/org/jboss/test/cluster/invokerha/UnifiedInvokerHaMockUtils.java
===================================================================
--- branches/Branch_4_2/testsuite/src/main/org/jboss/test/cluster/invokerha/UnifiedInvokerHaMockUtils.java	                        (rev 0)
+++ branches/Branch_4_2/testsuite/src/main/org/jboss/test/cluster/invokerha/UnifiedInvokerHaMockUtils.java	2007-11-13 18:14:12 UTC (rev 67033)
@@ -0,0 +1,290 @@
+/*
+ * 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.IOException;
+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.serialization.SerializationManager;
+import org.jboss.remoting.serialization.impl.java.JavaSerializationManager;
+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();
+      }
+      
+      @Override
+      protected SerializationManager getSerializationManager() throws IOException
+      {
+         return new JavaSerializationManager();
+      }
+      
+      @Override
+      public void postDeregister()
+      {
+      }
+   }
+   
+   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: branches/Branch_4_2/testsuite/src/main/org/jboss/test/cluster/invokerha/UnifiedInvokerHaUnitTestCase.java
===================================================================
--- branches/Branch_4_2/testsuite/src/main/org/jboss/test/cluster/invokerha/UnifiedInvokerHaUnitTestCase.java	                        (rev 0)
+++ branches/Branch_4_2/testsuite/src/main/org/jboss/test/cluster/invokerha/UnifiedInvokerHaUnitTestCase.java	2007-11-13 18:14:12 UTC (rev 67033)
@@ -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