Loading ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java +70 −32 Original line number Diff line number Diff line Loading @@ -21,6 +21,8 @@ import static com.android.ravenwood.common.RavenwoodCommonUtils.isOnRavenwood; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.TYPE; import android.util.Log; import com.android.ravenwood.common.RavenwoodCommonUtils; import com.android.ravenwood.common.SneakyThrow; Loading @@ -36,6 +38,7 @@ import org.junit.runner.manipulation.Orderable; import org.junit.runner.manipulation.Orderer; import org.junit.runner.manipulation.Sortable; import org.junit.runner.manipulation.Sorter; import org.junit.runner.notification.Failure; import org.junit.runner.notification.RunNotifier; import org.junit.runners.BlockJUnit4ClassRunner; import org.junit.runners.model.Statement; Loading Loading @@ -134,8 +137,10 @@ public class RavenwoodAwareTestRunner extends Runner implements Filterable, Orde return runner; } private final TestClass mTestClsas; private final Runner mRealRunner; private TestClass mTestClass = null; private Runner mRealRunner = null; private Description mDescription = null; private Throwable mExceptionInConstructor = null; /** Simple logging method. */ private void log(String message) { Loading @@ -149,28 +154,30 @@ public class RavenwoodAwareTestRunner extends Runner implements Filterable, Orde } public TestClass getTestClass() { return mTestClsas; return mTestClass; } /** * Constructor. */ public RavenwoodAwareTestRunner(Class<?> testClass) { mTestClsas = new TestClass(testClass); try { mTestClass = new TestClass(testClass); /* * If the class has @DisabledOnRavenwood, then we'll delegate to ClassSkippingTestRunner, * which simply skips it. * If the class has @DisabledOnRavenwood, then we'll delegate to * ClassSkippingTestRunner, which simply skips it. */ if (isOnRavenwood() && !RavenwoodAwareTestRunnerHook.shouldRunClassOnRavenwood( mTestClsas.getJavaClass())) { mRealRunner = new ClassSkippingTestRunner(mTestClsas); mTestClass.getJavaClass())) { mRealRunner = new ClassSkippingTestRunner(mTestClass); mDescription = mRealRunner.getDescription(); return; } // Find the real runner. final Class<? extends Runner> realRunner; final InnerRunner innerRunnerAnnotation = mTestClsas.getAnnotation(InnerRunner.class); final InnerRunner innerRunnerAnnotation = mTestClass.getAnnotation(InnerRunner.class); if (innerRunnerAnnotation != null) { realRunner = innerRunnerAnnotation.value(); } else { Loading @@ -184,11 +191,26 @@ public class RavenwoodAwareTestRunner extends Runner implements Filterable, Orde log("Initializing the inner runner: " + realRunner); mRealRunner = realRunner.getConstructor(Class.class).newInstance(testClass); mDescription = mRealRunner.getDescription(); } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { throw logAndFail("Failed to instantiate " + realRunner, e); } } catch (Throwable th) { // If we throw in the constructor, Tradefed may not report it and just ignore the class, // so record it and throw it when the test actually started. log("Fatal: Exception detected in constructor: " + th.getMessage() + "\n" + Log.getStackTraceString(th)); mExceptionInConstructor = new RuntimeException("Exception detected in constructor", th); mDescription = Description.createTestDescription(testClass, "Constructor"); // This is for testing if tradefed is fixed. if ("1".equals(System.getenv("RAVENWOOD_THROW_EXCEPTION_IN_TEST_RUNNER"))) { throw th; } } } /** Loading @@ -202,7 +224,7 @@ public class RavenwoodAwareTestRunner extends Runner implements Filterable, Orde log("onRunnerInitializing"); RavenwoodAwareTestRunnerHook.onRunnerInitializing(this, mTestClsas); RavenwoodAwareTestRunnerHook.onRunnerInitializing(this, mTestClass); // Hook point to allow more customization. runAnnotatedMethodsOnRavenwood(RavenwoodTestRunnerInitializing.class, null); Loading Loading @@ -230,7 +252,7 @@ public class RavenwoodAwareTestRunner extends Runner implements Filterable, Orde @Override public Description getDescription() { return mRealRunner.getDescription(); return mDescription; } @Override Loading @@ -241,6 +263,10 @@ public class RavenwoodAwareTestRunner extends Runner implements Filterable, Orde return; } if (maybeReportExceptionFromConstructor(notifier)) { return; } sCurrentRunner.set(this); try { runWithHooks(getDescription(), Scope.Runner, Order.First, Loading @@ -250,6 +276,18 @@ public class RavenwoodAwareTestRunner extends Runner implements Filterable, Orde } } /** Throw the exception detected in the constructor, if any. */ private boolean maybeReportExceptionFromConstructor(RunNotifier notifier) { if (mExceptionInConstructor == null) { return false; } notifier.fireTestStarted(mDescription); notifier.fireTestFailure(new Failure(mDescription, mExceptionInConstructor)); notifier.fireTestFinished(mDescription); return true; } @Override public void filter(Filter filter) throws NoTestsRemainException { if (mRealRunner instanceof Filterable r) { Loading Loading
ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java +70 −32 Original line number Diff line number Diff line Loading @@ -21,6 +21,8 @@ import static com.android.ravenwood.common.RavenwoodCommonUtils.isOnRavenwood; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.TYPE; import android.util.Log; import com.android.ravenwood.common.RavenwoodCommonUtils; import com.android.ravenwood.common.SneakyThrow; Loading @@ -36,6 +38,7 @@ import org.junit.runner.manipulation.Orderable; import org.junit.runner.manipulation.Orderer; import org.junit.runner.manipulation.Sortable; import org.junit.runner.manipulation.Sorter; import org.junit.runner.notification.Failure; import org.junit.runner.notification.RunNotifier; import org.junit.runners.BlockJUnit4ClassRunner; import org.junit.runners.model.Statement; Loading Loading @@ -134,8 +137,10 @@ public class RavenwoodAwareTestRunner extends Runner implements Filterable, Orde return runner; } private final TestClass mTestClsas; private final Runner mRealRunner; private TestClass mTestClass = null; private Runner mRealRunner = null; private Description mDescription = null; private Throwable mExceptionInConstructor = null; /** Simple logging method. */ private void log(String message) { Loading @@ -149,28 +154,30 @@ public class RavenwoodAwareTestRunner extends Runner implements Filterable, Orde } public TestClass getTestClass() { return mTestClsas; return mTestClass; } /** * Constructor. */ public RavenwoodAwareTestRunner(Class<?> testClass) { mTestClsas = new TestClass(testClass); try { mTestClass = new TestClass(testClass); /* * If the class has @DisabledOnRavenwood, then we'll delegate to ClassSkippingTestRunner, * which simply skips it. * If the class has @DisabledOnRavenwood, then we'll delegate to * ClassSkippingTestRunner, which simply skips it. */ if (isOnRavenwood() && !RavenwoodAwareTestRunnerHook.shouldRunClassOnRavenwood( mTestClsas.getJavaClass())) { mRealRunner = new ClassSkippingTestRunner(mTestClsas); mTestClass.getJavaClass())) { mRealRunner = new ClassSkippingTestRunner(mTestClass); mDescription = mRealRunner.getDescription(); return; } // Find the real runner. final Class<? extends Runner> realRunner; final InnerRunner innerRunnerAnnotation = mTestClsas.getAnnotation(InnerRunner.class); final InnerRunner innerRunnerAnnotation = mTestClass.getAnnotation(InnerRunner.class); if (innerRunnerAnnotation != null) { realRunner = innerRunnerAnnotation.value(); } else { Loading @@ -184,11 +191,26 @@ public class RavenwoodAwareTestRunner extends Runner implements Filterable, Orde log("Initializing the inner runner: " + realRunner); mRealRunner = realRunner.getConstructor(Class.class).newInstance(testClass); mDescription = mRealRunner.getDescription(); } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { throw logAndFail("Failed to instantiate " + realRunner, e); } } catch (Throwable th) { // If we throw in the constructor, Tradefed may not report it and just ignore the class, // so record it and throw it when the test actually started. log("Fatal: Exception detected in constructor: " + th.getMessage() + "\n" + Log.getStackTraceString(th)); mExceptionInConstructor = new RuntimeException("Exception detected in constructor", th); mDescription = Description.createTestDescription(testClass, "Constructor"); // This is for testing if tradefed is fixed. if ("1".equals(System.getenv("RAVENWOOD_THROW_EXCEPTION_IN_TEST_RUNNER"))) { throw th; } } } /** Loading @@ -202,7 +224,7 @@ public class RavenwoodAwareTestRunner extends Runner implements Filterable, Orde log("onRunnerInitializing"); RavenwoodAwareTestRunnerHook.onRunnerInitializing(this, mTestClsas); RavenwoodAwareTestRunnerHook.onRunnerInitializing(this, mTestClass); // Hook point to allow more customization. runAnnotatedMethodsOnRavenwood(RavenwoodTestRunnerInitializing.class, null); Loading Loading @@ -230,7 +252,7 @@ public class RavenwoodAwareTestRunner extends Runner implements Filterable, Orde @Override public Description getDescription() { return mRealRunner.getDescription(); return mDescription; } @Override Loading @@ -241,6 +263,10 @@ public class RavenwoodAwareTestRunner extends Runner implements Filterable, Orde return; } if (maybeReportExceptionFromConstructor(notifier)) { return; } sCurrentRunner.set(this); try { runWithHooks(getDescription(), Scope.Runner, Order.First, Loading @@ -250,6 +276,18 @@ public class RavenwoodAwareTestRunner extends Runner implements Filterable, Orde } } /** Throw the exception detected in the constructor, if any. */ private boolean maybeReportExceptionFromConstructor(RunNotifier notifier) { if (mExceptionInConstructor == null) { return false; } notifier.fireTestStarted(mDescription); notifier.fireTestFailure(new Failure(mDescription, mExceptionInConstructor)); notifier.fireTestFinished(mDescription); return true; } @Override public void filter(Filter filter) throws NoTestsRemainException { if (mRealRunner instanceof Filterable r) { Loading