Package org.jboss.test.util.ejb

Source Code of org.jboss.test.util.ejb.EJBTestRunnerBean

/*
* JBoss, Home of Professional Open Source.
* Copyright 2006, 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.util.ejb;

import java.lang.reflect.Constructor;
import java.util.Properties;
import javax.ejb.EJBException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
import javax.naming.Binding;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.naming.NamingEnumeration;
import javax.transaction.Status;
import javax.transaction.SystemException;
import javax.transaction.Transaction;
import javax.transaction.TransactionManager;

import org.jboss.logging.Logger;
import org.jboss.tm.TransactionManagerLocator;

/**
* Implementation of the ejb test runner.
*
* @see EJBTestRunner
*
* @author <a href="mailto:dain@daingroup.com">Dain Sundstrom</a>
* @author Scott.Stark@jboss.org
* @version $Revision: 65582 $
*/
public class EJBTestRunnerBean implements SessionBean
{
   private static final Logger log = Logger.getLogger(EJBTestRunnerBean.class);
   transient private SessionContext ctx;
   private String runnerJndiName;

   /** Run the specified test method on the given class name using a Properties
    * map built from all java:comp/env entries.
    *
    * @param className the name of the test class
    * @param methodName the name of the test method
    * @throws RemoteTestException If any throwable is thrown during
    * execution of the method, it is wrapped with a RemoteTestException and
    * rethrown.
    */
   public void run(String className, String methodName)
      throws RemoteTestException
   {
      Properties props = new Properties();
      try
      {
         InitialContext ctx = new InitialContext();
         NamingEnumeration bindings = ctx.listBindings("java:comp/env");
         while( bindings.hasMore() )
         {
            Binding binding = (Binding) bindings.next();
            String name = binding.getName();
            String value = binding.getObject().toString();
            props.setProperty(name, value);
         }
      }
      catch(NamingException e)
      {
         throw new RemoteTestException(e);
      }
      run(className, methodName, props);
   }

   /** Run the specified test method on the given class name
    * 
    * @param className the name of the test class
    * @param methodName the name of the test method
    * @param props
    * @throws RemoteTestException If any throwable is thrown during
    * execution of the method, it is wrapped with a RemoteTestException and
    * rethrown.
    */
   public void run(String className, String methodName, Properties props)
      throws RemoteTestException
   {
      EJBTestCase testCase = getTestInstance(className, methodName);

      setUpEJB(testCase, props);

      RemoteTestException exception = null;
      try
      {
         runTestCase(testCase);
      }
      catch (RemoteTestException e)
      {
         exception = e;
      }
      finally
      {
         try
         {
            tearDownEJB(testCase, props);
         }
         catch (RemoteTestException e)
         {
            // favor the run exception if one was thrown
            if (exception != null)
            {
               exception = e;
            }
         }
         if (exception != null)
         {
            throw exception;
         }
      }
   }

   private static boolean wantUserTransaction(Properties props)
   {
      return props == null || props.get("NO_USER_TRANSACTION") == null;
   }
  
   /**
    * Runs the setUpEJB method on the specified test case
    * @param testCase the actual test case that will be run
    * @throws RemoteTestException If any throwable is thrown during execution
    * of the method, it is wrapped with a RemoteTestException and rethrown.
    */
   private void setUpEJB(EJBTestCase testCase, Properties props)
      throws RemoteTestException
   {
      boolean wantUserTransaction = wantUserTransaction(props);
      try
      {
         if (wantUserTransaction)
            ctx.getUserTransaction().begin();
         try
         {
            testCase.setUpEJB(props);
         }
         catch (Throwable e)
         {
            throw new RemoteTestException(e);
         }
         if (wantUserTransaction && ctx.getUserTransaction().getStatus() == Status.STATUS_ACTIVE)
         {
            ctx.getUserTransaction().commit();
         }
      }
      catch (Throwable e)
      {
         try
         {
            if (wantUserTransaction)
               ctx.getUserTransaction().rollback();
         }
         catch (SystemException unused)
         {
            // eat the exception we are exceptioning out anyway
         }
         if (e instanceof RemoteTestException)
         {
            throw (RemoteTestException) e;
         }
         throw new RemoteTestException(e);
      }
   }

