Class TestThreadsHolder<T extends Runnable>

java.lang.Object
de.hybris.platform.test.TestThreadsHolder<T>
All Implemented Interfaces:
RunnerCreator<Runnable>

public class TestThreadsHolder<T extends Runnable> extends Object implements RunnerCreator<Runnable>
Allows to let any number of threads start at the same time by starting them up and (internally) waiting until all of them are up and running. This is especially useful when larger numbers of threads are being created for testing purpose because otherwise often creation time outnumbers shorter testing time which at worst would make a parallel test run nearly single threaded.

Also this class provides means to either wait for test threads to finish or to stop them manually via Thread.interrupt().

  • Constructor Summary

    Constructors
    Constructor
    Description
    TestThreadsHolder(int numberOfThreads)
    Creates a specified number of threads that will perform the given runnable logic as soon as startAll() has been invoked.
    TestThreadsHolder(int numberOfThreads, boolean inheritTenant)
    Creates a specified number of threads that will perform the given runnable logic as soon as startAll() has been invoked.
    TestThreadsHolder(int numberOfThreads, RunnerCreator<T> creator)
    Creates a specified number of threads that will perform the logic created by the specified runnable creator as soon as startAll() has been invoked.
    TestThreadsHolder(int numberOfThreads, RunnerCreator<T> creator, boolean inheritTenant)
    Creates a specified number of threads that will perform the logic created by the specified runnable creator as soon as startAll() has been invoked.
    TestThreadsHolder(int numberOfThreads, T runnable)
    Creates a specified number of threads that will perform the given runnable logic as soon as startAll() has been invoked.
    TestThreadsHolder(int numberOfThreads, T runnable, boolean inheritTenant)
    Creates a specified number of threads that will perform the given runnable logic as soon as startAll() has been invoked.
  • Method Summary

    Modifier and Type
    Method
    Description
    int
    Returns the current number of threads that did not complete their testing logic.
    Returns all errors recorded from runner threads.
    getRunner(int pos)
     
     
    long
    If all threads finished in
    boolean
    Tells whether any runner has recorded a error.
    newRunner(int threadNumber)
    Creates a new runnable object for the given runner thread number.
    boolean
    runAll(long duration, TimeUnit unit, int stopWaitSeconds)
    Starts all threads via startAll() and lets them run for the specified duration.
    void
    Allows all runner threads to perform the given test logic.
    void
    Stops all runner threads by invoking Thread.interrupt().
    boolean
    stopAndDestroy(int timeWaitSeconds)
    Attempts to stop all runners via stopAll() and waits for completion for 10 seconds.
    protected boolean
    Override to change latch timeout guarded waiting method.
    boolean
    waitAndDestroy(long terminationWaitSeconds)
    Waits for runner termination for the specified time.
    boolean
    waitForAll(long timeout, TimeUnit unit)
    Waits for all runners to finish their work for a specified amount of time.
    boolean
    waitForPrepared(long timeout, TimeUnit unit)
     

    Methods inherited from class java.lang.Object

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

    • TestThreadsHolder

      public TestThreadsHolder(int numberOfThreads)
      Creates a specified number of threads that will perform the given runnable logic as soon as startAll() has been invoked. Please note that this constructor is intended for creating inner classes only. The newRunner(int) method of this inner class *must* be overwritten!
    • TestThreadsHolder

      public TestThreadsHolder(int numberOfThreads, boolean inheritTenant)
      Creates a specified number of threads that will perform the given runnable logic as soon as startAll() has been invoked. Please note that this constructor is intended for creating inner classes only. The newRunner(int) method of this inner class *must* be overwritten!
    • TestThreadsHolder

      public TestThreadsHolder(int numberOfThreads, T runnable)
      Creates a specified number of threads that will perform the given runnable logic as soon as startAll() has been invoked.

      Please note that technically the actual threads will be immediately created and started. Calling startAll() only releases them from a waiting state.

      Parameters:
      numberOfThreads - the number of runner threads to use
      runnable - the runnable instance being used by each runner thread
    • TestThreadsHolder

      public TestThreadsHolder(int numberOfThreads, T runnable, boolean inheritTenant)
      Creates a specified number of threads that will perform the given runnable logic as soon as startAll() has been invoked.

      Please note that technically the actual threads will be immediately created and started. Calling startAll() only releases them from a waiting state.

      Parameters:
      numberOfThreads - the number of runner threads to use
      runnable - the runnable instance being used by each runner thread
      inheritTenant - if true all runner threads will inherit the current callers tenant, if false no thread will have a active tenant
    • TestThreadsHolder

      public TestThreadsHolder(int numberOfThreads, RunnerCreator<T> creator)
      Creates a specified number of threads that will perform the logic created by the specified runnable creator as soon as startAll() has been invoked.

      Please note that technically the actual threads will be immediately created and started. Calling startAll() only releases them from a waiting state.

      Parameters:
      numberOfThreads - the number of runner threads to use
      creator - the creator responsible for providing a runnable instance for each runner thread
    • TestThreadsHolder

      public TestThreadsHolder(int numberOfThreads, RunnerCreator<T> creator, boolean inheritTenant)
      Creates a specified number of threads that will perform the logic created by the specified runnable creator as soon as startAll() has been invoked.

      Please note that technically the actual threads will be immediately created and started. Calling startAll() only releases them from a waiting state.

      Parameters:
      numberOfThreads - the number of runner threads to use
      creator - the creator responsible for providing a runnable instance for each runner thread
      inheritTenant - if true each runner thread will inherit the current callers tenant, if false all threads will have no active tenant set
  • Method Details

    • useBusyWaiting

      protected boolean useBusyWaiting()
      Override to change latch timeout guarded waiting method.

      As default waiting is done via CountDownLatch.await(long, TimeUnit) which is most efficient for not disturbing workers and returning as quick as possible.

      However if you're suffering from JVM being blocked often (not getting computing time for minutes) for instance when running in a virtual environment it may be better to change timeout method to busily counting 'ticks'. In that case the latch is tested many times waiting at most one second. In case the JVM is being blocked for a longer time the timeout mechanism simply continues where it was blocked giving workers a fair chance to finished their work, even if it means that the actual timeout period is greatly exceeded!

    • newRunner

      public Runnable newRunner(int threadNumber)
      Description copied from interface: RunnerCreator
      Creates a new runnable object for the given runner thread number.
      Specified by:
      newRunner in interface RunnerCreator<T extends Runnable>
    • waitForPrepared

      public boolean waitForPrepared(long timeout, TimeUnit unit)
    • startAll

      public void startAll()
      Allows all runner threads to perform the given test logic. Ensures that all threads are up and running, which means that thread creation and startup overhead does not affect the tested logic at all.

      You may either wait for them to terminate on their own by calling waitForAll(long, TimeUnit) or stop them after some time via stopAll()

      See Also:
    • runAll

      public boolean runAll(long duration, TimeUnit unit, int stopWaitSeconds)
      Starts all threads via startAll() and lets them run for the specified duration.

      After that all threads are stopped via stopAndDestroy(int) and the stop result is being returned.

      Parameters:
      duration - the time to run
      unit - the unit of time to run
      stopWaitSeconds - the time to wait after stopping threads before killing them 'the hard way'
    • stopAll

      public void stopAll()
      Stops all runner threads by invoking Thread.interrupt(). Please make sure that the tested logic is handling thread interrupts correctly, which means either to pass on the InterruptedException or restoring the interrupted flag via Thread.interrupt()!
    • stopAndDestroy

      public boolean stopAndDestroy(int timeWaitSeconds)
      Attempts to stop all runners via stopAll() and waits for completion for 10 seconds. If for some reason this doesn't work it will unsafely stop all runners via Thread.stop().
      Returns:
      true in case all runners finished orderly, false otherwise
    • waitAndDestroy

      public boolean waitAndDestroy(long terminationWaitSeconds)
      Waits for runner termination for the specified time. If for some reason this doesn't work it will first try to stop them via interrupt, wait for terminationWaitSeconds/2 and only if this doesn't succeed all remaining workers will be unsafely stopped via Thread.stop().
      Parameters:
      terminationWaitSeconds - the time to wait for runner thread termination in seconds; after this time has elapsed it will unsafely kill them via Thread.stop()
    • getStartToFinishMillis

      public long getStartToFinishMillis()
      If all threads finished in
    • getAlive

      public int getAlive()
      Returns the current number of threads that did not complete their testing logic.

      Technically more threads than the returned number may be still alive, but as soon as they have completed their 'payload' they will definitely terminate so there is no need to wait for that.

    • waitForAll

      public boolean waitForAll(long timeout, TimeUnit unit)
      Waits for all runners to finish their work for a specified amount of time.
      Returns:
      true in case all runners did really finish, false otherwise
    • hasErrors

      public boolean hasErrors()
      Tells whether any runner has recorded a error.
      See Also:
    • getErrors

      public Map<Integer,Throwable> getErrors()
      Returns all errors recorded from runner threads.

      Please note that InterruptedException will not be recorded since this we prefer thread interrupt as valid way of stopping runners.

      See Also:
    • getRunners

      public List<T> getRunners()
    • getRunner

      public T getRunner(int pos)