/*
* JBoss, Home of Professional Open Source.
* Copyright 2008, 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.aspects.currentinvocation.test.basic.unit;
import junit.framework.TestCase;
import org.jboss.aspects.common.AOPDeployer;
import org.jboss.aspects.currentinvocation.CurrentInvocation;
import org.jboss.aspects.currentinvocation.test.basic.PojoBean;
import org.jboss.aspects.currentinvocation.test.basic.TestException;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
/**
* CurrentInvocationUnitTestCase
*
* Test Cases to ensure the CurrentInvocation mechanism
* is working correctly
*
* @author <a href="mailto:andrew.rubinger@jboss.org">ALR</a>
* @version $Revision: $
*/
public class CurrentInvocationUnitTestCase
{
// -------------------------------------------------------------------------------------------------||
// Class Members -----------------------------------------------------------------------------------||
// -------------------------------------------------------------------------------------------------||
private static final String DD_AOP_INCONTEXT = "jboss-aop.xml";
// -------------------------------------------------------------------------------------------------||
// Instance Members --------------------------------------------------------------------------------||
// -------------------------------------------------------------------------------------------------||
private AOPDeployer deployer = new AOPDeployer(CurrentInvocationUnitTestCase.DD_AOP_INCONTEXT);
// -------------------------------------------------------------------------------------------------||
// Tests -------------------------------------------------------------------------------------------||
// -------------------------------------------------------------------------------------------------||
/**
* Ensures that the current invocation
* can be obtained from within proper context
*/
@Test
public void testCurrentInvocationInContext()
{
// Set TCL
Thread.currentThread().setContextClassLoader(PojoBean.class.getClassLoader());
// Ensure current invocation is accessible from within context
TestCase.assertEquals("Current Invocation for this Thread was null", true, new PojoBean()
.canGetCurrentInvocation());
// Ensure context is cleansed after completion
TestCase.assertEquals("Current Invocation was not cleansed after interception completed", null, CurrentInvocation
.getCurrentInvocation());
}
/**
* Ensures that the Current Invocation is cleaned up
* even in the case an Exception is thrown
*/
@Test
public void testCleanupAfterException()
{
// Set TCL
Thread.currentThread().setContextClassLoader(PojoBean.class.getClassLoader());
try
{
new PojoBean().throwException();
}
catch (TestException e)
{
TestCase.assertEquals("Current Invocation was not cleansed after exception was thrown", null,
CurrentInvocation.getCurrentInvocation());
}
}
/**
* Ensures that a Thread running concurrently
* alongside an invocation cannot access
* the current invocation outside its own scope
*/
@Test
public void testConcurrentAccessFromSeparateThreadFails()
{
// Set TCL
Thread.currentThread().setContextClassLoader(PojoBean.class.getClassLoader());
// Initialize
long waitForLaunch = 750L;
// Make a new PojoBean
PojoBean bean = new PojoBean();
// Start a new job for Pojo to invoke and hold
Thread otherThread = new RunPojoBeanSuspend(bean);
otherThread.start();
// Let the process start
try
{
Thread.sleep(waitForLaunch);
}
catch (InterruptedException e)
{
throw new RuntimeException(e);
}
// Ensure we can't get the current invocation that's in
// the other Thread's scope
TestCase.assertEquals("Scoping of CurrentInvocation is not limited per Thread", null, CurrentInvocation
.getCurrentInvocation());
// Let the other Thread complete
synchronized(bean){
bean.notify();
}
// Wait for other thread to die
try
{
otherThread.join();
}
catch (InterruptedException e)
{
throw new RuntimeException(e);
}
}
// -------------------------------------------------------------------------------------------------||
// Helper Classes ---------------------------------------------------------------------------------||
// -------------------------------------------------------------------------------------------------||
private static class RunPojoBeanSuspend extends Thread
{
PojoBean bean;
public RunPojoBeanSuspend(PojoBean bean)
{
this.bean = bean;
}
@Override
public void run()
{
super.run();
this.bean.suspend();
}
}
// -------------------------------------------------------------------------------------------------||
// Lifecycle ---------------------------------------------------------------------------------------||
// -------------------------------------------------------------------------------------------------||
@Before
public void setup() throws Exception
{
this.getDeployer().deploy();
}
@After
public void tearDown() throws Exception
{
this.getDeployer().undeploy();
}
// -------------------------------------------------------------------------------------------------||
// Accessors ---------------------------------------------------------------------------------------||
// -------------------------------------------------------------------------------------------------||
private AOPDeployer getDeployer()
{
return deployer;
}
}