Class MultithreadedTestCase
- Direct Known Subclasses:
MultithreadedTest
initialize()
and finish()
methods
you can override.
A single run of a multithreaded test case consists of:
- Running the
initialize()
method - Running each thread method in a seperate thread
- Running the
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.
- Since:
- 1.0
- See Also:
-
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionvoid
assertTick
(int tick) Assert that the clock is in ticktick
static void
This method is a replacement forCondition.await()
.void
finish()
This method is invoked in a test after after all test threads have finished.void
When the clock is frozen, it will not advance even when all threads are blocked.getThread
(int index) Get a thread corresponding to the method whose name is formed using the prefix "thread" followed by an integer (represented byindex
.getThreadByName
(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()
void
This method is invoked in a test run before any test threads have started.boolean
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.Associates a thread with given method name.void
setTrace
(boolean trace) static void
When this method is called from a thread, the next call towaitOn(Object)
orawaitOn(Condition)
will return immediately without blocking.void
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
(Enum e) An Enum-based version of waitForTick.static void
This method is a replacement forObject.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, failNotEquals, failNotSame, failSame, format
-
Constructor Details
-
MultithreadedTestCase
public MultithreadedTestCase()
-
-
Method Details
-
initialize
public void initialize()This method is invoked in a test run before any test threads have started. -
finish
public void finish()This method is invoked in a test after after all test threads have finished. -
setTrace
public void setTrace(boolean trace) - Parameters:
trace
- the trace to set
-
getTrace
public boolean getTrace()- Returns:
- the trace
-
getThreadByName
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")
NOTE:
initialize()
is called before threads are created, so this method returns null if called frominitialize()
(but not fromfinish()
).- Parameters:
methodName
- the name of the method corresponding to the thread requested- Returns:
- the thread corresponding to methodName
- See Also:
-
getThread
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.NOTE:
initialize()
is called before threads are created, so this method returns null if called frominitialize()
(but not fromfinish()
).- Parameters:
index
- an integer following "thread" in the name of the method- Returns:
- the Thread corresponding to this method
- See Also:
-
putThread
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
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:
-
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
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
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
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
-