Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2ddab5c2 authored by John Wu's avatar John Wu Committed by Android (Google) Code Review
Browse files

Merge "Migrate android_ravenwood_tests to directly build resources" into main

parents cef226f3 d312fcb2
Loading
Loading
Loading
Loading
+3 −37
Original line number Diff line number Diff line
@@ -59,11 +59,6 @@ android_test {

    dxflags: ["--core-library"],

    aaptflags: [
        "-0 .dat",
        "-0 .gld",
        "-c fa",
    ],
    static_libs: [
        "TestParameterInjector",
        "android-common",
@@ -162,31 +157,6 @@ android_test {
    ],
}

// FrameworksCoreTestsRavenwood pulls in the R.java class from this one.
// Note, "FrameworksCoreTests" and "FrameworksCoreTests-resonly" _might_ not have indentical
// R.java (not sure if there's a guarantee), but that doesn't matter as long as
// FrameworksCoreTestsRavenwood consistently uses the R definition in this module.
android_app {
    name: "FrameworksCoreTests-resonly",
    defaults: ["FrameworksCoreTests-resources"],

    // FrameworksCoreTestsRavenwood references the .aapt.srcjar
    use_resource_processor: false,
    libs: [
        "android.test.runner.stubs",
        "framework-res",
        "org.apache.http.legacy.stubs",
    ],
    uses_libs: [
        "android.test.runner",
    ],
    optional_uses_libs: [
        "org.apache.http.legacy",
    ],
    sdk_version: "core_platform",
    resource_zips: [":FrameworksCoreTests_apks_as_resources"],
}

// Rules to copy all the test apks to the intermediate raw resource directory
java_genrule {
    name: "FrameworksCoreTests_apks_as_resources",
@@ -251,6 +221,8 @@ android_library {

android_ravenwood_test {
    name: "FrameworksCoreTestsRavenwood",
    defaults: ["FrameworksCoreTests-resources"],
    build_resources: true,
    libs: [
        "android.test.base.stubs",
        "android.test.mock.stubs",
@@ -309,19 +281,12 @@ android_ravenwood_test {
        ":FrameworksCoreTestDoubles-sources",
        ":FrameworksCoreTests-aidl",
        ":FrameworksCoreTests-helpers",

        // Pull in R.java from FrameworksCoreTests-resonly, not from FrameworksCoreTests,
        // to avoid having a dependency to FrameworksCoreTests.
        // This way, when updating source files and running this test, we don't need to
        // rebuild the entire FrameworksCoreTests, which would be slow.
        ":FrameworksCoreTests-resonly{.aapt.srcjar}",
    ],
    exclude_srcs: [
        "src/android/content/res/FontScaleConverterActivityTest.java",
        "src/android/graphics/GraphicsPerformanceTests.java",
        "src/android/graphics/drawable/StateListDrawableTest.java",
    ],
    resource_apk: "FrameworksCoreTests-resonly",
    aidl: {
        generate_get_transaction_name: true,
        local_include_dirs: ["aidl"],
@@ -331,6 +296,7 @@ android_ravenwood_test {
        "res/xml/power_profile_test_cpu_legacy.xml",
        "res/xml/power_profile_test_modem.xml",
    ],
    resource_zips: [":FrameworksCoreTests_apks_as_resources"],
    sdk_version: "core_platform",
    auto_gen_config: true,
    team: "trendy_team_ravenwood",
+6 −22
Original line number Diff line number Diff line
@@ -797,24 +797,6 @@ android_library {
    ],
}

android_app {
    name: "SystemUI-tests-res",
    // SystemUiRavenTests references the .aapt.srcjar
    use_resource_processor: false,
    manifest: "tests/AndroidManifest-base.xml",
    resource_dirs: [
        "tests/res",
    ],
    asset_dirs: [
        "tests/goldens",
        "schemas",
    ],
    static_libs: [
        "SystemUI-res",
    ],
    platform_apis: true,
}

android_library {
    name: "SystemUI-tests",
    use_resource_processor: true,
@@ -1032,12 +1014,11 @@ filegroup {

android_ravenwood_test {
    name: "SystemUiRavenTests",
    manifest: "tests/AndroidManifest-base.xml",
    build_resources: true,
    srcs: [
        ":SystemUI-tests-utils",
        ":SystemUI-tests-multivalent",
        // TODO(b/294256649): pivot to using {.aapt.jar} and re-enable
        // use_resource_processor: true when better supported by soong
        ":SystemUI-tests-res{.aapt.srcjar}",
    ],
    exclude_srcs: [
        // TODO(b/429013941): kapt is way too slow, so disable them for now.
@@ -1060,7 +1041,10 @@ android_ravenwood_test {
        "android.test.base.impl",
        "android.test.mock.impl",
    ],
    resource_apk: "SystemUI-tests-res",
    aaptflags: [
        "--extra-packages",
        "com.android.systemui",
    ],
    auto_gen_config: true,
    team: "trendy_team_ravenwood",
}
+6 −53
Original line number Diff line number Diff line
@@ -16,13 +16,10 @@

package android.platform.test.ravenwood;

import static android.os.Process.FIRST_APPLICATION_UID;
import static android.os.UserHandle.SYSTEM;

import static com.android.modules.utils.ravenwood.RavenwoodHelper.RavenwoodInternal.RAVENWOOD_RUNTIME_PATH_JAVA_SYSPROP;
import static com.android.ravenwood.common.RavenwoodInternalUtils.getRavenwoodRuntimePath;
import static com.android.ravenwood.common.RavenwoodInternalUtils.parseNullableInt;
import static com.android.ravenwood.common.RavenwoodInternalUtils.withDefault;

import static org.junit.Assert.assertThrows;

@@ -37,8 +34,6 @@ import android.graphics.Typeface;
import android.icu.util.ULocale;
import android.os.Binder;
import android.os.Build;
import android.os.Build.VERSION_CODES;
import android.os.HandlerThread;
import android.os.Process_ravenwood;
import android.os.ServiceManager;
import android.os.ServiceManager.ServiceNotFoundException;
@@ -104,9 +99,6 @@ public class RavenwoodDriver {
        }
    }

    private static final String MAIN_THREAD_NAME = "Ravenwood:Main";
    private static final String TEST_THREAD_NAME = "Ravenwood:Test";

    private static final String LIBRAVENWOOD_INITIALIZER_NAME = "ravenwood_initializer";
    private static final String RAVENWOOD_NATIVE_RUNTIME_NAME = "ravenwood_runtime";

@@ -169,16 +161,10 @@ public class RavenwoodDriver {
    @GuardedBy("sInitializationLock")
    private static Throwable sExceptionFromGlobalInit;

    private static final int DEFAULT_TARGET_SDK_LEVEL = VERSION_CODES.CUR_DEVELOPMENT;
    private static final String DEFAULT_PACKAGE_NAME = "com.android.ravenwoodtests.defaultname";
    private static final String DEFAULT_INSTRUMENTATION_CLASS =
            "androidx.test.runner.AndroidJUnitRunner";

    /**
     * Initialize the global environment.
     */
    public static void globalInitOnce() {
        Thread.currentThread().setName(TEST_THREAD_NAME);
        synchronized (sInitializationLock) {
            if (!sInitialized) {
                // globalInitOnce() is called from class initializer, which cause
@@ -244,6 +230,7 @@ public class RavenwoodDriver {
        // Make sure libravenwood_runtime is loaded.
        System.load(RavenwoodInternalUtils.getJniLibraryPath(RAVENWOOD_NATIVE_RUNTIME_NAME));

        // TODO: Why do we use a random PID? We can get the real PID via JNI. Why not use that?
        final int pid = new Random().nextInt(100, 32768);
        Log_ravenwood.setPid(pid);
        Log_ravenwood.setLogLevels(getLogTags());
@@ -299,14 +286,14 @@ public class RavenwoodDriver {
        ActivityManager.init$ravenwood(SYSTEM.getIdentifier());

        // Initialize the "environment".
        var env = createEnvironment(pid);
        RavenwoodEnvironment.init(pid);

        // Start app lifecycle.
        RavenwoodAppDriver.init();

        // TODO(b/428775903) Make sure nothing would try to access compat-IDs before this call.
        // We may want to do it within initAppDriver().
        initializeCompatIds(env);
        initializeCompatIds();
    }

    /**
@@ -321,31 +308,6 @@ public class RavenwoodDriver {
        return logTags;
    }

    private static RavenwoodEnvironment createEnvironment(int pid) throws Exception {
        final var props = RavenwoodSystemProperties.readProperties("ravenwood.properties");

        // TODO(b/377765941) Read them from the manifest too?
        var targetSdkLevel = withDefault(
                parseNullableInt(props.get("targetSdkVersionInt")), DEFAULT_TARGET_SDK_LEVEL);
        var targetPackageName = withDefault(props.get("packageName"), DEFAULT_PACKAGE_NAME);
        var testPackageName = withDefault(props.get("instPackageName"), targetPackageName);
        var instrumentationClass = withDefault(props.get("instrumentationClass"),
                DEFAULT_INSTRUMENTATION_CLASS);

        // TODO: Why do we use a random PID? We can get the real PID via JNI. Why not use that?

        return RavenwoodEnvironment.init(
                FIRST_APPLICATION_UID,
                pid,
                targetSdkLevel,
                targetPackageName,
                testPackageName,
                instrumentationClass,
                Thread.currentThread(), // Test thread
                new HandlerThread(MAIN_THREAD_NAME)
        );
    }

    /**
     * Partially reset and initialize before each test class invocation
     */
@@ -410,12 +372,14 @@ public class RavenwoodDriver {
        }
    }

    private static void initializeCompatIds(RavenwoodEnvironment env) {
    private static void initializeCompatIds() {
        // Set up compat-IDs for the app side.
        // TODO: Inside the system server, all the compat-IDs should be enabled,
        // Due to the `AppCompatCallbacks.install(new long[0], new long[0] ...` call in
        // SystemServer.

        var env = RavenwoodEnvironment.getInstance();

        // Compat framework only uses the package name and the target SDK level.
        ApplicationInfo appInfo = new ApplicationInfo();
        appInfo.packageName = env.getTargetPackageName();
@@ -589,15 +553,4 @@ public class RavenwoodDriver {
        var itz = android.icu.util.TimeZone.getDefault();
        Log.i(TAG, "  android.icu.util.TimeZone="  + itz.getDisplayName() + " / " + itz);
    }

    /**
     * @return the name of the current test module.
     *
     * The current version "guesses" the name from the current directory name.
     *
     * TODO: Write the real module name in ravenwood.go to ravenwood.properties and use that.
     */
    public static String getTestModuleName() {
        return sInitialDirectory.getName();
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -260,7 +260,7 @@ public class RavenwoodEnablementChecker {
            result = false;
        } else {
            result = sEnablementPolicy.shouldEnableClass(
                    RavenwoodDriver.getTestModuleName(), testClass.getName());
                    RavenwoodEnvironment.getInstance().getTestModuleName(), testClass.getName());
        }
        if (checkRunDisabledTestsFlag && RUN_DISABLED_TESTS) {
            // Invert the result + check the really disable pattern
+63 −29
Original line number Diff line number Diff line
@@ -15,6 +15,11 @@
 */
package android.platform.test.ravenwood;

import static android.os.Process.FIRST_APPLICATION_UID;

import static com.android.ravenwood.common.RavenwoodInternalUtils.parseNullableInt;
import static com.android.ravenwood.common.RavenwoodInternalUtils.withDefault;

import static org.junit.Assert.assertNotNull;

import android.annotation.NonNull;
@@ -24,6 +29,7 @@ import android.app.LoadedApk;
import android.app.RavenwoodAppDriver;
import android.app.ResourcesManager;
import android.content.res.Resources;
import android.os.Build;
import android.os.HandlerThread;
import android.os.Looper;
import android.util.Log;
@@ -70,15 +76,20 @@ public final class RavenwoodEnvironment {
        return Objects.requireNonNull(sInstance.get(), "RavenwoodEnvironment not initialized");
    }

    private static final File RAVENWOOD_TARGET_RESOURCE_APK =
            new File("ravenwood-res-apks/ravenwood-res.apk");
    private static final File RAVENWOOD_INST_RESOURCE_APK =
            new File("ravenwood-res-apks/ravenwood-inst-res.apk");

    private static final File RAVENWOOD_EMPTY_RESOURCES_APK =
            new File(RavenwoodInternalUtils.getRavenwoodRuntimePath(),
                    "/ravenwood-data/ravenwood-empty-res.apk");

    private static final String MAIN_THREAD_NAME = "Ravenwood:Main";
    private static final String TEST_THREAD_NAME = "Ravenwood:Test";

    private static final String RESOURCE_APK_DIR = "ravenwood-res-apks";

    private static final int DEFAULT_TARGET_SDK_LEVEL = Build.VERSION_CODES.CUR_DEVELOPMENT;
    private static final String DEFAULT_PACKAGE_NAME = "com.android.ravenwoodtests.defaultname";
    private static final String DEFAULT_INSTRUMENTATION_CLASS =
            "androidx.test.runner.AndroidJUnitRunner";

    private final Object mLock = new Object();

    private final int mUid;
@@ -94,6 +105,15 @@ public final class RavenwoodEnvironment {
    @NonNull
    private final String mInstrumentationClass;

    @NonNull
    private final String mModuleName;

    @Nullable
    private final String mResourceApk;

    @Nullable
    private final String mTargetResourceApk;

    /** Represents the filesystem root. */
    private final File mRootDir;

@@ -120,6 +140,9 @@ public final class RavenwoodEnvironment {
            @NonNull String targetPackageName,
            @NonNull String instPackageName,
            @NonNull String instrumentationClass,
            @NonNull String moduleName,
            @Nullable String resourceApk,
            @Nullable String targetResourceApk,
            @NonNull Thread testThread,
            @NonNull HandlerThread mainThread
    ) throws IOException {
@@ -129,6 +152,9 @@ public final class RavenwoodEnvironment {
        mTargetPackageName = Objects.requireNonNull(targetPackageName);
        mInstPackageName = Objects.requireNonNull(instPackageName);
        mInstrumentationClass = Objects.requireNonNull(instrumentationClass);
        mModuleName = Objects.requireNonNull(moduleName);
        mResourceApk = resourceApk;
        mTargetResourceApk = targetResourceApk;
        mTestThread = testThread;
        mMainThread = mainThread;

@@ -146,30 +172,37 @@ public final class RavenwoodEnvironment {
    /**
     * Create and initialize the singleton instance. Also initializes {@link RavenwoodVmState}.
     */
    public static RavenwoodEnvironment init(
            int uid,
            int pid,
            int targetSdkLevel,
            @NonNull String targetPackageName,
            @NonNull String instPackageName,
            @NonNull String instrumentationClass,
            @NonNull Thread testThread,
            @NonNull HandlerThread mainThread
    ) throws IOException {
    public static void init(int pid) throws IOException {
        final var props = RavenwoodSystemProperties.readProperties("ravenwood.properties");

        // TODO(b/377765941) Read them from the manifest too?
        var targetSdkLevel = withDefault(
                parseNullableInt(props.get("targetSdkVersionInt")), DEFAULT_TARGET_SDK_LEVEL);
        var testPackageName = withDefault(props.get("packageName"), DEFAULT_PACKAGE_NAME);
        var targetPackageName = withDefault(props.get("targetPackageName"), testPackageName);
        var instrumentationClass = withDefault(props.get("instrumentationClass"),
                DEFAULT_INSTRUMENTATION_CLASS);
        var moduleName = withDefault(props.get("moduleName"), testPackageName);
        var resourceApk = withDefault(props.get("resourceApk"), null);
        var targetResourceApk = withDefault(props.get("targetResourceApk"), null);

        Thread.currentThread().setName(TEST_THREAD_NAME);
        final var instance = new RavenwoodEnvironment(
                uid,
                FIRST_APPLICATION_UID,
                pid,
                targetSdkLevel,
                targetPackageName,
                instPackageName,
                testPackageName,
                instrumentationClass,
                testThread,
                mainThread);
                moduleName,
                resourceApk,
                targetResourceApk,
                Thread.currentThread(), // Test thread,
                new HandlerThread(MAIN_THREAD_NAME));
        if (!sInstance.compareAndSet(null, instance)) {
            throw new RuntimeException("RavenwoodEnvironment already initialized!");
        }
        RavenwoodVmState.init(instance.getUid(), instance.getPid(), instance.getTargetSdkLevel());
        return instance;
    }

    /**
@@ -202,6 +235,10 @@ public final class RavenwoodEnvironment {
        return mInstPackageName;
    }

    public String getTestModuleName() {
        return mModuleName;
    }

    @NonNull
    public String getInstrumentationClass() {
        return mInstrumentationClass;
@@ -300,19 +337,16 @@ public final class RavenwoodEnvironment {
     * @param packageName package name, or "android" to load the system resources.
     */
    public File getResourcesApkFile(@NonNull String packageName) {
        if (packageName.equals(getTargetPackageName())) {
            if (RAVENWOOD_TARGET_RESOURCE_APK.exists()) {
                return RAVENWOOD_TARGET_RESOURCE_APK;
        if (packageName.equals(getInstPackageName())) {
            if (mResourceApk != null) {
                return new File(RESOURCE_APK_DIR, mResourceApk);
            }
            // fall-through and use the default resources.

        } else if (packageName.equals(getInstPackageName())) {
            if (RAVENWOOD_INST_RESOURCE_APK.exists()) {
                return RAVENWOOD_INST_RESOURCE_APK;
        } else if (packageName.equals(getTargetPackageName())) {
            if (mTargetResourceApk != null) {
                return new File(RESOURCE_APK_DIR, mTargetResourceApk);
            }
            // fall-through and use the default resources.


        } else if (packageName.equals(RavenwoodInternalUtils.ANDROID_PACKAGE_NAME)) {
            // fall-through and use the default resources.

Loading