1 package org.junit.internal.runners; 2 3 import java.lang.reflect.InvocationTargetException ; 4 import java.lang.reflect.Method ; 5 import java.util.concurrent.Callable ; 6 import java.util.concurrent.ExecutorService ; 7 import java.util.concurrent.Executors ; 8 import java.util.concurrent.Future ; 9 import java.util.concurrent.TimeUnit ; 10 import java.util.concurrent.TimeoutException ; 11 12 import org.junit.After; 13 import org.junit.Before; 14 import org.junit.runner.Description; 15 import org.junit.runner.notification.Failure; 16 import org.junit.runner.notification.RunNotifier; 17 18 public class TestMethodRunner extends BeforeAndAfterRunner { 19 private final Object fTest; 20 private final Method fMethod; 21 private final RunNotifier fNotifier; 22 private final TestIntrospector fTestIntrospector; 23 private final Description fDescription; 24 25 public TestMethodRunner(Object test, Method method, RunNotifier notifier, Description description) { 26 super(test.getClass(), Before.class, After.class, test); 27 fTest= test; 28 fMethod= method; 29 fNotifier= notifier; 30 fTestIntrospector= new TestIntrospector(test.getClass()); 31 fDescription= description; 32 } 33 34 public void run() { 35 if (fTestIntrospector.isIgnored(fMethod)) { 36 fNotifier.fireTestIgnored(fDescription); 37 return; 38 } 39 fNotifier.fireTestStarted(fDescription); 40 try { 41 long timeout= fTestIntrospector.getTimeout(fMethod); 42 if (timeout > 0) 43 runWithTimeout(timeout); 44 else 45 runMethod(); 46 } finally { 47 fNotifier.fireTestFinished(fDescription); 48 } 49 } 50 51 private void runWithTimeout(long timeout) { 52 ExecutorService service= Executors.newSingleThreadExecutor(); 53 Callable <Object > callable= new Callable <Object >() { 54 public Object call() throws Exception { 55 runMethod(); 56 return null; 57 } 58 }; 59 Future <Object > result= service.submit(callable); 60 service.shutdown(); 61 try { 62 boolean terminated= service.awaitTermination(timeout, 63 TimeUnit.MILLISECONDS); 64 if (!terminated) 65 service.shutdownNow(); 66 result.get(0, TimeUnit.MILLISECONDS); } catch (TimeoutException e) { 68 addFailure(new Exception (String.format("test timed out after %d milliseconds", timeout))); 69 } catch (Exception e) { 70 addFailure(e); 71 } 72 } 73 74 private void runMethod() { 75 runProtected(); 76 } 77 78 @Override 79 protected void runUnprotected() { 80 try { 81 executeMethodBody(); 82 if (expectsException()) 83 addFailure(new AssertionError ("Expected exception: " + expectedException().getName())); 84 } catch (InvocationTargetException e) { 85 Throwable actual= e.getTargetException(); 86 if (!expectsException()) 87 addFailure(actual); 88 else if (isUnexpected(actual)) { 89 String message= "Unexpected exception, expected<" + expectedException().getName() + "> but was<" 90 + actual.getClass().getName() + ">"; 91 addFailure(new Exception (message, actual)); 92 } 93 } catch (Throwable e) { 94 addFailure(e); 95 } 96 } 97 98 protected void executeMethodBody() throws IllegalAccessException , InvocationTargetException { 99 fMethod.invoke(fTest); 100 } 101 102 @Override 103 protected void addFailure(Throwable e) { 104 fNotifier.fireTestFailure(new Failure(fDescription, e)); 105 } 106 107 private boolean expectsException() { 108 return expectedException() != null; 109 } 110 111 private Class <? extends Throwable > expectedException() { 112 return fTestIntrospector.expectedException(fMethod); 113 } 114 115 private boolean isUnexpected(Throwable exception) { 116 return ! expectedException().isAssignableFrom(exception.getClass()); 117 } 118 } 119 120 | Popular Tags |