aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org/junit/internal/runners/MethodRoadie.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org/junit/internal/runners/MethodRoadie.java')
-rw-r--r--src/main/java/org/junit/internal/runners/MethodRoadie.java157
1 files changed, 157 insertions, 0 deletions
diff --git a/src/main/java/org/junit/internal/runners/MethodRoadie.java b/src/main/java/org/junit/internal/runners/MethodRoadie.java
new file mode 100644
index 0000000..4407821
--- /dev/null
+++ b/src/main/java/org/junit/internal/runners/MethodRoadie.java
@@ -0,0 +1,157 @@
+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;
+
+/**
+ * @deprecated Included for backwards compatibility with JUnit 4.4. Will be
+ * removed in the next release. Please use
+ * {@link BlockJUnit4ClassRunner} in place of {@link JUnit4ClassRunner}.
+ */
+@Deprecated
+public class MethodRoadie {
+ private final Object fTest;
+ private final RunNotifier fNotifier;
+ private final Description fDescription;
+ private TestMethod fTestMethod;
+
+ public MethodRoadie(Object test, TestMethod method, RunNotifier notifier, Description description) {
+ fTest= test;
+ fNotifier= notifier;
+ fDescription= description;
+ fTestMethod= method;
+ }
+
+ public void run() {
+ if (fTestMethod.isIgnored()) {
+ fNotifier.fireTestIgnored(fDescription);
+ return;
+ }
+ fNotifier.fireTestStarted(fDescription);
+ try {
+ long timeout= fTestMethod.getTimeout();
+ if (timeout > 0)
+ runWithTimeout(timeout);
+ else
+ runTest();
+ } finally {
+ fNotifier.fireTestFinished(fDescription);
+ }
+ }
+
+ 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 Exception(String.format("test timed out after %d milliseconds", timeout)));
+ } 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 {
+ fTestMethod.invoke(fTest);
+ if (fTestMethod.expectsException())
+ addFailure(new AssertionError("Expected exception: " + fTestMethod.getExpectedException().getName()));
+ } catch (InvocationTargetException e) {
+ Throwable actual= e.getTargetException();
+ if (actual instanceof AssumptionViolatedException)
+ return;
+ else if (!fTestMethod.expectsException())
+ addFailure(actual);
+ else if (fTestMethod.isUnexpected(actual)) {
+ String message= "Unexpected exception, expected<" + fTestMethod.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= fTestMethod.getBefores();
+ for (Method before : befores)
+ before.invoke(fTest);
+ } 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= fTestMethod.getAfters();
+ for (Method after : afters)
+ try {
+ after.invoke(fTest);
+ } catch (InvocationTargetException e) {
+ addFailure(e.getTargetException());
+ } catch (Throwable e) {
+ addFailure(e); // Untested, but seems impossible
+ }
+ }
+
+ protected void addFailure(Throwable e) {
+ fNotifier.fireTestFailure(new Failure(fDescription, e));
+ }
+}
+