/*
* 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.lock.test;
import java.rmi.*;
import java.util.HashMap;
import java.util.StringTokenizer;
import javax.ejb.FinderException;
import javax.naming.Context;
import javax.naming.InitialContext;
import junit.framework.Assert;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.jboss.logging.Logger;
import org.jboss.test.JBossTestCase;
import org.jboss.test.lock.interfaces.EnterpriseEntity;
import org.jboss.test.lock.interfaces.EnterpriseEntityHome;
/**
* #Description of the Class
*/
public abstract class EnterpriseEntityTest
extends JBossTestCase
{
/**
* Description of the Field
*/
public final static int DEFAULT_THREAD_COUNT = 20;
/**
* Description of the Field
*/
public final static int DEFAULT_ITERATIONS = 10;
private String jndiname;
/**
* The number of threads to test with.
*/
private int nbThreads;
private int completedThreads;
/**
* The number of iterations each thread will go through
*/
private int iterations;
private Worker[] threads;
private HashMap param = new HashMap();
private EnterpriseEntity entity;
private boolean failed;
/**
* Constructor for the EnterpriseEntityTest object
*
* @param name Description of Parameter
* @param jndiname Description of Parameter
*/
public EnterpriseEntityTest(final String name,
final String jndiname)
{
super(name);
this.jndiname = jndiname;
}
/**
* A unit test for JUnit
*
* @exception Exception Description of Exception
*/
public void testSingleBean() throws Exception
{
getLog().debug("Spawning " + nbThreads + " threads for " +
iterations + " iterations with single bean call");
Task prototype =
new Task()
{
/**
* Main processing method for the EnterpriseEntityTest object
*
* @param name Description of Parameter
* @param i Description of Parameter
* @exception Exception Description of Exception
*/
public void run(String name, int i) throws Exception
{
entity.setField(name + " i=" + i);
}
};
run(prototype);
}
/**
* A unit test for JUnit
*
* @exception Exception Description of Exception
*/
public void testB2B() throws Exception
{
getLog().debug("Spawning " + nbThreads + " threads for " +
iterations + " iterations with bean to bean call");
entity.setNextEntity("daniel");
Task prototype =
new Task()
{
/**
* Main processing method for the EnterpriseEntityTest object
*
* @param name Description of Parameter
* @param i Description of Parameter
* @exception Exception Description of Exception
*/
public void run(String name, int i) throws Exception
{
entity.setAndCopyField(name + " i=" + i);
}
};
run(prototype);
}
/**
* The JUnit setup method
*
* @exception Exception Description of Exception
*/
protected void setUp() throws Exception
{
super.setUp();
nbThreads = getThreadCount();//DEFAULT_THREAD_COUNT;
iterations = getIterationCount();//DEFAULT_ITERATIONS;
getLog().debug("+++ Setting up: " + getClass().getName() + " test: " + getName());
EnterpriseEntityHome home =
(EnterpriseEntityHome)getInitialContext().lookup(jndiname);
try
{
entity = home.findByPrimaryKey("seb");
}
catch (FinderException e)
{
entity = home.create("seb");
}
// setup the threads
threads = new Worker[nbThreads];
}
/**
* Sets the Failed attribute of the EnterpriseEntityTest object
*/
protected synchronized void setFailed()
{
failed = true;
}
/**
* #Description of the Method
*
* @param prototype Description of Parameter
* @exception Exception Description of Exception
*/
protected void startAll(Task prototype) throws Exception
{
completedThreads = 0;
for (int i = 0; i < nbThreads; i++)
{
Task task = (Task)prototype.clone();
threads[i] = new Worker("Thread #" + (i + 1), task, getLog());
threads[i].start();
}
}
/**
* #Description of the Method
*
* @exception Exception Description of Exception
*/
protected void joinAll() throws Exception
{
// wait for all the threads to finish
for (int i = 0; i < nbThreads; i++)
{
threads[i].join();
}
}
/**
* Main processing method for the EnterpriseEntityTest object
*
* @param prototype Description of Parameter
* @exception Exception Description of Exception
*/
protected void run(Task prototype) throws Exception
{
startAll(prototype);
joinAll();
assertTrue(!failed);
}
/**
* #Description of the Method
*
* @return Description of the Returned Value
*/
protected boolean hasFailed()
{
return failed;
}
/////////////////////////////////////////////////////////////////////////
// Iteration Worker & Task //
/////////////////////////////////////////////////////////////////////////
/**
* #Description of the Class
*/
public abstract class Task
implements Cloneable
{
/**
* Main processing method for the Task object
*
* @param name Description of Parameter
* @param i Description of Parameter
* @exception Exception Description of Exception
*/
public abstract void run(String name, int i) throws Exception;
/**
* #Description of the Method
*
* @return Description of the Returned Value
*/
public Object clone()
{
try
{
return super.clone();
}
catch (CloneNotSupportedException e)
{
throw new InternalError();
}
}
}
/**
* #Description of the Class
*/
public class Worker
extends Thread
{
/**
* Description of the Field
*/
public String name;
/**
* Description of the Field
*/
public boolean running;
/**
* Description of the Field
*/
public Task task;
private Logger log;
/**
* Constructor for the Worker object
*
* @param name Description of Parameter
* @param task Description of Parameter
* @param log Description of Parameter
*/
public Worker(final String name, final Task task, Logger log)
{
this.name = name;
this.task = task;
this.log = log;
running = true;
}
/**
* Main processing method for the Worker object
*/
public void run()
{
long start = System.currentTimeMillis();
int i;
for (i = 0; i < iterations; i++)
{
if (!running || hasFailed())
{
break;
}
try
{
task.run(name, i);
//log.debug(name + " " + (i+1) + " iterations done");
}
catch (Throwable t)
{
log.error(name + " caught an exception, dying", t);
t.printStackTrace();
running = false;
setFailed();
}
}
synchronized (this)
{
completedThreads++;
}
long end = System.currentTimeMillis();
log.debug(name + ": did " + i +
" iterations in " + (end - start) + "ms, complete=" + completedThreads);
}
}
}