Loading core/java/com/android/internal/os/RuntimeInit.java +11 −0 Original line number Diff line number Diff line Loading @@ -404,6 +404,17 @@ public class RuntimeInit { } public static void redirectLogStreams$ravenwood() { if (sOut$ravenwood != null && sErr$ravenwood != null) { return; // Already initialized. } // Make sure the Log class is loaded and the JNI methods are hooked up, // before redirecting System.out/err. // Otherwise, because ClassLoadHook tries to write to System.out, this would cause // a circular initialization problem and would cause a UnsatisfiedLinkError // on the JNI methods. Log.isLoggable("X", Log.VERBOSE); if (sOut$ravenwood == null) { sOut$ravenwood = System.out; System.setOut(new AndroidPrintStream(Log.INFO, "System.out")); Loading ravenwood/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -127,6 +127,7 @@ java_library { libs: [ "framework-minus-apex.ravenwood", "ravenwood-junit", "ravenwood-helper-libcore-runtime", ], visibility: ["//visibility:private"], } Loading ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodAwareTestRunnerHook.java +27 −8 Original line number Diff line number Diff line Loading @@ -27,6 +27,9 @@ import android.util.Log; import androidx.test.platform.app.InstrumentationRegistry; import com.android.internal.os.RuntimeInit; import com.android.ravenwood.common.RavenwoodCommonUtils; import org.junit.runner.Description; import org.junit.runner.Runner; import org.junit.runners.model.TestClass; Loading @@ -35,7 +38,7 @@ import org.junit.runners.model.TestClass; * Provide hook points created by {@link RavenwoodAwareTestRunner}. */ public class RavenwoodAwareTestRunnerHook { private static final String TAG = "RavenwoodAwareTestRunnerHook"; private static final String TAG = RavenwoodAwareTestRunner.TAG; private RavenwoodAwareTestRunnerHook() { } Loading @@ -56,20 +59,36 @@ public class RavenwoodAwareTestRunnerHook { * Called when a runner starts, before the inner runner gets a chance to run. */ public static void onRunnerInitializing(Runner runner, TestClass testClass) { // TODO: Move the initialization code to a better place. initOnce(); // This log call also ensures the framework JNI is loaded. Log.i(TAG, "onRunnerInitializing: testClass=" + testClass.getJavaClass() + " runner=" + runner); // TODO: Move the initialization code to a better place. // This is needed to make AndroidJUnit4ClassRunner happy. InstrumentationRegistry.registerInstance(null, Bundle.EMPTY); } private static boolean sInitialized = false; private static void initOnce() { if (sInitialized) { return; } sInitialized = true; // We haven't initialized liblog yet, so directly write to System.out here. RavenwoodCommonUtils.log(TAG, "initOnce()"); // Redirect stdout/stdin to liblog. RuntimeInit.redirectLogStreams(); // This will let AndroidJUnit4 use the original runner. System.setProperty("android.junit.runner", "androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner"); System.setProperty(RAVENWOOD_VERSION_JAVA_SYSPROP, "1"); // This is needed to make AndroidJUnit4ClassRunner happy. InstrumentationRegistry.registerInstance(null, Bundle.EMPTY); } /** Loading @@ -87,7 +106,7 @@ public class RavenwoodAwareTestRunnerHook { */ public static boolean onBefore(RavenwoodAwareTestRunner runner, Description description, Scope scope, Order order) { Log.i(TAG, "onBefore: description=" + description + ", " + scope + ", " + order); Log.v(TAG, "onBefore: description=" + description + ", " + scope + ", " + order); if (scope == Scope.Class && order == Order.First) { // Keep track of the current class. Loading @@ -113,7 +132,7 @@ public class RavenwoodAwareTestRunnerHook { */ public static boolean onAfter(RavenwoodAwareTestRunner runner, Description description, Scope scope, Order order, Throwable th) { Log.i(TAG, "onAfter: description=" + description + ", " + scope + ", " + order + ", " + th); Log.v(TAG, "onAfter: description=" + description + ", " + scope + ", " + order + ", " + th); if (scope == Scope.Instance && order == Order.First) { getStats().onTestFinished(sCurrentClassDescription, description, Loading ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuleImpl.java +0 −3 Original line number Diff line number Diff line Loading @@ -36,7 +36,6 @@ import android.view.DisplayAdjustments; import androidx.test.platform.app.InstrumentationRegistry; import com.android.internal.os.RuntimeInit; import com.android.server.LocalServices; import org.junit.runner.Description; Loading Loading @@ -92,8 +91,6 @@ public class RavenwoodRuleImpl { Thread.setDefaultUncaughtExceptionHandler(sUncaughtExceptionHandler); } RuntimeInit.redirectLogStreams(); android.os.Process.init$ravenwood(rule.mUid, rule.mPid); android.os.Binder.init$ravenwood(); setSystemProperties(rule.mSystemProperties); Loading ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java +10 −20 Original line number Diff line number Diff line Loading @@ -23,7 +23,6 @@ import static java.lang.annotation.ElementType.TYPE; import android.util.Log; import com.android.ravenwood.common.RavenwoodCommonUtils; import com.android.ravenwood.common.SneakyThrow; import org.junit.Assume; Loading Loading @@ -75,7 +74,7 @@ import java.lang.reflect.InvocationTargetException; * (no hooks, etc.) */ public class RavenwoodAwareTestRunner extends Runner implements Filterable, Orderable { private static final String TAG = "RavenwoodAwareTestRunner"; public static final String TAG = "Ravenwood"; @Inherited @Target({TYPE}) Loading Loading @@ -142,16 +141,9 @@ public class RavenwoodAwareTestRunner extends Runner implements Filterable, Orde private Description mDescription = null; private Throwable mExceptionInConstructor = null; /** Simple logging method. */ private void log(String message) { RavenwoodCommonUtils.log(TAG, "[" + getTestClass().getJavaClass() + " @" + this + "] " + message); } private Error logAndFail(String message, Throwable innerException) { log(message); log(" Exception=" + innerException); throw new AssertionError(message, innerException); private Error logAndFail(String message, Throwable exception) { Log.e(TAG, message, exception); throw new AssertionError(message, exception); } public TestClass getTestClass() { Loading @@ -165,6 +157,8 @@ public class RavenwoodAwareTestRunner extends Runner implements Filterable, Orde try { mTestClass = new TestClass(testClass); onRunnerInitializing(); /* * If the class has @DisabledOnRavenwood, then we'll delegate to * ClassSkippingTestRunner, which simply skips it. Loading @@ -186,10 +180,8 @@ public class RavenwoodAwareTestRunner extends Runner implements Filterable, Orde realRunnerClass = BlockJUnit4ClassRunner.class; } onRunnerInitializing(); try { log("Initializing the inner runner: " + realRunnerClass); Log.i(TAG, "Initializing the inner runner: " + realRunnerClass); mRealRunner = instantiateRealRunner(realRunnerClass, testClass); mDescription = mRealRunner.getDescription(); Loading @@ -201,8 +193,7 @@ public class RavenwoodAwareTestRunner extends Runner implements Filterable, Orde } 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)); Log.e(TAG, "Fatal: Exception detected in constructor", th); mExceptionInConstructor = new RuntimeException("Exception detected in constructor", th); mDescription = Description.createTestDescription(testClass, "Constructor"); Loading Loading @@ -236,8 +227,7 @@ public class RavenwoodAwareTestRunner extends Runner implements Filterable, Orde if (!isOnRavenwood()) { return; } log("onRunnerInitializing"); // DO NOT USE android.util.Log before calling onRunnerInitializing(). RavenwoodAwareTestRunnerHook.onRunnerInitializing(this, mTestClass); Loading @@ -250,7 +240,7 @@ public class RavenwoodAwareTestRunner extends Runner implements Filterable, Orde if (!isOnRavenwood()) { return; } log("runAnnotatedMethodsOnRavenwood() " + annotationClass.getName()); Log.v(TAG, "runAnnotatedMethodsOnRavenwood() " + annotationClass.getName()); for (var method : getTestClass().getAnnotatedMethods(annotationClass)) { ensureIsPublicVoidMethod(method.getMethod(), /* isStatic=*/ instance == null); Loading Loading
core/java/com/android/internal/os/RuntimeInit.java +11 −0 Original line number Diff line number Diff line Loading @@ -404,6 +404,17 @@ public class RuntimeInit { } public static void redirectLogStreams$ravenwood() { if (sOut$ravenwood != null && sErr$ravenwood != null) { return; // Already initialized. } // Make sure the Log class is loaded and the JNI methods are hooked up, // before redirecting System.out/err. // Otherwise, because ClassLoadHook tries to write to System.out, this would cause // a circular initialization problem and would cause a UnsatisfiedLinkError // on the JNI methods. Log.isLoggable("X", Log.VERBOSE); if (sOut$ravenwood == null) { sOut$ravenwood = System.out; System.setOut(new AndroidPrintStream(Log.INFO, "System.out")); Loading
ravenwood/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -127,6 +127,7 @@ java_library { libs: [ "framework-minus-apex.ravenwood", "ravenwood-junit", "ravenwood-helper-libcore-runtime", ], visibility: ["//visibility:private"], } Loading
ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodAwareTestRunnerHook.java +27 −8 Original line number Diff line number Diff line Loading @@ -27,6 +27,9 @@ import android.util.Log; import androidx.test.platform.app.InstrumentationRegistry; import com.android.internal.os.RuntimeInit; import com.android.ravenwood.common.RavenwoodCommonUtils; import org.junit.runner.Description; import org.junit.runner.Runner; import org.junit.runners.model.TestClass; Loading @@ -35,7 +38,7 @@ import org.junit.runners.model.TestClass; * Provide hook points created by {@link RavenwoodAwareTestRunner}. */ public class RavenwoodAwareTestRunnerHook { private static final String TAG = "RavenwoodAwareTestRunnerHook"; private static final String TAG = RavenwoodAwareTestRunner.TAG; private RavenwoodAwareTestRunnerHook() { } Loading @@ -56,20 +59,36 @@ public class RavenwoodAwareTestRunnerHook { * Called when a runner starts, before the inner runner gets a chance to run. */ public static void onRunnerInitializing(Runner runner, TestClass testClass) { // TODO: Move the initialization code to a better place. initOnce(); // This log call also ensures the framework JNI is loaded. Log.i(TAG, "onRunnerInitializing: testClass=" + testClass.getJavaClass() + " runner=" + runner); // TODO: Move the initialization code to a better place. // This is needed to make AndroidJUnit4ClassRunner happy. InstrumentationRegistry.registerInstance(null, Bundle.EMPTY); } private static boolean sInitialized = false; private static void initOnce() { if (sInitialized) { return; } sInitialized = true; // We haven't initialized liblog yet, so directly write to System.out here. RavenwoodCommonUtils.log(TAG, "initOnce()"); // Redirect stdout/stdin to liblog. RuntimeInit.redirectLogStreams(); // This will let AndroidJUnit4 use the original runner. System.setProperty("android.junit.runner", "androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner"); System.setProperty(RAVENWOOD_VERSION_JAVA_SYSPROP, "1"); // This is needed to make AndroidJUnit4ClassRunner happy. InstrumentationRegistry.registerInstance(null, Bundle.EMPTY); } /** Loading @@ -87,7 +106,7 @@ public class RavenwoodAwareTestRunnerHook { */ public static boolean onBefore(RavenwoodAwareTestRunner runner, Description description, Scope scope, Order order) { Log.i(TAG, "onBefore: description=" + description + ", " + scope + ", " + order); Log.v(TAG, "onBefore: description=" + description + ", " + scope + ", " + order); if (scope == Scope.Class && order == Order.First) { // Keep track of the current class. Loading @@ -113,7 +132,7 @@ public class RavenwoodAwareTestRunnerHook { */ public static boolean onAfter(RavenwoodAwareTestRunner runner, Description description, Scope scope, Order order, Throwable th) { Log.i(TAG, "onAfter: description=" + description + ", " + scope + ", " + order + ", " + th); Log.v(TAG, "onAfter: description=" + description + ", " + scope + ", " + order + ", " + th); if (scope == Scope.Instance && order == Order.First) { getStats().onTestFinished(sCurrentClassDescription, description, Loading
ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuleImpl.java +0 −3 Original line number Diff line number Diff line Loading @@ -36,7 +36,6 @@ import android.view.DisplayAdjustments; import androidx.test.platform.app.InstrumentationRegistry; import com.android.internal.os.RuntimeInit; import com.android.server.LocalServices; import org.junit.runner.Description; Loading Loading @@ -92,8 +91,6 @@ public class RavenwoodRuleImpl { Thread.setDefaultUncaughtExceptionHandler(sUncaughtExceptionHandler); } RuntimeInit.redirectLogStreams(); android.os.Process.init$ravenwood(rule.mUid, rule.mPid); android.os.Binder.init$ravenwood(); setSystemProperties(rule.mSystemProperties); Loading
ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java +10 −20 Original line number Diff line number Diff line Loading @@ -23,7 +23,6 @@ import static java.lang.annotation.ElementType.TYPE; import android.util.Log; import com.android.ravenwood.common.RavenwoodCommonUtils; import com.android.ravenwood.common.SneakyThrow; import org.junit.Assume; Loading Loading @@ -75,7 +74,7 @@ import java.lang.reflect.InvocationTargetException; * (no hooks, etc.) */ public class RavenwoodAwareTestRunner extends Runner implements Filterable, Orderable { private static final String TAG = "RavenwoodAwareTestRunner"; public static final String TAG = "Ravenwood"; @Inherited @Target({TYPE}) Loading Loading @@ -142,16 +141,9 @@ public class RavenwoodAwareTestRunner extends Runner implements Filterable, Orde private Description mDescription = null; private Throwable mExceptionInConstructor = null; /** Simple logging method. */ private void log(String message) { RavenwoodCommonUtils.log(TAG, "[" + getTestClass().getJavaClass() + " @" + this + "] " + message); } private Error logAndFail(String message, Throwable innerException) { log(message); log(" Exception=" + innerException); throw new AssertionError(message, innerException); private Error logAndFail(String message, Throwable exception) { Log.e(TAG, message, exception); throw new AssertionError(message, exception); } public TestClass getTestClass() { Loading @@ -165,6 +157,8 @@ public class RavenwoodAwareTestRunner extends Runner implements Filterable, Orde try { mTestClass = new TestClass(testClass); onRunnerInitializing(); /* * If the class has @DisabledOnRavenwood, then we'll delegate to * ClassSkippingTestRunner, which simply skips it. Loading @@ -186,10 +180,8 @@ public class RavenwoodAwareTestRunner extends Runner implements Filterable, Orde realRunnerClass = BlockJUnit4ClassRunner.class; } onRunnerInitializing(); try { log("Initializing the inner runner: " + realRunnerClass); Log.i(TAG, "Initializing the inner runner: " + realRunnerClass); mRealRunner = instantiateRealRunner(realRunnerClass, testClass); mDescription = mRealRunner.getDescription(); Loading @@ -201,8 +193,7 @@ public class RavenwoodAwareTestRunner extends Runner implements Filterable, Orde } 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)); Log.e(TAG, "Fatal: Exception detected in constructor", th); mExceptionInConstructor = new RuntimeException("Exception detected in constructor", th); mDescription = Description.createTestDescription(testClass, "Constructor"); Loading Loading @@ -236,8 +227,7 @@ public class RavenwoodAwareTestRunner extends Runner implements Filterable, Orde if (!isOnRavenwood()) { return; } log("onRunnerInitializing"); // DO NOT USE android.util.Log before calling onRunnerInitializing(). RavenwoodAwareTestRunnerHook.onRunnerInitializing(this, mTestClass); Loading @@ -250,7 +240,7 @@ public class RavenwoodAwareTestRunner extends Runner implements Filterable, Orde if (!isOnRavenwood()) { return; } log("runAnnotatedMethodsOnRavenwood() " + annotationClass.getName()); Log.v(TAG, "runAnnotatedMethodsOnRavenwood() " + annotationClass.getName()); for (var method : getTestClass().getAnnotatedMethods(annotationClass)) { ensureIsPublicVoidMethod(method.getMethod(), /* isStatic=*/ instance == null); Loading