| /** |
| * |
| */ |
| 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; |
| } |
| } |
| } |
| } |