blob: bff7c723510785cb8e1243c22877481b082c1017 [file] [log] [blame]
/**
*
*/
package org.junit.internal.runners.statements;
import org.junit.runners.model.Statement;
public class FailOnTimeout extends Statement {
private final Statement fOriginalStatement;
private final long fTimeout;
public FailOnTimeout(Statement originalStatement, long timeout) {
fOriginalStatement= originalStatement;
fTimeout= timeout;
}
@Override
public void evaluate() throws Throwable {
StatementThread thread= evaluateStatement();
if (!thread.fFinished)
throwExceptionForUnfinishedThread(thread);
}
private StatementThread evaluateStatement() throws InterruptedException {
StatementThread thread= new StatementThread(fOriginalStatement);
thread.start();
thread.join(fTimeout);
thread.interrupt();
return thread;
}
private void throwExceptionForUnfinishedThread(StatementThread thread)
throws Throwable {
if (thread.fExceptionThrownByOriginalStatement != null)
throw thread.fExceptionThrownByOriginalStatement;
else
throwTimeoutException(thread);
}
private void throwTimeoutException(StatementThread thread) throws Exception {
Exception exception= new Exception(String.format(
"test timed out after %d milliseconds", fTimeout));
exception.setStackTrace(thread.getStackTrace());
throw exception;
}
private static class StatementThread extends Thread {
private final Statement fStatement;
private boolean fFinished= false;
private Throwable fExceptionThrownByOriginalStatement= null;
public StatementThread(Statement statement) {
fStatement= statement;
}
@Override
public void run() {
try {
fStatement.evaluate();
fFinished= true;
} catch (InterruptedException e) {
//don't log the InterruptedException
} catch (Throwable e) {
fExceptionThrownByOriginalStatement= e;
}
}
}
}