Class 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 the Threaded 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 the MultithreadedTest 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 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
    Author:
    William Pugh, Nathaniel Ayewah
    See Also:
    Threaded, MultithreadedTest
    • 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 tick tick
      static void awaitOn​(java.util.concurrent.locks.Condition c)
      This method is a replacement for Condition.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 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()  
      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 to waitOn(Object) or awaitOn(Condition) will return immediately without blocking.
      void unfreezeClock()
      Unfreeze a clock that has been frozen by freezeClock().
      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 for Object.wait().
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Constructor Detail

      • MultithreadedTestCase

        public MultithreadedTestCase()
    • 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 method thread1(), call getThreadByName("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 by index . e.g. getThread(1) returns the thread that thread1() 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 tick tick
        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 a waitForTick(int) in another thread. This statements that occur when clock is frozen should be followed by unfreezeClock() in the same thread.
      • unfreezeClock

        public void unfreezeClock()
        Unfreeze a clock that has been frozen by freezeClock(). 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 to waitOn(Object) or awaitOn(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 for 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.
        Parameters:
        o - the object to wait on
      • awaitOn

        public static void awaitOn​(java.util.concurrent.locks.Condition c)
        This method is a replacement for 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.
        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