package org.junit.internal.runners; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import org.junit.internal.AssumptionViolatedException; import org.junit.runner.Description; import org.junit.runner.notification.Failure; import org.junit.runner.notification.RunNotifier; import org.junit.runners.BlockJUnit4ClassRunner; import org.junit.runners.model.TestTimedOutException; /** * @deprecated Included for backwards compatibility with JUnit 4.4. Will be * removed in the next major release. Please use * {@link BlockJUnit4ClassRunner} in place of {@link JUnit4ClassRunner}. */ @Deprecated public class MethodRoadie { private final Object test; private final RunNotifier notifier; private final Description description; private TestMethod testMethod; public MethodRoadie(Object test, TestMethod method, RunNotifier notifier, Description description) { this.test = test; this.notifier = notifier; this.description = description; testMethod = method; } public void run() { if (testMethod.isIgnored()) { notifier.fireTestIgnored(description); return; } notifier.fireTestStarted(description); try { long timeout = testMethod.getTimeout(); if (timeout > 0) { runWithTimeout(timeout); } else { runTest(); } } finally { notifier.fireTestFinished(description); } } private void runWithTimeout(final long timeout) { runBeforesThenTestThenAfters(new Runnable() { public void run() { ExecutorService service = Executors.newSingleThreadExecutor(); Callable<Object> callable = new Callable<Object>() { public Object call() throws Exception { runTestMethod(); return null; } }; Future<Object> result = service.submit(callable); service.shutdown(); try { boolean terminated = service.awaitTermination(timeout, TimeUnit.MILLISECONDS); if (!terminated) { service.shutdownNow(); } result.get(0, TimeUnit.MILLISECONDS); // throws the exception if one occurred during the invocation } catch (TimeoutException e) { addFailure(new TestTimedOutException(timeout, TimeUnit.MILLISECONDS)); } catch (Exception e) { addFailure(e); } } }); } public void runTest() { runBeforesThenTestThenAfters(new Runnable() { public void run() { runTestMethod(); } }); } public void runBeforesThenTestThenAfters(Runnable test) { try { runBefores(); test.run(); } catch (FailedBefore e) { } catch (Exception e) { throw new RuntimeException("test should never throw an exception to this level"); } finally { runAfters(); } } protected void runTestMethod() { try { testMethod.invoke(test); if (testMethod.expectsException()) { addFailure(new AssertionError("Expected exception: " + testMethod.getExpectedException().getName())); } } catch (InvocationTargetException e) { Throwable actual = e.getTargetException(); if (actual instanceof AssumptionViolatedException) { return; } else if (!testMethod.expectsException()) { addFailure(actual); } else if (testMethod.isUnexpected(actual)) { String message = "Unexpected exception, expected<" + testMethod.getExpectedException().getName() + "> but was<" + actual.getClass().getName() + ">"; addFailure(new Exception(message, actual)); } } catch (Throwable e) { addFailure(e); } } private void runBefores() throws FailedBefore { try { try { List<Method> befores = testMethod.getBefores(); for (Method before : befores) { before.invoke(test); } } catch (InvocationTargetException e) { throw e.getTargetException(); } } catch (AssumptionViolatedException e) { throw new FailedBefore(); } catch (Throwable e) { addFailure(e); throw new FailedBefore(); } } private void runAfters() { List<Method> afters = testMethod.getAfters(); for (Method after : afters) { try { after.invoke(test); } catch (InvocationTargetException e) { addFailure(e.getTargetException()); } catch (Throwable e) { addFailure(e); // Untested, but seems impossible } } } protected void addFailure(Throwable e) { notifier.fireTestFailure(new Failure(description, e)); } }