package org.jboss.test.cache.stress;
import EDU.oswego.cs.dl.util.concurrent.Sync;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.jboss.cache.lock.ReadWriteLockWithUpgrade;
import org.jboss.logging.Logger;
public class ReadWriteLockWithUpgradeStressTestCase extends TestCase
{
static final ReadWriteLockWithUpgrade lock_ = new ReadWriteLockWithUpgrade();
static final long SLEEP_MSECS = 50;
static final int LOOPS = 200;
static int SEED = 1;
static Logger log_ = Logger.getLogger("ReadWriteLockWithUpgrade");
int counter;
public ReadWriteLockWithUpgradeStressTestCase(String name)
{
super(name);
}
public static void main(String[] args) throws Exception
{
log("\nBeginning ReadWriteLockWithUpgrade automated testing ...\n");
junit.textui.TestRunner.run(suite());
}
public static Test suite()
{
TestSuite suite = new TestSuite();
suite.addTestSuite(ReadWriteLockWithUpgradeStressTestCase.class);
return suite;
}
public void setUp()
{
log("Setting up stress test case ...");
counter = 0;
}
public void tearDown()
{
log("Tearing down stress test case ...");
}
protected Thread readAttemptThread(String name, final long msecs)
{
return new Thread(name)
{
public void run()
{
java.util.Random rand = new java.util.Random(++SEED);
for (int i = 0; i < LOOPS; i++) {
int duration = rand.nextInt((int) SLEEP_MSECS);
_sleep(SLEEP_MSECS);
Sync rlock = null;
try {
rlock = lock_.readLock();
if (!rlock.attempt(msecs)) {
log("Read lock attempt failed.");
counter++;
continue;
}
log("acquired read lock");
_sleep(duration);
log("released read lock");
} catch (Exception ex) {
}
finally {
rlock.release();
}
}
}
};
}
protected Thread writeAttemptThread(String name, final long msecs)
{
return new Thread(name)
{
public void run()
{
java.util.Random rand = new java.util.Random(++SEED);
for (int i = 0; i < LOOPS; i++) {
int duration = rand.nextInt((int) SLEEP_MSECS);
_sleep(SLEEP_MSECS + duration);
Sync wlock = null;
try {
wlock = lock_.writeLock();
if (!wlock.attempt(msecs)) {
log("Write lock attempt failed.");
counter++;
continue;
}
log("acquired write lock");
_sleep(duration);
log("released write lock");
} catch (Exception ex) {
}
finally {
wlock.release();
}
}
}
};
}
protected Thread upgradeAttemptThread(String name, final long msecs)
{
return new Thread(name)
{
public void run()
{
java.util.Random rand = new java.util.Random(++SEED);
for (int i = 0; i < LOOPS; i++) {
int duration = rand.nextInt((int) SLEEP_MSECS);
_sleep(SLEEP_MSECS);
Sync rlock = null;
Sync wlock = null;
try {
rlock = lock_.readLock();
if (!wlock.attempt(msecs)) {
log("Read lock attempt failed.");
counter++;
continue;
}
log("Acquired read lock for upgrade later");
_sleep(duration / 2);
wlock = lock_.upgradeLockAttempt(msecs);
if (wlock == null) {
log("upgrade lock attempt failed");
rlock.release();
counter++;
}
log("Upgraded write lock");
_sleep(duration);
log("released write lock");
} catch (Exception ex) {
}
finally {
if(wlock != null)
wlock.release();
}
}
}
};
}
private void _sleep(long l) {
try {
Thread.sleep(l);
}
catch(InterruptedException e) {
e.printStackTrace();
}
}
public void testWriteWriteAttempt() throws Exception
{
log("testWriteWriteAttempt() ...");
final long msecs = 1000;
Thread t1 = writeAttemptThread("t1-write", msecs);
Thread t2 = writeAttemptThread("t2-write", msecs);
Thread t3 = writeAttemptThread("t3-write", msecs);
Thread t4 = writeAttemptThread("t4-write", msecs);
t1.start();
t2.start();
t3.start();
t4.start();
long timeout = 0;
t1.join(timeout);
t2.join(timeout);
t3.join(timeout);
t4.join(timeout);
checkCounter();
}
public void testReadWriteAttempt1() throws Exception
{
log("testReadWriteAttemp1() ...");
final long msecs = 2000;
Thread t1 = readAttemptThread("t1-read", msecs);
Thread t2 = readAttemptThread("t2-read", msecs);
Thread t3 = writeAttemptThread("t3-write", msecs);
Thread t4 = writeAttemptThread("t4-write", msecs);
Thread t5 = upgradeAttemptThread("t5-upgrade", msecs);
Thread t6 = upgradeAttemptThread("t6-upgrade", msecs);
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
t6.start();
long timeout = 0;
t1.join(timeout);
t2.join(timeout);
t3.join(timeout);
t4.join(timeout);
t5.join(timeout);
t6.join(timeout);
checkCounter();
}
public void testReadWriteAttempt2() throws Exception
{
log("**************");
log("testReadWriteAttemp2() ...");
log("**************");
SEED++;
final long msecs = 1000;
Thread t1 = readAttemptThread("t1-read", msecs);
Thread t3 = writeAttemptThread("t3-write", msecs);
Thread t5 = upgradeAttemptThread("t5-upgrade", msecs);
Thread t6 = upgradeAttemptThread("t6-upgrade", msecs);
t1.start();
t3.start();
t5.start();
t6.start();
long timeout = 0;
t1.join(timeout);
t3.join(timeout);
t5.join(timeout);
t6.join(timeout);
checkCounter();
}
public void testReadWriteAttempt3() throws Exception
{
log("**************");
log("testReadWriteAttemp3() ...");
log("**************");
SEED++;
final long msecs = 1000;
Thread t1 = readAttemptThread("t1-read", msecs);
Thread t2 = readAttemptThread("t2-read", msecs);
Thread t3 = writeAttemptThread("t3-write", msecs);
Thread t4 = writeAttemptThread("t4-write", msecs);
Thread t6 = upgradeAttemptThread("t6-upgrade", msecs);
t1.start();
t2.start();
t3.start();
t4.start();
t6.start();
long timeout = 0;
t1.join(timeout);
t2.join(timeout);
t3.join(timeout);
t4.join(timeout);
t6.join(timeout);
checkCounter();
}
private void checkCounter() {
if(counter > (LOOPS) )
fail("Failed lock attempt or upgrade exceeded warning. Counter: "+counter);
}
public static void log(String str)
{
log_.debug(Thread.currentThread() + ": "
+ " : " + str);
}
}