Package edu.umd.cs.mtc
Class MultithreadedTestCase
- java.lang.Object
-
- edu.umd.cs.mtc.MultithreadedTestCase
-
public abstract class MultithreadedTestCase extends java.lang.Object
This is the base class for each test in the MultithreadedTC framework. To create a multithreaded test case, simply extend this class. Any method annotated with theThreaded
annotation is a thread method. Each thread method will be run in a seperate thread. JUnit test methods in your class will be run after the thread methods have finished. You can annotate your junit test methods with theMultithreadedTest
method to specify how many times the threaded methods should be run before the junit test method is executed. 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 withgetTick()
and you can wait until a particular tick withwaitForTick(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 invokesetTrace(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.- Since:
- 1.0
- Author:
- William Pugh, Nathaniel Ayewah
- See Also:
Threaded
,MultithreadedTest
-
-
Constructor Summary
Constructors Constructor Description MultithreadedTestCase()
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description void
assertTick(int tick)
Assert that the clock is in ticktick
static void
awaitOn(java.util.concurrent.locks.Condition c)
This method is a replacement forCondition.await()
.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 byindex
.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()
boolean
isClockFrozen()
Check if the clock has been frozen by any threads.void
mayYield()
Calling this method from one of the test threads may cause the thread to yield.void
mayYield(double probability)
Calling this method from one of the test threads may cause the thread to yield.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 towaitOn(Object)
orawaitOn(Condition)
will return immediately without blocking.void
unfreezeClock()
Unfreeze a clock that has been frozen byfreezeClock()
.void
waitForTick(int c)
Force this thread to block until the thread metronome reaches the specified value, at which point the thread is unblocked.void
waitForTick(java.lang.Enum<?> e)
An Enum-based version of waitForTick.static void
waitOn(java.lang.Object o)
This method is a replacement forObject.wait()
.
-
-
-
Method Detail
-
setTrace
public void setTrace(boolean trace)
- Parameters:
trace
- the trace to set
-
getTrace
public boolean getTrace()
- Returns:
- the trace
-
getThreadByName
public java.lang.Thread getThreadByName(java.lang.String methodName)
Get a thread given the method name that it corresponds to. E.g. to get the thread running the contents of the methodthread1()
, callgetThreadByName("thread1")
- Parameters:
methodName
- the name of the method corresponding to the thread requested- Returns:
- the thread corresponding to methodName
- See Also:
getThread(int)
-
getThread
public 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 byindex
. e.g. getThread(1) returns the thread thatthread1()
is running in.- Parameters:
index
- an integer following "thread" in the name of the method- Returns:
- the Thread corresponding to this method
- See Also:
getThreadByName(String)
-
putThread
public java.lang.Thread putThread(java.lang.String methodName, java.lang.Thread t)
Associates a thread with given method name. If the method name is already associated with a Thread, the old thread is returned, otherwise null is returned
-
waitForTick
public void waitForTick(int c)
Force this thread to block until the thread metronome reaches the specified value, at which point the thread is unblocked.- Parameters:
c
- the tick value to wait for
-
waitForTick
public void waitForTick(java.lang.Enum<?> e)
An Enum-based version of waitForTick. It simply looks up the ordinal and adds 1 to determine the clock tick to wait for.- Parameters:
e
- An Enum representing the tick to wait for. The first enumeration constant represents tick 1, the second is tick 2, etc.- See Also:
waitForTick(int)
-
getTick
public int getTick()
Gets the current value of the thread metronome. Primarily useful in assert statements.- Returns:
- the current tick value
- See Also:
assertTick(int)
-
assertTick
public void assertTick(int tick)
Assert that the clock is in ticktick
- Parameters:
tick
- a number >= 0
-
freezeClock
public void freezeClock()
When the clock is frozen, it will not advance even when all threads are blocked. Use this to block the current thread with a time limit, but prevent the clock from advancing due to awaitForTick(int)
in another thread. This statements that occur when clock is frozen should be followed byunfreezeClock()
in the same thread.
-
unfreezeClock
public void unfreezeClock()
Unfreeze a clock that has been frozen byfreezeClock()
. Both methods must be called from the same thread.
-
isClockFrozen
public boolean isClockFrozen()
Check if the clock has been frozen by any threads.
-
skipNextWait
public static void skipNextWait()
When this method is called from a thread, the next call towaitOn(Object)
orawaitOn(Condition)
will return immediately without blocking. Use this to make tests more robust.
-
waitOn
public static void waitOn(java.lang.Object o)
This method is a replacement forObject.wait()
. It suppresses theInterruptedException
that you would otherwise have to deal with, and allows automated skipping of the next wait. The methodskipNextWait()
will force that thread to immediately return from the next call to this method. Designing your tests so that they work even ifObject.wait()
occasionally returns immediately will make your code much more robust in face of several potential threading issues.- Parameters:
o
- the object to wait on
-
awaitOn
public static void awaitOn(java.util.concurrent.locks.Condition c)
This method is a replacement forCondition.await()
. It suppresses theInterruptedException
that you would otherwise have to deal with, and allows automated skipping of the next wait. The methodskipNextWait()
will force that thread to immediately return from the next call to this method. Designing your tests so that they work even ifCondition.await()
occasionally returns immediately will make your code much more robust in face of several potential threading issues.- Parameters:
c
- the condition to await on
-
mayYield
public void mayYield()
Calling this method from one of the test threads may cause the thread to yield. Use this between statements to generate more interleavings.
-
mayYield
public void mayYield(double probability)
Calling this method from one of the test threads may cause the thread to yield. Use this between statements to generate more interleavings.- Parameters:
probability
- (a number between 0 and 1) the likelihood that Thread.yield() is called
-
-