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

Commit 06a21382 authored by Eric Holk's avatar Eric Holk
Browse files

[view compiler] Add test coverage for layouts compiled from APK

The existing LayoutCompilerTest only covered compiled layouts generated from
text XML files. It did not cover layouts that were extracted from the APK. This
is an important area to cover.

This test works by calling `pm compile --compile-layouts` on the test APK, and
then directly loads the `compiled_view.dex` file. From there, it pulls out the
compiled layouts and executes their inflater. This makes sure the generated DEX
files validate and execute without error.

Bug: 111895153
Merged-In: Ifc6719c2f438474b5474def02422ef68eee800b2
Change-Id: I7024069bb4d77a81871366f259fb34ae54a55aac
parent d191463b
Loading
Loading
Loading
Loading
+9 −3
Original line number Original line Diff line number Diff line
@@ -37,15 +37,21 @@ genrule {
android_test {
android_test {
    name: "dex-builder-test",
    name: "dex-builder-test",
    srcs: [
    srcs: [
        "src/android/startop/test/ApkLayoutCompilerTest.java",
        "src/android/startop/test/DexBuilderTest.java",
        "src/android/startop/test/DexBuilderTest.java",
        "src/android/startop/test/LayoutCompilerTest.java",
        "src/android/startop/test/LayoutCompilerTest.java",
        "src/android/startop/test/TestClass.java",
        "src/android/startop/test/TestClass.java",
    ],
    ],
    sdk_version: "current",
    sdk_version: "current",
    data: [":generate_dex_testcases", ":generate_compiled_layout1", ":generate_compiled_layout2"],
    data: [
        ":generate_dex_testcases",
        ":generate_compiled_layout1",
        ":generate_compiled_layout2",
    ],
    static_libs: [
    static_libs: [
        "androidx.test.rules",
        "androidx.test.core",
        "guava",
        "androidx.test.runner",
        "junit",
    ],
    ],
    manifest: "AndroidManifest.xml",
    manifest: "AndroidManifest.xml",
    resource_dirs: ["res"],
    resource_dirs: ["res"],
+57 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */

package android.startop.test;

import android.content.Context;
import androidx.test.InstrumentationRegistry;
import android.view.View;
import dalvik.system.PathClassLoader;
import java.lang.reflect.Method;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;

public class ApkLayoutCompilerTest {
    static ClassLoader loadDexFile() throws Exception {
        Context context = InstrumentationRegistry.getTargetContext();
        return new PathClassLoader(context.getCodeCacheDir() + "/compiled_view.dex",
                ClassLoader.getSystemClassLoader());
    }

    @BeforeClass
    public static void setup() throws Exception {
        // ensure PackageManager has compiled the layouts.
        Process pm = Runtime.getRuntime().exec("pm compile --compile-layouts android.startop.test");
        pm.waitFor();
    }

    @Test
    public void loadAndInflateLayout1() throws Exception {
        ClassLoader dex_file = loadDexFile();
        Class compiled_view = dex_file.loadClass("android.startop.test.CompiledView");
        Method layout1 = compiled_view.getMethod("layout1", Context.class, int.class);
        Context context = InstrumentationRegistry.getTargetContext();
        layout1.invoke(null, context, R.layout.layout1);
    }

    @Test
    public void loadAndInflateLayout2() throws Exception {
        ClassLoader dex_file = loadDexFile();
        Class compiled_view = dex_file.loadClass("android.startop.test.CompiledView");
        Method layout2 = compiled_view.getMethod("layout2", Context.class, int.class);
        Context context = InstrumentationRegistry.getTargetContext();
        layout2.invoke(null, context, R.layout.layout2);
    }
}
+4 −1
Original line number Original line Diff line number Diff line
@@ -14,8 +14,11 @@


package android.startop.test;
package android.startop.test;


import android.content.Context;
import androidx.test.InstrumentationRegistry;
import dalvik.system.PathClassLoader;
import dalvik.system.PathClassLoader;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.junit.Assert;
import org.junit.Assert;
import org.junit.Test;
import org.junit.Test;


+3 −3
Original line number Original line Diff line number Diff line
@@ -15,11 +15,11 @@
package android.startop.test;
package android.startop.test;


import android.content.Context;
import android.content.Context;

import androidx.test.InstrumentationRegistry;
import androidx.test.InstrumentationRegistry;

import android.view.View;
import dalvik.system.PathClassLoader;
import dalvik.system.PathClassLoader;

import java.lang.reflect.Method;
import org.junit.Assert;
import org.junit.Test;
import org.junit.Test;


import java.lang.reflect.Method;
import java.lang.reflect.Method;