|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object junit.framework.Assert edu.umd.cs.mtc.MultithreadedTestCase
public abstract class MultithreadedTestCase
This is the base class for each test in the MultithreadedTC framework.
To create a multithreaded test case, simply extend this class. Any method
with a name that starts with "thread", that has no parameters and a void
return type is a thread method. Each thread method will be run in a seperate
thread. This class also defines initialize()
and finish()
methods
you can override.
A single run of a multithreaded test case consists of:
initialize()
method
finish()
method when all threads are done.
The method TestFramework.runOnce(MultithreadedTestCase)
can be used
to run a MultithreadedTestCase once. The method
TestFramework.runManyTimes(MultithreadedTestCase, int)
can be used to
run a multithread test case multiple times (to see if different interleavings
produce different behaviors).
There are several additional methods you can use in designing test cases. The
MultithreadedTestCase maintains a metronome or clock, and ticks off
intervals. You can get the current tick with getTick()
and you can
wait until a particular tick with waitForTick(int)
. The metronome
isn't a free running clock; it only advances to the next tick when all
threads are blocked or waiting. Also, when all threads are blocked, if at least one
thread isn't waiting for the metronome to advance, the system declares a
deadlock to have occurred and terminates the test case (unless one of the
threads is in state TIMED_WAITING).
You can set a command line parameter -Dtunit.trace=true to cause tracing
messages to be printed by the metronome frame, or invoke
setTrace(boolean)
to turn tracing on or off.
You can set command line parameter -Dtunit.runLimit=10 to cause a test case to fail if at least one thread stays in a runnable state for more than 10 seconds without becoming blocked or waiting for a metronome tick. Use different values for shorter or longer time limits.
TestFramework
Field Summary | |
---|---|
(package private) int |
clock
The metronome used to coordinate between threads. |
(package private) java.util.concurrent.locks.ReentrantReadWriteLock |
clockLock
Read locks are acquired when clock is frozen and must be released before the clock can advance in a waitForTick(). |
(package private) static java.lang.ThreadLocal<MultithreadedTestCase> |
currentTestCase
ThreadLocal containing a reference to the current instance of this class for each thread. |
(package private) boolean |
failed
This flag is set to true when a test fails due to deadlock or timeout. |
(package private) java.lang.Object |
lock
The primary lock to synchronize on in this test case before accessing fields in this class. |
(package private) java.util.HashMap<java.lang.String,java.lang.Thread> |
methodThreads
Map a thread name to all test case threads as they are created, primarily so that they can be accessed by each other. |
(package private) java.util.IdentityHashMap<java.lang.Thread,java.lang.Integer> |
threads
Map each thread to the clock tick it is waiting for. |
Constructor Summary | |
---|---|
MultithreadedTestCase()
|
Method Summary | |
---|---|
void |
assertTick(int tick)
Assert that the clock is in tick tick |
static void |
awaitOn(java.util.concurrent.locks.Condition c)
This method is a replacement for Condition.await() . |
void |
finish()
This method is invoked in a test after after all test threads have finished. |
void |
freezeClock()
When the clock is frozen, it will not advance even when all threads are blocked. |
java.lang.Thread |
getThread(int index)
Get a thread corresponding to the method whose name is formed using the prefix "thread" followed by an integer (represented by index . |
java.lang.Thread |
getThreadByName(java.lang.String methodName)
Get a thread given the method name that it corresponds to. |
int |
getTick()
Gets the current value of the thread metronome. |
boolean |
getTrace()
|
(package private) void |
goodbye()
This method is called just before a testcase thread completes. |
(package private) void |
hello()
This method is called right after a new testcase thread is created by the TestFramework . |
void |
initialize()
This method is invoked in a test run before any test threads have started. |
boolean |
isClockFrozen()
Check if the clock has been frozen by any threads. |
java.lang.Thread |
putThread(java.lang.String methodName,
java.lang.Thread t)
Associates a thread with given method name. |
void |
setTrace(boolean trace)
|
static void |
skipNextWait()
When this method is called from a thread, the next call to waitOn(Object) or awaitOn(Condition) will return
immediately without blocking. |
void |
unfreezeClock()
Unfreeze a clock that has been frozen by freezeClock() . |
void |
waitForTick(java.lang.Enum e)
An Enum-based version of waitForTick. |
void |
waitForTick(int c)
Force this thread to block until the thread metronome reaches the specified value, at which point the thread is unblocked. |
static void |
waitOn(java.lang.Object o)
This method is a replacement for Object.wait() . |
Methods inherited from class junit.framework.Assert |
---|
assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertFalse, assertFalse, assertNotNull, assertNotNull, assertNotSame, assertNotSame, assertNull, assertNull, assertSame, assertSame, assertTrue, assertTrue, fail, fail |
Methods inherited from class java.lang.Object |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Field Detail |
---|
int clock
TestFramework
.
The clock will not advance if it is frozen.
waitForTick(int)
,
freezeClock()
,
unfreezeClock()
java.lang.Object lock
boolean failed
TestFramework
java.util.IdentityHashMap<java.lang.Thread,java.lang.Integer> threads
static java.lang.ThreadLocal<MultithreadedTestCase> currentTestCase
java.util.HashMap<java.lang.String,java.lang.Thread> methodThreads
getThreadByName(String)
,
getThread(int)
final java.util.concurrent.locks.ReentrantReadWriteLock clockLock
Constructor Detail |
---|
public MultithreadedTestCase()
Method Detail |
---|
public void initialize()
public void finish()
public void setTrace(boolean trace)
trace
- the trace to setpublic boolean getTrace()
void hello()
TestFramework
. It provides initial values for
currentTestCase
and threads
.
void goodbye()
currentTestCase
and threads
.
public java.lang.Thread getThreadByName(java.lang.String methodName)
thread1()
, call getThreadByName("thread1")
NOTE: initialize()
is called before threads are created,
so this method returns null if called from initialize()
(but not from finish()
).
methodName
- the name of the method corresponding to the thread requested
getThread(int)
public java.lang.Thread getThread(int index)
index
. e.g. getThread(1) returns the thread
that thread1()
is running in.
NOTE: initialize()
is called before threads are created,
so this method returns null if called from initialize()
(but not from finish()
).
index
- an integer following "thread" in the name of the method
getThreadByName(String)
public java.lang.Thread putThread(java.lang.String methodName, java.lang.Thread t)
public void waitForTick(int c)
c
- the tick value to wait forpublic void waitForTick(java.lang.Enum e)
e
- An Enum representing the tick to wait for. The first enumeration
constant represents tick 1, the second is tick 2, etc.waitForTick(int)
public int getTick()
assertTick(int)
public void assertTick(int tick)
tick
tick
- a number >= 0public void freezeClock()
waitForTick(int)
in
another thread. This statements that occur when clock is frozen should be
followed by unfreezeClock()
in the same thread.
public void unfreezeClock()
freezeClock()
. Both
methods must be called from the same thread.
public boolean isClockFrozen()
public static void skipNextWait()
waitOn(Object)
or awaitOn(Condition)
will return
immediately without blocking. Use this to make tests more robust.
public static void waitOn(java.lang.Object o)
Object.wait()
. It suppresses
the InterruptedException
that you would otherwise have to
deal with, and allows automated skipping of the next wait. The
method skipNextWait()
will force that thread to immediately return
from the next call to this method.
Designing your tests so that they work even if Object.wait()
occasionally returns immediately will make your code
much more robust in face of several potential threading issues.
o
- the object to wait onpublic static void awaitOn(java.util.concurrent.locks.Condition c)
Condition.await()
. It suppresses
the InterruptedException
that you would otherwise have to
deal with, and allows automated skipping of the next wait. The
method skipNextWait()
will force that thread to immediately return
from the next call to this method.
Designing your tests so that they work even if Condition.await()
occasionally returns immediately will make your code
much more robust in face of several potential threading issues.
c
- the condition to await on
|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |