package org.multiverse; import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicLong; import static org.junit.Assert.*; /** * A TestThread that tracks if any throwable has been thrown by a thread. * * @author Peter Veentjer. */ public abstract class TestThread extends Thread { private final static AtomicLong idGenerator = new AtomicLong(); private volatile Throwable throwable; private volatile Boolean endedWithInterruptStatus; private volatile boolean startInterrupted; private volatile boolean printStackTrace = true; private long durationMs = -1; private CountDownLatch latch; public TestThread() { this("TestThread-"+idGenerator.incrementAndGet()); } public TestThread(String name) { this(name, false); } public TestThread(String name, boolean startInterrupted) { super(name); this.startInterrupted = startInterrupted; } public void setLatch(CountDownLatch latch) { this.latch = latch; } public void setStartInterrupted(boolean startInterrupted) { this.startInterrupted = startInterrupted; } public void setPrintStackTrace(boolean printStackTrace) { this.printStackTrace = printStackTrace; } public boolean doesStartInterrupted() { return startInterrupted; } public Boolean hasEndedWithInterruptStatus() { return endedWithInterruptStatus; } public long getDurationMs() { return durationMs; } @Override public final void run() { if(latch!=null){ latch.countDown(); } if (startInterrupted) { interrupt(); } long startMs = System.currentTimeMillis(); try { doRun(); } catch (Throwable ex) { if (printStackTrace) { System.out.printf("Thread %s has thrown an exception\n", getName()); ex.printStackTrace(); } this.throwable = ex; } finally { endedWithInterruptStatus = isInterrupted(); durationMs = System.currentTimeMillis() - startMs; } } public abstract void doRun() throws Exception; public Throwable getThrowable() { return throwable; } public void assertInterrupted() { assertFailedWithException(InterruptedException.class); } public void assertEndedWithInterruptStatus(boolean interrupt) { assertEquals(interrupt,endedWithInterruptStatus); } public void assertFailedWithException(Class expected) { assertNotNull(throwable); assertTrue("Found exception: " + throwable.getClass().getName(), throwable.getClass().isAssignableFrom(expected)); } public void assertNothingThrown() { assertNull(throwable); } }