Open Source Repository

Home /junit/junit-4.10 | Repository Home



org/junit/internal/runners/statements/FailOnTimeout.java
/**
 
 */
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 threadthrows 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;
      }
    }
  }
}