   /**
    * Runs the test method on the specified test case
    * @param testCase the actual test case that will be run
    * @throws RemoteTestException If any throwable is thrown during execution
    * of the method, it is wrapped with a RemoteTestException and rethrown.
    */
   private void runTestCase(EJBTestCase testCase) throws RemoteTestException
   {
      try
      {
         boolean wantUserTransaction = wantUserTransaction(testCase.getProps());
         try
         {
            if (wantUserTransaction)
               ctx.getUserTransaction().begin();
            try
            {
               testCase.runBare();
            }
            catch (Throwable e)
            {
               throw new RemoteTestException(e);
            }
            if (wantUserTransaction && ctx.getUserTransaction().getStatus() == Status.STATUS_ACTIVE)
            {
               ctx.getUserTransaction().commit();
            }
         }
         catch (Throwable e)
         {
            try
            {
               if (wantUserTransaction)
                  ctx.getUserTransaction().rollback();
            }
            catch (SystemException unused)
            {
               // eat the exception we are exceptioning out anyway
            }
            if (e instanceof RemoteTestException)
            {
               throw (RemoteTestException) e;
            }
            throw new RemoteTestException(e);
         }
      }
      finally
      {
         Transaction tx = null;
         TransactionManager tm = TransactionManagerLocator.getInstance().locate();
         try
         {
            tx = tm.getTransaction();
            if (tx != null)
            {
               try
               {
                  tx.rollback();
               }
               finally
               {
                  tm.suspend();
               }
            }
         }
         catch (Exception e)
         {
            log.error("Error rolling back incomplete transaction: " + tx, e);
         }
      }
   }

   /**
    * Runs the tearDownEJB method on the specified test case
    * @param testCase the actual test case that will be run
    * @throws RemoteTestException If any throwable is thrown during execution
    * of the method, it is wrapped with a RemoteTestException and rethrown.
    */
   private void tearDownEJB(EJBTestCase testCase, Properties props)
      throws RemoteTestException
   {
      boolean wantUserTransaction = wantUserTransaction(props);
      try
      {
         if (wantUserTransaction)
            ctx.getUserTransaction().begin();
         try
         {
            testCase.tearDownEJB(props);
         }
         catch (Throwable e)
         {
            throw new RemoteTestException(e);
         }
         if (wantUserTransaction && ctx.getUserTransaction().getStatus() == Status.STATUS_ACTIVE)
         {
            ctx.getUserTransaction().commit();
         }
      }
      catch (Throwable e)
      {
         try
         {
            if (wantUserTransaction)
               ctx.getUserTransaction().rollback();
         }
         catch (SystemException unused)
         {
            // eat the exception we are exceptioning out anyway
         }
         if (e instanceof RemoteTestException)
         {
            throw (RemoteTestException) e;
         }
         throw new RemoteTestException(e);
      }
   }

   /**
    * Gets a instance of the test class with the specified class name and
    * initialized to execute the specified method.
    *
    * @param className the name of the test class
    * @param methodName the name of the test method
    * @return a new instance of the test class with the specified class name and
    *    initialized to execute the specified method.
    */
   private EJBTestCase getTestInstance(String className, String methodName)
   {
      Class testClass = null;
      try
      {
         ClassLoader loader = Thread.currentThread().getContextClassLoader();
         testClass = loader.loadClass(className);
      }
      catch (ClassNotFoundException e)
      {
         throw new EJBException("Test class not found : " + className);
      }

      Constructor constructor = null;
      try
      {
         constructor = testClass.getConstructor(new Class[]{String.class});
      }
      catch (Exception e)
      {
         throw new EJBException("Test class does not have a constructor " +
            "which has a single String argument.", e);
      }

      try
      {
         EJBTestCase testCase =
            (EJBTestCase) constructor.newInstance(new Object[]{methodName});
         testCase.setServerSide(true);
         return testCase;
      }
      catch (Exception e)
      {
         throw new EJBException("Cannot instantiate test class: " +
            testClass.getName(), e);
      }
   }

   public void ejbCreate()
   {
   }

   public void ejbRemove()
   {
   }

   public void ejbActivate()
   {
   }

   public void ejbPassivate()
   {
   }

   public void setSessionContext(SessionContext ctx)
   {
      this.ctx = ctx;
   }
}
TOP

Related Classes of org.jboss.test.util.ejb.EJBTestRunnerBean

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.