Add CompOS to odsign_e2e_tests

Output of CompOS should pass the same verification for the early boot
compilation.  Some test cases are currently ignored due to the known
issues.

The implementation extracts the post-boot verification tests into a new
test class. Since I couldn't find another way to include a test class
(given BaseHostJUnit4Test and DeviceJUnit4ClassRunner), I can only make
it work as a base class (not SuiteClasses;
DeviceJUnit4ClassRunnerWithParameters might work but would be more
complicated).

The new test coverage would have prevent b/216618545.

However, the VM currently fails to boot on user build (b/216321149), so
it's excluded with an assumption.

Bug: 213573626
Test: adb root; atest odsign_e2e_tests
Test: flash -user build; atest odsign_e2e_tests
Change-Id: I54b33742a936329ad0d593b3f623b8a35c2ba627
diff --git a/test/odsign/test-src/com/android/tests/odsign/ActivationTest.java b/test/odsign/test-src/com/android/tests/odsign/ActivationTest.java
new file mode 100644
index 0000000..c6c8b38
--- /dev/null
+++ b/test/odsign/test-src/com/android/tests/odsign/ActivationTest.java
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2022 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 com.android.tests.odsign;
+
+import static org.junit.Assert.assertTrue;
+
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
+import com.android.tradefed.testtype.junit4.DeviceTestRunOptions;
+
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Arrays;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ * Test to check if odrefresh, odsign, fs-verity, and ART runtime work together properly.
+ */
+@Ignore("See derived classes, each produces the file for running the following verification")
+abstract class ActivationTest extends BaseHostJUnit4Test {
+    private static final String TEST_APP_PACKAGE_NAME = "com.android.tests.odsign";
+    private static final String TEST_APP_APK = "odsign_e2e_test_app.apk";
+
+    private OdsignTestUtils mTestUtils;
+
+    @Before
+    public void setUp() throws Exception {
+        mTestUtils = new OdsignTestUtils(getTestInformation());
+    }
+
+    @Test
+    public void verifyArtUpgradeSignsFiles() throws Exception {
+        installPackage(TEST_APP_APK);
+        DeviceTestRunOptions options = new DeviceTestRunOptions(TEST_APP_PACKAGE_NAME);
+        options.setTestClassName(TEST_APP_PACKAGE_NAME + ".ArtifactsSignedTest");
+        options.setTestMethodName("testArtArtifactsHaveFsverity");
+        runDeviceTests(options);
+    }
+
+    @Test
+    public void verifyArtUpgradeGeneratesRequiredArtifacts() throws Exception {
+        installPackage(TEST_APP_APK);
+        DeviceTestRunOptions options = new DeviceTestRunOptions(TEST_APP_PACKAGE_NAME);
+        options.setTestClassName(TEST_APP_PACKAGE_NAME + ".ArtifactsSignedTest");
+        options.setTestMethodName("testGeneratesRequiredArtArtifacts");
+        runDeviceTests(options);
+    }
+
+    @Test
+    public void verifyGeneratedArtifactsLoaded() throws Exception {
+        // Checking zygote and system_server need the device have adb root to walk process maps.
+        mTestUtils.enableAdbRootOrSkipTest();
+
+        // Check there is a compilation log, we expect compilation to have occurred.
+        assertTrue("Compilation log not found", mTestUtils.haveCompilationLog());
+
+        // Check both zygote and system_server processes to see that they have loaded the
+        // artifacts compiled and signed by odrefresh and odsign. We check both here rather than
+        // having a separate test because the device reboots between each @Test method and
+        // that is an expensive use of time.
+        verifyZygotesLoadedArtifacts();
+        verifySystemServerLoadedArtifacts();
+    }
+
+    @Test
+    public void verifyGeneratedArtifactsLoadedAfterReboot() throws Exception {
+        mTestUtils.enableAdbRootOrSkipTest();
+
+        mTestUtils.reboot();
+        verifyGeneratedArtifactsLoaded();
+    }
+
+    @Test
+    public void verifyGeneratedArtifactsLoadedAfterPartialCompilation() throws Exception {
+        mTestUtils.enableAdbRootOrSkipTest();
+
+        Set<String> mappedArtifacts = mTestUtils.getSystemServerLoadedArtifacts();
+        // Delete an arbitrary artifact.
+        getDevice().deleteFile(mappedArtifacts.iterator().next());
+        mTestUtils.removeCompilationLogToAvoidBackoff();
+        mTestUtils.reboot();
+        verifyGeneratedArtifactsLoaded();
+    }
+
+    private String[] getListFromEnvironmentVariable(String name) throws Exception {
+        String systemServerClasspath = getDevice().executeShellCommand("echo $" + name).trim();
+        if (!systemServerClasspath.isEmpty()) {
+            return systemServerClasspath.split(":");
+        }
+        return new String[0];
+    }
+
+    private String getSystemServerIsa(String mappedArtifact) {
+        // Artifact path for system server artifacts has the form:
+        //    ART_APEX_DALVIK_CACHE_DIRNAME + "/<arch>/system@framework@some.jar@classes.odex"
+        String[] pathComponents = mappedArtifact.split("/");
+        return pathComponents[pathComponents.length - 2];
+    }
+
+    private void verifySystemServerLoadedArtifacts() throws Exception {
+        String[] classpathElements = getListFromEnvironmentVariable("SYSTEMSERVERCLASSPATH");
+        assertTrue("SYSTEMSERVERCLASSPATH is empty", classpathElements.length > 0);
+        String[] standaloneJars = getListFromEnvironmentVariable("STANDALONE_SYSTEMSERVER_JARS");
+        String[] allSystemServerJars = Stream
+                .concat(Arrays.stream(classpathElements), Arrays.stream(standaloneJars))
+                .toArray(String[]::new);
+
+        final Set<String> mappedArtifacts = mTestUtils.getSystemServerLoadedArtifacts();
+        assertTrue(
+                "No mapped artifacts under " + OdsignTestUtils.ART_APEX_DALVIK_CACHE_DIRNAME,
+                mappedArtifacts.size() > 0);
+        final String isa = getSystemServerIsa(mappedArtifacts.iterator().next());
+        final String isaCacheDirectory =
+                String.format("%s/%s", OdsignTestUtils.ART_APEX_DALVIK_CACHE_DIRNAME, isa);
+
+        // Check components in the system_server classpath have mapped artifacts.
+        for (String element : allSystemServerJars) {
+          String escapedPath = element.substring(1).replace('/', '@');
+          for (String extension : OdsignTestUtils.APP_ARTIFACT_EXTENSIONS) {
+            final String fullArtifactPath =
+                    String.format("%s/%s@classes%s", isaCacheDirectory, escapedPath, extension);
+            assertTrue("Missing " + fullArtifactPath, mappedArtifacts.contains(fullArtifactPath));
+          }
+        }
+
+        for (String mappedArtifact : mappedArtifacts) {
+          // Check the mapped artifact has a .art, .odex or .vdex extension.
+          final boolean knownArtifactKind =
+                    OdsignTestUtils.APP_ARTIFACT_EXTENSIONS.stream().anyMatch(
+                            e -> mappedArtifact.endsWith(e));
+          assertTrue("Unknown artifact kind: " + mappedArtifact, knownArtifactKind);
+        }
+    }
+
+    private void verifyZygoteLoadedArtifacts(String zygoteName, Set<String> mappedArtifacts)
+            throws Exception {
+        final String bootImageStem = "boot";
+
+        assertTrue("Expect 3 bootclasspath artifacts", mappedArtifacts.size() == 3);
+
+        String allArtifacts = mappedArtifacts.stream().collect(Collectors.joining(","));
+        for (String extension : OdsignTestUtils.BCP_ARTIFACT_EXTENSIONS) {
+            final String artifact = bootImageStem + extension;
+            final boolean found = mappedArtifacts.stream().anyMatch(a -> a.endsWith(artifact));
+            assertTrue(zygoteName + " " + artifact + " not found: '" + allArtifacts + "'", found);
+        }
+    }
+
+    private void verifyZygotesLoadedArtifacts() throws Exception {
+        // There are potentially two zygote processes "zygote" and "zygote64". These are
+        // instances 32-bit and 64-bit unspecialized app_process processes.
+        // (frameworks/base/cmds/app_process).
+        int zygoteCount = 0;
+        for (String zygoteName : OdsignTestUtils.ZYGOTE_NAMES) {
+            final Optional<Set<String>> mappedArtifacts =
+                    mTestUtils.getZygoteLoadedArtifacts(zygoteName);
+            if (!mappedArtifacts.isPresent()) {
+                continue;
+            }
+            verifyZygoteLoadedArtifacts(zygoteName, mappedArtifacts.get());
+            zygoteCount += 1;
+        }
+        assertTrue("No zygote processes found", zygoteCount > 0);
+    }
+}
diff --git a/test/odsign/test-src/com/android/tests/odsign/CompOsSigningHostTest.java b/test/odsign/test-src/com/android/tests/odsign/CompOsSigningHostTest.java
new file mode 100644
index 0000000..8119a9e
--- /dev/null
+++ b/test/odsign/test-src/com/android/tests/odsign/CompOsSigningHostTest.java
@@ -0,0 +1,196 @@
+/*
+ * Copyright 2022 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 com.android.tests.odsign;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeTrue;
+import static org.junit.Assume.assumeFalse;
+
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.invoker.TestInformation;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import com.android.tradefed.testtype.junit4.AfterClassWithInfo;
+import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
+import com.android.tradefed.testtype.junit4.BeforeClassWithInfo;
+import com.android.tradefed.testtype.junit4.DeviceTestRunOptions;
+import com.android.tradefed.util.CommandResult;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Arrays;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ * Test to check if CompOS works properly.
+ *
+ * @see ActivationTest for actual tests
+ * @see OnDeviceSigningHostTest for the same test with compilation happens in early boot
+ */
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CompOsSigningHostTest extends ActivationTest {
+
+    private static final String COMPOSD_CMD_BIN = "/apex/com.android.compos/bin/composd_cmd";
+    private static final String PENDING_ARTIFACTS_DIR =
+            "/data/misc/apexdata/com.android.art/compos-pending";
+
+    /** odrefresh is currently hard-coded to fail if it does not complete in 300 seconds. */
+    private static final int ODREFRESH_MAX_SECONDS = 300;
+
+    /** Waiting time before starting to check odrefresh progress. */
+    private static final int SECONDS_BEFORE_PROGRESS_CHECK = 30;
+
+    /** Job ID of the pending compilation with staged APEXes. */
+    private static final String JOB_ID = "5132251";
+
+    private static final String ORIGINAL_CHECKSUMS_KEY = "compos_test_orig_checksums";
+    private static final String PENDING_CHECKSUMS_KEY = "compos_test_pending_checksums";
+
+    @BeforeClassWithInfo
+    public static void beforeClassWithDevice(TestInformation testInfo) throws Exception {
+        ITestDevice device = testInfo.getDevice();
+
+        // TODO(216321149): enable when the bug is fixed.
+        assumeFalse("VM fails to boot on user build", device.getBuildFlavor().endsWith("-user"));
+
+        assumeCompOsPresent(device);
+
+        testInfo.properties().put(ORIGINAL_CHECKSUMS_KEY,
+                checksumDirectoryContentPartial(device,
+                    "/data/misc/apexdata/com.android.art/dalvik-cache/"));
+
+        OdsignTestUtils testUtils = new OdsignTestUtils(testInfo);
+        testUtils.installTestApex();
+
+        // Once the test APK is installed, a CompilationJob is scheduled to run when certain
+        // criteria are met, e.g. the device is charging and idle. Since we don't want to wait in
+        // the test, here we start the job by ID immediately.
+        assertCommandSucceeds(device, "cmd jobscheduler run android " + JOB_ID);
+        // It takes time. Just don't spam.
+        TimeUnit.SECONDS.sleep(SECONDS_BEFORE_PROGRESS_CHECK);
+        // The job runs asynchronously. To wait until it completes.
+        waitForJobExit(device, ODREFRESH_MAX_SECONDS - SECONDS_BEFORE_PROGRESS_CHECK);
+
+        // Checks the output validity, then store the hashes of pending files.
+        assertThat(device.getChildren(PENDING_ARTIFACTS_DIR)).asList().containsAtLeast(
+                "cache-info.xml", "compos.info", "compos.info.signature");
+        testInfo.properties().put(PENDING_CHECKSUMS_KEY,
+                checksumDirectoryContentPartial(device,
+                    "/data/misc/apexdata/com.android.art/compos-pending/"));
+
+        testUtils.reboot();
+    }
+
+    @AfterClassWithInfo
+    public static void afterClassWithDevice(TestInformation testInfo) throws Exception {
+        OdsignTestUtils testUtils = new OdsignTestUtils(testInfo);
+        testUtils.uninstallTestApex();
+        testUtils.reboot();
+        testUtils.restoreAdbRoot();
+    }
+
+    @Test
+    public void checkFileChecksums() throws Exception {
+        String actualChecksums = checksumDirectoryContentPartial(getDevice(),
+                "/data/misc/apexdata/com.android.art/dalvik-cache/");
+
+        String pendingChecksums = getTestInformation().properties().get(PENDING_CHECKSUMS_KEY);
+        assertThat(actualChecksums).isEqualTo(pendingChecksums);
+
+        // With test apex, the output should be different.
+        String originalChecksums = getTestInformation().properties().get(ORIGINAL_CHECKSUMS_KEY);
+        assertThat(actualChecksums).isNotEqualTo(originalChecksums);
+    }
+
+    @Ignore("Implement timestamp check when possible. b/215589015")
+    public void verifyFileTimestamps() {}
+
+    @Ignore("Override base class. Due to b/211458160 and b/210998761.")
+    public void verifyGeneratedArtifactsLoaded() {}
+
+    @Ignore("Override base class. Due to b/211458160 and b/210998761.")
+    public void verifyGeneratedArtifactsLoadedAfterPartialCompilation() {}
+
+    @Ignore("Override base class. Due to b/211458160 and b/210998761.")
+    public void verifyGeneratedArtifactsLoadedAfterReboot() {}
+
+    private static String checksumDirectoryContentPartial(ITestDevice device, String path)
+            throws Exception {
+        // Sort by filename (second column) to make comparison easier.
+        // Filter out compos.info* (which will be deleted at boot) and cache-info.xm
+        // compos.info.signature since it's only generated by CompOS.
+        // TODO(b/210473615): Remove irrelevant APEXes (i.e. those aren't contributing to the
+        // classpaths, thus not in the VM) from cache-info.xml.
+        return assertCommandSucceeds(device, "cd " + path + "; find -type f -exec sha256sum {} \\;"
+                + "| grep -v cache-info.xml | grep -v compos.info"
+                + "| sort -k2");
+    }
+
+    private static String assertCommandSucceeds(ITestDevice device, String command)
+            throws DeviceNotAvailableException {
+        CommandResult result = device.executeShellV2Command(command);
+        assertWithMessage(result.toString()).that(result.getExitCode()).isEqualTo(0);
+        return result.getStdout();
+    }
+
+    private static void waitForJobExit(ITestDevice device, int timeout)
+            throws Exception {
+        boolean started = false;
+        for (int i = 0; i < timeout; i++) {
+            CommandResult result = device.executeShellV2Command(
+                    "cmd jobscheduler get-job-state android " + JOB_ID);
+            String state = result.getStdout().toString();
+            if (state.contains("ready") || state.contains("active")) {
+                started = true;
+                TimeUnit.SECONDS.sleep(1);
+            } else if (state.startsWith("unknown")) {
+                if (!started) {
+                    // It's likely that the job hasn't been scheduled. So try again.
+                    TimeUnit.SECONDS.sleep(1);
+                    continue;
+                } else {
+                    // Job has completed
+                    return;
+                }
+            } else {
+                fail("Failing due to unexpected job state: " + result);
+            }
+        }
+        fail("Timed out waiting for the job to complete");
+    }
+
+    public static void assumeCompOsPresent(ITestDevice device) throws Exception {
+        // We have to have kernel support for a VM.
+        assumeTrue(device.doesFileExist("/dev/kvm"));
+
+        // And the CompOS APEX must be present.
+        assumeTrue(device.doesFileExist("/apex/com.android.compos/"));
+    }
+}
diff --git a/test/odsign/test-src/com/android/tests/odsign/OdrefreshHostTest.java b/test/odsign/test-src/com/android/tests/odsign/OdrefreshHostTest.java
index 67d45b3..c6fc37a 100644
--- a/test/odsign/test-src/com/android/tests/odsign/OdrefreshHostTest.java
+++ b/test/odsign/test-src/com/android/tests/odsign/OdrefreshHostTest.java
@@ -61,6 +61,7 @@
     public static void beforeClassWithDevice(TestInformation testInfo) throws Exception {
         OdsignTestUtils testUtils = new OdsignTestUtils(testInfo);
         testUtils.installTestApex();
+        testUtils.reboot();
         testUtils.enableAdbRootOrSkipTest();
 
         HashSet<String> zygoteArtifacts = new HashSet<>();
@@ -79,6 +80,7 @@
     public static void afterClassWithDevice(TestInformation testInfo) throws Exception {
         OdsignTestUtils testUtils = new OdsignTestUtils(testInfo);
         testUtils.uninstallTestApex();
+        testUtils.reboot();
         testUtils.restoreAdbRoot();
     }
 
diff --git a/test/odsign/test-src/com/android/tests/odsign/OdsignTestUtils.java b/test/odsign/test-src/com/android/tests/odsign/OdsignTestUtils.java
index a18286e..edb9fa4 100644
--- a/test/odsign/test-src/com/android/tests/odsign/OdsignTestUtils.java
+++ b/test/odsign/test-src/com/android/tests/odsign/OdsignTestUtils.java
@@ -67,14 +67,12 @@
         assumeTrue("Updating APEX is not supported", mInstallUtils.isApexUpdateSupported());
         mInstallUtils.installApexes(APEX_FILENAME);
         removeCompilationLogToAvoidBackoff();
-        reboot();
     }
 
     public void uninstallTestApex() throws Exception {
         ApexInfo apex = mInstallUtils.getApexInfo(mInstallUtils.getTestFile(APEX_FILENAME));
         mTestInfo.getDevice().uninstallPackage(apex.name);
         removeCompilationLogToAvoidBackoff();
-        reboot();
     }
 
     public Set<String> getMappedArtifacts(String pid, String grepPattern) throws Exception {
diff --git a/test/odsign/test-src/com/android/tests/odsign/OnDeviceSigningHostTest.java b/test/odsign/test-src/com/android/tests/odsign/OnDeviceSigningHostTest.java
index 62d61a2..20a9ba7 100644
--- a/test/odsign/test-src/com/android/tests/odsign/OnDeviceSigningHostTest.java
+++ b/test/odsign/test-src/com/android/tests/odsign/OnDeviceSigningHostTest.java
@@ -16,186 +16,36 @@
 
 package com.android.tests.odsign;
 
-import static org.junit.Assert.assertTrue;
-
 import com.android.tradefed.invoker.TestInformation;
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 import com.android.tradefed.testtype.junit4.AfterClassWithInfo;
 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
 import com.android.tradefed.testtype.junit4.BeforeClassWithInfo;
-import com.android.tradefed.testtype.junit4.DeviceTestRunOptions;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import java.util.Arrays;
-import java.util.List;
-import java.util.Optional;
-import java.util.Set;
-import java.util.stream.Stream;
-import java.util.stream.Collectors;
-
 /**
- * Test to check if odrefresh, odsign, fs-verity, and ART runtime work together properly.
+ * Test to check if the early boot compilation works properly.
+ *
+ * @see ActivationTest for actual tests
+ * @see CompOsSigningHostTest for the same test with compilation happens in the CompOS VM
  */
 @RunWith(DeviceJUnit4ClassRunner.class)
-public class OnDeviceSigningHostTest extends BaseHostJUnit4Test {
-    private static final String TEST_APP_PACKAGE_NAME = "com.android.tests.odsign";
-    private static final String TEST_APP_APK = "odsign_e2e_test_app.apk";
-
-    private OdsignTestUtils mTestUtils;
-
+public class OnDeviceSigningHostTest extends ActivationTest {
     @BeforeClassWithInfo
     public static void beforeClassWithDevice(TestInformation testInfo) throws Exception {
         OdsignTestUtils testUtils = new OdsignTestUtils(testInfo);
         testUtils.installTestApex();
+        testUtils.reboot();
     }
 
     @AfterClassWithInfo
     public static void afterClassWithDevice(TestInformation testInfo) throws Exception {
         OdsignTestUtils testUtils = new OdsignTestUtils(testInfo);
         testUtils.uninstallTestApex();
+        testUtils.reboot();
         testUtils.restoreAdbRoot();
     }
-
-    @Before
-    public void setUp() throws Exception {
-        mTestUtils = new OdsignTestUtils(getTestInformation());
-    }
-
-    @Test
-    public void verifyArtUpgradeSignsFiles() throws Exception {
-        installPackage(TEST_APP_APK);
-        DeviceTestRunOptions options = new DeviceTestRunOptions(TEST_APP_PACKAGE_NAME);
-        options.setTestClassName(TEST_APP_PACKAGE_NAME + ".ArtifactsSignedTest");
-        options.setTestMethodName("testArtArtifactsHaveFsverity");
-        runDeviceTests(options);
-    }
-
-    @Test
-    public void verifyArtUpgradeGeneratesRequiredArtifacts() throws Exception {
-        installPackage(TEST_APP_APK);
-        DeviceTestRunOptions options = new DeviceTestRunOptions(TEST_APP_PACKAGE_NAME);
-        options.setTestClassName(TEST_APP_PACKAGE_NAME + ".ArtifactsSignedTest");
-        options.setTestMethodName("testGeneratesRequiredArtArtifacts");
-        runDeviceTests(options);
-    }
-
-    @Test
-    public void verifyGeneratedArtifactsLoaded() throws Exception {
-        // Checking zygote and system_server need the device have adb root to walk process maps.
-        mTestUtils.enableAdbRootOrSkipTest();
-
-        // Check there is a compilation log, we expect compilation to have occurred.
-        assertTrue("Compilation log not found", mTestUtils.haveCompilationLog());
-
-        // Check both zygote and system_server processes to see that they have loaded the
-        // artifacts compiled and signed by odrefresh and odsign. We check both here rather than
-        // having a separate test because the device reboots between each @Test method and
-        // that is an expensive use of time.
-        verifyZygotesLoadedArtifacts();
-        verifySystemServerLoadedArtifacts();
-    }
-
-    @Test
-    public void verifyGeneratedArtifactsLoadedAfterReboot() throws Exception {
-        mTestUtils.enableAdbRootOrSkipTest();
-
-        mTestUtils.reboot();
-        verifyGeneratedArtifactsLoaded();
-    }
-
-    @Test
-    public void verifyGeneratedArtifactsLoadedAfterPartialCompilation() throws Exception {
-        mTestUtils.enableAdbRootOrSkipTest();
-
-        Set<String> mappedArtifacts = mTestUtils.getSystemServerLoadedArtifacts();
-        // Delete an arbitrary artifact.
-        getDevice().deleteFile(mappedArtifacts.iterator().next());
-        mTestUtils.removeCompilationLogToAvoidBackoff();
-        mTestUtils.reboot();
-        verifyGeneratedArtifactsLoaded();
-    }
-
-    private String[] getListFromEnvironmentVariable(String name) throws Exception {
-        String systemServerClasspath = getDevice().executeShellCommand("echo $" + name).trim();
-        if (!systemServerClasspath.isEmpty()) {
-            return systemServerClasspath.split(":");
-        }
-        return new String[0];
-    }
-
-    private String getSystemServerIsa(String mappedArtifact) {
-        // Artifact path for system server artifacts has the form:
-        //    ART_APEX_DALVIK_CACHE_DIRNAME + "/<arch>/system@framework@some.jar@classes.odex"
-        String[] pathComponents = mappedArtifact.split("/");
-        return pathComponents[pathComponents.length - 2];
-    }
-
-    private void verifySystemServerLoadedArtifacts() throws Exception {
-        String[] classpathElements = getListFromEnvironmentVariable("SYSTEMSERVERCLASSPATH");
-        assertTrue("SYSTEMSERVERCLASSPATH is empty", classpathElements.length > 0);
-        String[] standaloneJars = getListFromEnvironmentVariable("STANDALONE_SYSTEMSERVER_JARS");
-        String[] allSystemServerJars = Stream
-                .concat(Arrays.stream(classpathElements), Arrays.stream(standaloneJars))
-                .toArray(String[]::new);
-
-        final Set<String> mappedArtifacts = mTestUtils.getSystemServerLoadedArtifacts();
-        assertTrue(
-                "No mapped artifacts under " + OdsignTestUtils.ART_APEX_DALVIK_CACHE_DIRNAME,
-                mappedArtifacts.size() > 0);
-        final String isa = getSystemServerIsa(mappedArtifacts.iterator().next());
-        final String isaCacheDirectory =
-                String.format("%s/%s", OdsignTestUtils.ART_APEX_DALVIK_CACHE_DIRNAME, isa);
-
-        // Check components in the system_server classpath have mapped artifacts.
-        for (String element : allSystemServerJars) {
-          String escapedPath = element.substring(1).replace('/', '@');
-          for (String extension : OdsignTestUtils.APP_ARTIFACT_EXTENSIONS) {
-            final String fullArtifactPath =
-                    String.format("%s/%s@classes%s", isaCacheDirectory, escapedPath, extension);
-            assertTrue("Missing " + fullArtifactPath, mappedArtifacts.contains(fullArtifactPath));
-          }
-        }
-
-        for (String mappedArtifact : mappedArtifacts) {
-          // Check the mapped artifact has a .art, .odex or .vdex extension.
-          final boolean knownArtifactKind =
-                    OdsignTestUtils.APP_ARTIFACT_EXTENSIONS.stream().anyMatch(
-                            e -> mappedArtifact.endsWith(e));
-          assertTrue("Unknown artifact kind: " + mappedArtifact, knownArtifactKind);
-        }
-    }
-
-    private void verifyZygoteLoadedArtifacts(String zygoteName, Set<String> mappedArtifacts)
-            throws Exception {
-        final String bootImageStem = "boot";
-
-        assertTrue("Expect 3 bootclasspath artifacts", mappedArtifacts.size() == 3);
-
-        String allArtifacts = mappedArtifacts.stream().collect(Collectors.joining(","));
-        for (String extension : OdsignTestUtils.BCP_ARTIFACT_EXTENSIONS) {
-            final String artifact = bootImageStem + extension;
-            final boolean found = mappedArtifacts.stream().anyMatch(a -> a.endsWith(artifact));
-            assertTrue(zygoteName + " " + artifact + " not found: '" + allArtifacts + "'", found);
-        }
-    }
-
-    private void verifyZygotesLoadedArtifacts() throws Exception {
-        // There are potentially two zygote processes "zygote" and "zygote64". These are
-        // instances 32-bit and 64-bit unspecialized app_process processes.
-        // (frameworks/base/cmds/app_process).
-        int zygoteCount = 0;
-        for (String zygoteName : OdsignTestUtils.ZYGOTE_NAMES) {
-            final Optional<Set<String>> mappedArtifacts =
-                    mTestUtils.getZygoteLoadedArtifacts(zygoteName);
-            if (!mappedArtifacts.isPresent()) {
-                continue;
-            }
-            verifyZygoteLoadedArtifacts(zygoteName, mappedArtifacts.get());
-            zygoteCount += 1;
-        }
-        assertTrue("No zygote processes found", zygoteCount > 0);
-    }
 }