package org.jboss.test.cache.test.eviction;
import java.util.Random;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.apache.log4j.Logger;
import org.jboss.cache.Fqn;
import org.jboss.cache.PropertyConfigurator;
import org.jboss.cache.TreeCache;
import org.jboss.cache.eviction.RegionManager;
public final class ConcurrentEvictAndRemoveTestCase extends TestCase
{
private static final Logger logger = Logger.getLogger(ConcurrentEvictAndRemoveTestCase.class.getName());
private TreeCache cache;
static void log(String msg) {
System.out.println(msg);
logger.info(msg);
}
void err(String msg) {
System.err.println(msg);
logger.error(msg);
}
public ConcurrentEvictAndRemoveTestCase(String name)
{
super(name);
}
public void setUp() throws Exception
{
cache = new TreeCache();
cache.setCacheMode(TreeCache.LOCAL);
PropertyConfigurator config = new PropertyConfigurator();
config.configure(cache, "META-INF/local-eviction-service.xml");
cache.setTransactionManagerLookupClass("org.jboss.cache.DummyTransactionManagerLookup");
cache.start();
}
public void tearDown() throws Exception
{
cache.stop();
}
public void test() throws Exception
{
final long MAX_LOOP_TIME = 4000; int numberOfInitialCreatedNodes = 0;
log("*** Start Test: ConcurrentEvictAndRemoveTest ***");
{
final StopWatch stopWatch = new StopWatch();
int i = 0;
while(true) {
i++;
final Fqn fqn = Fqn.fromString("/test/item_" + i);
cache.put(fqn, "att", null);
if (stopWatch.getTime()>MAX_LOOP_TIME) {
break;
}
}
numberOfInitialCreatedNodes = i;
log(
"nodes created: "
+ numberOfInitialCreatedNodes
+ " time: "
+ stopWatch.getTime()
+ " ms"
);
}
{
int numberCacheHitSuccess = 0;
int numberCacheHitFailure = 0;
final Random random = new Random();
final StopWatch stopWatch = new StopWatch();
while(true) {
final Fqn fqn = Fqn.fromString("/test/item_" + random.nextInt(numberOfInitialCreatedNodes));
if (cache.exists(fqn)) {
cache.remove(fqn);
numberCacheHitSuccess++;
} else {
numberCacheHitFailure++;
}
if (stopWatch.getTime()>MAX_LOOP_TIME) {
break;
}
}
log(
"nodes removed: "
+ numberCacheHitSuccess
+ ", total cache hits: "
+ (numberCacheHitFailure + numberCacheHitSuccess)
+ " time: "
+ stopWatch.getTime()
+ " ms"
);
}
{
log("create put/remove events");
final int SEQUENCE_SIZE = 10000; final long TIMEOUT_DEFAULT = 100000;
final int MAX_TIMEOUT_FACTOR = 10;
for(int i = 0; i < RegionManager.CAPACITY; i = i + SEQUENCE_SIZE) {
final int sequenceStart = i;
final int sequenceEnd = i + SEQUENCE_SIZE -1;
Thread thread = new Thread(
new HelperThread(cache, sequenceStart, sequenceEnd)
);
long timeout = (HelperThread.getTime()==HelperThread.EXECUTION_TIME_NOT_INITIALIZED)?
TIMEOUT_DEFAULT:
HelperThread.getTime()*MAX_TIMEOUT_FACTOR;
thread.start();
try {
thread.join(timeout);
if (thread.isAlive()) {
err("Timeout of " + timeout + " ms exceeded for sequence of put/remove operations.");
fail("Timeout of " + timeout + " ms exceeded for sequence of put/remove operations.");
} else {
}
}
catch(InterruptedException ignore) {
err("Thread join interrupted.");
}
}
}
log("*** Successfully finished! ***");
}
public static Test suite() throws Exception
{
return new TestSuite(ConcurrentEvictAndRemoveTestCase.class);
}
private static final class StopWatch {
public StopWatch() {
startTime = System.currentTimeMillis() ;
}
private final long startTime;
public String toString() {
return String.valueOf(getTime());
}
public long getTime() {
return System.currentTimeMillis() - startTime;
}
}
private static final class HelperThread implements Runnable {
private static final Logger logger = Logger.getLogger(HelperThread.class.getName());
private final TreeCache cache;
private final int start;
private final int end;
public static final long EXECUTION_TIME_NOT_INITIALIZED = -1;
private static long previousExceutionTime = EXECUTION_TIME_NOT_INITIALIZED;
private static final String FQN_PREFIX = "/test/overflow-item_";
public HelperThread ( TreeCache cache, int start, int end) {
this.cache = cache;
this.start = start;
this.end = end;
}
public void run() {
StopWatch stopWatch = new StopWatch();
log(
"process node range: "
+ this.start
+ "/"
+ this.end
);
try {
for (int i = start; i<=end; i++) {
final Fqn fqn = Fqn.fromString(FQN_PREFIX + i);
cache.put(fqn, "att", null);
cache.remove(fqn);
}
} catch (Exception e) {
System.out.println("exception: " + e);
if ( e instanceof RuntimeException) {
throw (RuntimeException)e;
} else {
throw new RuntimeException(e);
}
}
previousExceutionTime = stopWatch.getTime();
log(
"time: "
+ previousExceutionTime
+ " ms"
);
}
public static long getTime() {
return previousExceutionTime;
}
}
}