/** Checks that the threads do not terminate within the given millisecond delay. */ void assertThreadsStayAlive(long millis, Thread... threads) { try { // No need to optimize the failing case via Thread.join. delay(millis); for (Thread thread : threads) assertTrue(thread.isAlive()); } catch (InterruptedException ie) { fail("Unexpected InterruptedException"); } }
/** * Waits for the specified time (in milliseconds) for the thread to terminate (using {@link * Thread#join(long)}), else interrupts the thread (in the hope that it may terminate later) and * fails. */ void awaitTermination(Thread t, long timeoutMillis) { try { t.join(timeoutMillis); } catch (InterruptedException ie) { threadUnexpectedException(ie); } finally { if (t.getState() != Thread.State.TERMINATED) { t.interrupt(); fail("Test timed out"); } } }
/** * Delays, via Thread.sleep, for the given millisecond delay, but if the sleep is shorter than * specified, may re-sleep or yield until time elapses. */ static void delay(long millis) throws InterruptedException { long startTime = System.nanoTime(); long ns = millis * 1000 * 1000; for (; ; ) { if (millis > 0L) Thread.sleep(millis); else // too short to sleep Thread.yield(); long d = ns - (System.nanoTime() - startTime); if (d > 0L) millis = d / (1000 * 1000); else break; } }
/** * Spin-waits up to the specified number of milliseconds for the given thread to enter a wait * state: BLOCKED, WAITING, or TIMED_WAITING. */ void waitForThreadToEnterWaitState(Thread thread, long timeoutMillis) { long startTime = System.nanoTime(); for (; ; ) { Thread.State s = thread.getState(); if (s == Thread.State.BLOCKED || s == Thread.State.WAITING || s == Thread.State.TIMED_WAITING) return; else if (s == Thread.State.TERMINATED) fail("Unexpected thread termination"); else if (millisElapsedSince(startTime) > timeoutMillis) { threadAssertTrue(thread.isAlive()); return; } Thread.yield(); } }
public final void run() { try { realRun(); threadShouldThrow("InterruptedException"); } catch (InterruptedException success) { threadAssertFalse(Thread.interrupted()); } catch (Throwable t) { threadUnexpectedException(t); } }
public final T call() { try { T result = realCall(); threadShouldThrow("InterruptedException"); return result; } catch (InterruptedException success) { threadAssertFalse(Thread.interrupted()); } catch (Throwable t) { threadUnexpectedException(t); } return null; }
/** * Extra checks that get done for all test cases. * * <p>Triggers test case failure if any thread assertions have failed, by rethrowing, in the test * harness thread, any exception recorded earlier by threadRecordFailure. * * <p>Triggers test case failure if interrupt status is set in the main thread. */ public void tearDown() throws Exception { Throwable t = threadFailure.getAndSet(null); if (t != null) { if (t instanceof Error) throw (Error) t; else if (t instanceof RuntimeException) throw (RuntimeException) t; else if (t instanceof Exception) throw (Exception) t; else { AssertionFailedError afe = new AssertionFailedError(t.toString()); afe.initCause(t); throw afe; } } if (Thread.interrupted()) throw new AssertionFailedError("interrupt status set in main thread"); }
/** Returns a new started daemon Thread running the given runnable. */ Thread newStartedThread(Runnable runnable) { Thread t = new Thread(runnable); t.setDaemon(true); t.start(); return t; }