/*
* 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.test.timer.test;
import java.rmi.RemoteException;
import java.rmi.ServerException;
import javax.ejb.EJBHome;
import javax.ejb.NoSuchObjectLocalException;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.security.auth.login.LoginContext;
import junit.framework.Test;
import org.jboss.security.auth.callback.AppCallbackHandler;
import org.jboss.test.JBossTestCase;
import org.jboss.test.timer.interfaces.TimerEntity;
import org.jboss.test.timer.interfaces.TimerEntityHome;
import org.jboss.test.timer.interfaces.TimerSFSB;
import org.jboss.test.timer.interfaces.TimerSFSBHome;
import org.jboss.test.timer.interfaces.TimerSLSB;
import org.jboss.test.timer.interfaces.TimerSLSBHome;
/**
* Simple unit tests for the EJB Timer service that uses secured ejbs.
*/
public class SecureTimerUnitTestCase extends JBossTestCase
{
private static final String EJB_TIMER_XAR = "ejb-timer.ear";
private static final int SHORT_PERIOD = 1 * 1000; // 1s
private LoginContext lc;
/**
* Setup the test suite.
*/
public static Test suite() throws Exception
{
return JBossTestCase.getDeploySetup(SecureTimerUnitTestCase.class, EJB_TIMER_XAR);
}
/**
* Constructor for the BasicTimerUnitTest object
*/
public SecureTimerUnitTestCase(String pName)
{
super(pName);
}
public void tearDown()
{
}
/**
* Test that a Stafeful Session Bean cannot access a Timer Service
*
* @throws Exception Unexpected Exception indicating an error
*/
public void testSecuredStatefulSessionBeanTimer()
throws Exception
{
login();
TimerSFSBHome home = (TimerSFSBHome) getEJBHome(TimerSFSBHome.SECURED_JNDI_NAME);
TimerSFSB lBean = home.create();
try
{
lBean.checkTimerService();
fail("Stateful Session Bean is not allowed to get a Timer Service");
}
catch (RemoteException re)
{
Throwable lCause = re.detail;
if (lCause instanceof ServerException)
{
lCause = ((ServerException) lCause).detail;
if (lCause instanceof IllegalStateException)
{
// This exception is expected -> ignore
}
else
{
throw re;
}
}
}
logout();
}
/**
* Test that a repetitive Stafeless Session Bean Timer
*
* @throws Exception Unexpected Exception indicating an error
*/
public void testSecuredStatelessSessionBeanTimer()
throws Exception
{
login();
TimerSLSBHome home = (TimerSLSBHome) getEJBHome(TimerSLSBHome.SECURED_JNDI_NAME);
TimerSLSB bean = home.create();
byte[] handle = bean.startTimer(SHORT_PERIOD);
// Sleep for 20x the timer interval and expect at least 10 events
Thread.sleep(20 * SHORT_PERIOD);
int count = bean.getTimeoutCount(handle);
bean.stopTimer(handle);
assertTrue("Timeout was expected to be called at least 10 times but was "
+ "only called: " + count + " times",
count >= 10);
Thread.sleep(5 * SHORT_PERIOD);
int count2 = bean.getTimeoutCount(handle);
assertTrue("After the timer was stopped no timeout should happen but "
+ "it was called " + count2 + " more times",
count2 == 0);
bean.remove();
logout();
}
/**
* Test that a single Stafeless Session Bean Timer
*
* @throws Exception Unexpected Exception indicating an error
*/
public void testSecuredStatelessSessionBeanSingleTimer()
throws Exception
{
login();
TimerSLSBHome home = (TimerSLSBHome) getEJBHome(TimerSLSBHome.SECURED_JNDI_NAME);
TimerSLSB bean = home.create();
byte[] handle = bean.startSingleTimer(SHORT_PERIOD);
Thread.sleep(5 * SHORT_PERIOD);
int count = bean.getTimeoutCount(handle);
assertTrue("Timeout was expected to be called only once but was called: "
+ count + " times",
count == 1);
try
{
bean.stopTimer(handle);
fail("A single timer should expire after the first event and therefore this "
+ "has to throw an NoSuchObjectLocalException");
}
catch (RemoteException re)
{
Throwable lCause = re.detail;
if (lCause instanceof ServerException)
{
lCause = ((ServerException) lCause).detail;
if (lCause instanceof NoSuchObjectLocalException)
{
// This exception is expected -> ignore
}
else
{
throw re;
}
}
}
bean.remove();
logout();
}
/**
* Test that a repetitive Entity Bean Timer
*
* @throws Exception Unexpected Exception indicating an error
*/
public void testSecuredEntityBeanTimer()
throws Exception
{
login();
TimerEntityHome home = (TimerEntityHome) getEJBHome(TimerEntityHome.SECURED_JNDI_NAME);
TimerEntity entity = home.create(new Integer(111));
entity.startTimer(SHORT_PERIOD);
Thread.sleep(12 * SHORT_PERIOD);
entity.stopTimer();
int count = entity.getTimeoutCount();
assertTrue("Timeout was expected to be called at least 10 times but was "
+ "only called: " + count + " times",
count >= 10);
Thread.sleep(5 * SHORT_PERIOD);
int count2 = entity.getTimeoutCount();
assertTrue("After the timer was stopped no timeout should happen but "
+ "it was called " + (count2 - count) + " more times",
count == count2);
entity.remove();
logout();
}
/**
* Test that a single Entity Bean Timer
*
* @throws Exception Unexpected Exception indicating an error
*/
public void testSecuredEntityBeanSingleTimer()
throws Exception
{
login();
TimerEntityHome home = (TimerEntityHome) getEJBHome(TimerEntityHome.SECURED_JNDI_NAME);
TimerEntity entity = home.create(new Integer(222));
entity.startSingleTimer(SHORT_PERIOD);
Thread.sleep(5 * SHORT_PERIOD);
int count = entity.getTimeoutCount();
assertTrue("Timeout was expected to be called only once but was called: "
+ count + " times",
count == 1);
try
{
entity.stopTimer();
fail("A single timer should expire after the first event and therefore this "
+ "has to throw an NoSuchObjectLocalException");
}
catch (RemoteException re)
{
Throwable lCause = re.detail;
if (lCause instanceof ServerException)
{
lCause = ((ServerException) lCause).detail;
if (lCause instanceof NoSuchObjectLocalException)
{
// This exception is expected -> ignore
}
else
{
throw re;
}
}
}
entity.remove();
logout();
}
private EJBHome getEJBHome(String pJNDIName)
throws NamingException
{
InitialContext lContext = new InitialContext();
return (EJBHome) lContext.lookup(pJNDIName);
}
private void login() throws Exception
{
lc = null;
String username = "jduke";
char[] password = "theduke".toCharArray();
AppCallbackHandler handler = new AppCallbackHandler(username, password);
log.debug("Creating LoginContext(ejb-timers)");
lc = new LoginContext("ejb-timers", handler);
lc.login();
log.debug("Created LoginContext, subject="+lc.getSubject());
}
private void logout() throws Exception
{
if( lc != null )
{
lc.logout();
lc = null;
}
}
}