Home | History | Annotate | Download | only in statements
      1 /**
      2  *
      3  */
      4 package org.junit.internal.runners.statements;
      5 
      6 import org.junit.runners.model.Statement;
      7 
      8 public class FailOnTimeout extends Statement {
      9 	private final Statement fOriginalStatement;
     10 
     11 	private final long fTimeout;
     12 
     13 	public FailOnTimeout(Statement originalStatement, long timeout) {
     14 		fOriginalStatement= originalStatement;
     15 		fTimeout= timeout;
     16 	}
     17 
     18 	@Override
     19 	public void evaluate() throws Throwable {
     20 		StatementThread thread= evaluateStatement();
     21 		if (!thread.fFinished)
     22 			throwExceptionForUnfinishedThread(thread);
     23 	}
     24 
     25 	private StatementThread evaluateStatement() throws InterruptedException {
     26 		StatementThread thread= new StatementThread(fOriginalStatement);
     27 		thread.start();
     28 		thread.join(fTimeout);
     29 		thread.interrupt();
     30 		return thread;
     31 	}
     32 
     33 	private void throwExceptionForUnfinishedThread(StatementThread thread)
     34 			throws Throwable {
     35 		if (thread.fExceptionThrownByOriginalStatement != null)
     36 			throw thread.fExceptionThrownByOriginalStatement;
     37 		else
     38 			throwTimeoutException(thread);
     39 	}
     40 
     41 	private void throwTimeoutException(StatementThread thread) throws Exception {
     42 		Exception exception= new Exception(String.format(
     43 				"test timed out after %d milliseconds", fTimeout));
     44 		exception.setStackTrace(thread.getStackTrace());
     45 		throw exception;
     46 	}
     47 
     48 	private static class StatementThread extends Thread {
     49 		private final Statement fStatement;
     50 
     51 		private boolean fFinished= false;
     52 
     53 		private Throwable fExceptionThrownByOriginalStatement= null;
     54 
     55 		public StatementThread(Statement statement) {
     56 			fStatement= statement;
     57 		}
     58 
     59 		@Override
     60 		public void run() {
     61 			try {
     62 				fStatement.evaluate();
     63 				fFinished= true;
     64 			} catch (InterruptedException e) {
     65 				//don't log the InterruptedException
     66 			} catch (Throwable e) {
     67 				fExceptionThrownByOriginalStatement= e;
     68 			}
     69 		}
     70 	}
     71 }