package org.jboss.test.cache.stress;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.jboss.cache.CacheException;
import org.jboss.cache.PropertyConfigurator;
import org.jboss.cache.TreeCache;
import org.jboss.cache.lock.IsolationLevel;
import org.jboss.cache.lock.LockStrategyFactory;
import org.jboss.cache.transaction.DummyTransactionManager;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.transaction.*;
import java.util.ArrayList;
import java.util.Properties;
import java.util.Random;
public class LocalStressTestCase extends TestCase
{
static TreeCache cache_;
int cachingMode_ = TreeCache.LOCAL;
final static Properties p_;
String oldFactory_ = null;
final String FACTORY = "org.jboss.cache.transaction.DummyContextFactory";
static ArrayList nodeList_;
static final int depth_ = 4;
static final int children_ = 4;
DummyTransactionManager tm_;
static final int MAX_LOOP = 100;
static final int SLEEP_TIME = 50;
static Exception thread_ex=null;
static
{
p_ = new Properties();
p_.put(Context.INITIAL_CONTEXT_FACTORY,
"org.jboss.cache.transaction.DummyContextFactory");
}
public LocalStressTestCase(String name)
{
super(name);
}
public void setUp() throws Exception
{
super.setUp();
oldFactory_ = System.getProperty(Context.INITIAL_CONTEXT_FACTORY);
System.setProperty(Context.INITIAL_CONTEXT_FACTORY, FACTORY);
DummyTransactionManager.getInstance();
initCaches(TreeCache.LOCAL);
nodeList_ = nodeGen(depth_, children_);
tm_ = new DummyTransactionManager();
log("LocalStressTestCase: cacheMode=TRANSIENT, one cache");
}
public void tearDown() throws Exception
{
super.tearDown();
thread_ex=null;
DummyTransactionManager.destroy();
destroyCaches();
if (oldFactory_ != null) {
System.setProperty(Context.INITIAL_CONTEXT_FACTORY, oldFactory_);
oldFactory_ = null;
}
}
void initCaches(int caching_mode) throws Exception
{
cachingMode_ = caching_mode;
cache_ = new TreeCache();
PropertyConfigurator config = new PropertyConfigurator();
config.configure(cache_, "META-INF/local-eviction-service.xml"); cache_.setTransactionManagerLookupClass("org.jboss.cache.DummyTransactionManagerLookup");
cache_.createService();
cache_.startService();
}
void destroyCaches() throws Exception
{
cache_.stopService();
cache_ = null;
}
protected void setLevelRW()
{
log("set lock level to RWUpgrade ...");
LockStrategyFactory.setIsolationLevel(IsolationLevel.REPEATABLE_READ);
}
protected void setLevelSerial()
{
log("set lock level to SimpleLock ...");
LockStrategyFactory.setIsolationLevel(IsolationLevel.SERIALIZABLE);
}
public void testAllTx_RWLock() throws Exception
{
setLevelRW();
allTx();
}
public void XtestAllTx_SimpleLock() throws Exception
{
setLevelSerial();
allTx();
}
private void allTx() throws Exception
{
UserTransaction tx = null;
tx = (UserTransaction) new InitialContext(p_).lookup("UserTransaction");
RunThread t1 = new RunThread(tx, 1);
RunThread t2 = new RunThread(tx, 2);
t1.start();
t2.start();
t1.join(60000); t2.join(60000);
if(thread_ex != null)
throw thread_ex;
}
static class RunThread extends Thread
{
final int seed_;
Random random_;
UserTransaction tx_ = null;
public RunThread(UserTransaction tx, int seed)
{
seed_ = seed;
random_ = new Random(seed);
tx_ = tx;
}
public void run() {
try {
_run();
}
catch(Exception e) {
thread_ex=e;
}
}
public void _run() throws HeuristicMixedException, SystemException,
NotSupportedException, HeuristicRollbackException, RollbackException, CacheException {
for (int loop = 0; loop < MAX_LOOP; loop++) {
sleep_(random_.nextInt(50));
log("Executing op1. Loop-" + loop);
op1();
sleep_(random_.nextInt(50));
log("Executing op2...");
op2();
sleep_(random_.nextInt(50));
log("Executing op3...");
op3();
}
}
private void op1() throws SystemException, NotSupportedException, CacheException,
HeuristicMixedException, HeuristicRollbackException, RollbackException {
int i = random_.nextInt(nodeList_.size() - 1);
String key = Integer.toString(i);
String value = Integer.toString(i);
tx_.begin();
String node = (String) nodeList_.get(i);
cache_.get(node, key);
sleep_(random_.nextInt(SLEEP_TIME)); cache_.put(node, key, value);
sleep_(random_.nextInt(SLEEP_TIME)); cache_.remove(node, key);
tx_.commit();
}
private void op2() throws SystemException, NotSupportedException, CacheException,
HeuristicMixedException, HeuristicRollbackException, RollbackException {
int i = random_.nextInt(nodeList_.size() - 1);
String key = Integer.toString(i);
tx_.begin();
String node = (String) nodeList_.get(i);
cache_.get(node, key);
sleep_(random_.nextInt(SLEEP_TIME)); cache_.get(node, key);
sleep_(random_.nextInt(SLEEP_TIME)); tx_.commit();
}
private void op3() throws SystemException, NotSupportedException, CacheException,
HeuristicMixedException, HeuristicRollbackException, RollbackException {
int i = random_.nextInt(nodeList_.size() - 1);
String key = Integer.toString(i);
String value = Integer.toString(i);
tx_.begin();
String node = (String) nodeList_.get(i);
cache_.put(node, key, value);
sleep_(random_.nextInt(SLEEP_TIME)); cache_.remove(node, key);
tx_.commit();
}
private void sleep_(long msecs)
{
try {
Thread.sleep(msecs);
} catch (Exception ex) {
}
}
}
private ArrayList nodeGen(int depth, int children)
{
ArrayList strList = new ArrayList();
ArrayList oldList = new ArrayList();
ArrayList newList = new ArrayList();
oldList.add("/");
newList.add("/");
strList.add("/");
while (depth > 0) {
newList = new ArrayList();
for (int i = 0; i < oldList.size(); i++) {
for (int j = 0; j < children; j++) {
String tmp = (String) oldList.get(i);
tmp += Integer.toString(j);
if (depth != 1)
tmp += "/";
newList.add(tmp);
}
}
strList.addAll(newList);
oldList = newList;
depth--;
}
log("Nodes generated: " + strList.size());
return strList;
}
public static Test suite() throws Exception
{
return new TestSuite(LocalStressTestCase.class);
}
private static void log(String str)
{
System.out.println("Thread: " + Thread.currentThread() + ": " + str);
}
}