Speed up odsign_e2e_tests.
This change moves preparation code and cleanup code to
@BeforeClassWithInfo and @AfterClassWithInfo respectively, which run
only once. It reduces the runtime of the test by ~85%. After the
change, the test only takes 5 minutes on Cuttlefish.
Note that any test state will NOT be reset after the change. Test cases
are ordered in a way that state changes won't cause problems.
Bug: 199114301
Test: atest odsign_e2e_tests
Change-Id: Ic5ba84a3a274322f5ba8fec3119419cd3c0ee1c4
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 02c2787..2e20591 100644
--- a/test/odsign/test-src/com/android/tests/odsign/OnDeviceSigningHostTest.java
+++ b/test/odsign/test-src/com/android/tests/odsign/OnDeviceSigningHostTest.java
@@ -18,19 +18,21 @@
import static com.google.common.truth.Truth.assertWithMessage;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;
import android.cts.install.lib.host.InstallUtilsHost;
import com.android.tradefed.device.ITestDevice.ApexInfo;
+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.FixMethodOrder;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -68,42 +70,48 @@
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 final InstallUtilsHost mInstallUtils = new InstallUtilsHost(this);
-
private static final Duration BOOT_COMPLETE_TIMEOUT = Duration.ofMinutes(2);
- private final String[] ZYGOTE_NAMES = new String[] {"zygote", "zygote64"};
+ private static final String[] ZYGOTE_NAMES = new String[] {"zygote", "zygote64"};
- private Set<String> mZygoteArtifacts;
- private Set<String> mSystemServerArtifacts;
- private long mBootTimeMs;
+ private static InstallUtilsHost sInstallUtils;
+ private static TestInformation sTestInfo;
- @Before
- public void setUp() throws Exception {
- assumeTrue("Updating APEX is not supported", mInstallUtils.isApexUpdateSupported());
- installPackage(TEST_APP_APK);
- mInstallUtils.installApexes(APEX_FILENAME);
+ private static Set<String> sZygoteArtifacts;
+ private static Set<String> sSystemServerArtifacts;
+
+ @BeforeClassWithInfo
+ public static void beforeClassWithDevice(TestInformation testInfo) throws Exception {
+ assertNotNull(testInfo.getDevice());
+ sInstallUtils = new InstallUtilsHost(testInfo);
+ sTestInfo = testInfo;
+
+ assumeTrue("Updating APEX is not supported", sInstallUtils.isApexUpdateSupported());
+ sInstallUtils.installApexes(APEX_FILENAME);
removeCompilationLogToAvoidBackoff();
reboot();
- mZygoteArtifacts = new HashSet<>();
+ sZygoteArtifacts = new HashSet<>();
for (String zygoteName : ZYGOTE_NAMES) {
- mZygoteArtifacts.addAll(getZygoteLoadedArtifacts(zygoteName).orElse(new HashSet<>()));
+ sZygoteArtifacts.addAll(getZygoteLoadedArtifacts(zygoteName).orElse(new HashSet<>()));
}
- mSystemServerArtifacts = getSystemServerLoadedArtifacts();
- mBootTimeMs = getCurrentTimeMs();
+ sSystemServerArtifacts = getSystemServerLoadedArtifacts();
}
- @After
- public void cleanup() throws Exception {
- ApexInfo apex = mInstallUtils.getApexInfo(mInstallUtils.getTestFile(APEX_FILENAME));
- getDevice().uninstallPackage(apex.name);
+ @AfterClassWithInfo
+ public static void afterClassWithDevice(TestInformation testInfo) throws Exception {
+ ApexInfo apex = sInstallUtils.getApexInfo(sInstallUtils.getTestFile(APEX_FILENAME));
+ testInfo.getDevice().uninstallPackage(apex.name);
removeCompilationLogToAvoidBackoff();
reboot();
}
+ // Test cases starts with `testA` check if odrefresh, odsign, fs-verity, and ART runtime work
+ // together properly.
+
@Test
- public void verifyArtUpgradeSignsFiles() throws Exception {
+ public void testAVerifyArtUpgradeSignsFiles() throws Exception {
+ installPackage(TEST_APP_APK);
DeviceTestRunOptions options = new DeviceTestRunOptions(TEST_APP_PACKAGE_NAME);
options.setTestClassName(TEST_APP_PACKAGE_NAME + ".ArtifactsSignedTest");
options.setTestMethodName("testArtArtifactsHaveFsverity");
@@ -111,16 +119,17 @@
}
@Test
- public void verifyArtUpgradeGeneratesRequiredArtifacts() throws Exception {
+ public void testAVerifyArtUpgradeGeneratesRequiredArtifacts() 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);
}
- private Set<String> getMappedArtifacts(String pid, String grepPattern) throws Exception {
+ private static Set<String> getMappedArtifacts(String pid, String grepPattern) throws Exception {
final String grepCommand = String.format("grep \"%s\" /proc/%s/maps", grepPattern, pid);
- CommandResult result = getDevice().executeShellV2Command(grepCommand);
+ CommandResult result = sTestInfo.getDevice().executeShellV2Command(grepCommand);
assertTrue(result.toString(), result.getExitCode() == 0);
Set<String> mappedFiles = new HashSet<>();
for (String line : result.getStdout().split("\\R")) {
@@ -137,9 +146,10 @@
* Returns the mapped artifacts of the Zygote process, or {@code Optional.empty()} if the
* process does not exist.
*/
- private Optional<Set<String>> getZygoteLoadedArtifacts(String zygoteName) throws Exception {
+ private static Optional<Set<String>> getZygoteLoadedArtifacts(String zygoteName)
+ throws Exception {
final CommandResult result =
- getDevice().executeShellV2Command("pidof " + zygoteName);
+ sTestInfo.getDevice().executeShellV2Command("pidof " + zygoteName);
if (result.getExitCode() != 0) {
return Optional.empty();
}
@@ -155,9 +165,9 @@
return Optional.of(getMappedArtifacts(zygotePid, grepPattern));
}
- private Set<String> getSystemServerLoadedArtifacts() throws Exception {
+ private static Set<String> getSystemServerLoadedArtifacts() throws Exception {
final CommandResult result =
- getDevice().executeShellV2Command("pidof system_server");
+ sTestInfo.getDevice().executeShellV2Command("pidof system_server");
assertTrue(result.toString(), result.getExitCode() == 0);
final String systemServerPid = result.getStdout().trim();
assertTrue(!systemServerPid.isEmpty());
@@ -247,7 +257,7 @@
}
@Test
- public void verifyGeneratedArtifactsLoaded() throws Exception {
+ public void testAVerifyGeneratedArtifactsLoaded() throws Exception {
// Checking zygote and system_server need the device have adb root to walk process maps.
final boolean adbEnabled = getDevice().enableAdbRoot();
assertTrue("ADB root failed and required to get process maps", adbEnabled);
@@ -264,9 +274,9 @@
}
@Test
- public void verifyGeneratedArtifactsLoadedAfterReboot() throws Exception {
+ public void testAVerifyGeneratedArtifactsLoadedAfterReboot() throws Exception {
reboot();
- verifyGeneratedArtifactsLoaded();
+ testAVerifyGeneratedArtifactsLoaded();
}
/**
@@ -367,80 +377,89 @@
return parseFormattedDateTime(dateTimeStr);
}
- void assertArtifactsModifiedAfterBoot(Set<String> artifacts) throws Exception {
+ void assertArtifactsModifiedAfter(Set<String> artifacts, long timeMs) throws Exception {
for (String artifact : artifacts) {
long modifiedTime = getModifiedTimeMs(artifact);
assertTrue(
String.format(
- "Artifact %s is not re-compiled. Modified time: %d, Boot time: %d",
+ "Artifact %s is not re-compiled. Modified time: %d, Reference time: %d",
artifact,
modifiedTime,
- mBootTimeMs),
- modifiedTime > mBootTimeMs);
+ timeMs),
+ modifiedTime > timeMs);
}
}
- void assertArtifactsNotModifiedAfterBoot(Set<String> artifacts) throws Exception {
+ void assertArtifactsNotModifiedAfter(Set<String> artifacts, long timeMs) throws Exception {
for (String artifact : artifacts) {
long modifiedTime = getModifiedTimeMs(artifact);
assertTrue(
String.format(
"Artifact %s is unexpectedly re-compiled. " +
- "Modified time: %d, Boot time: %d",
+ "Modified time: %d, Reference time: %d",
artifact,
modifiedTime,
- mBootTimeMs),
- modifiedTime < mBootTimeMs);
+ timeMs),
+ modifiedTime < timeMs);
}
}
+ // Test cases starts with `testB` check end-to-end odrefresh invocations, but without odsign,
+ // fs-verity, and ART runtime involved. Do not add tests after `testB*` cases that check
+ // fs-verity or runtime behaviors.
+
@Test
- public void verifyArtSamegradeUpdateTriggersCompilation() throws Exception {
+ public void testBVerifyArtSamegradeUpdateTriggersCompilation() throws Exception {
simulateArtApexUpgrade();
removeCompilationLogToAvoidBackoff();
+ long timeMs = getCurrentTimeMs();
getDevice().executeShellV2Command("odrefresh --compile");
- assertArtifactsModifiedAfterBoot(mZygoteArtifacts);
- assertArtifactsModifiedAfterBoot(mSystemServerArtifacts);
+ assertArtifactsModifiedAfter(sZygoteArtifacts, timeMs);
+ assertArtifactsModifiedAfter(sSystemServerArtifacts, timeMs);
}
@Test
- public void verifyOtherApexSamegradeUpdateTriggersCompilation() throws Exception {
+ public void testBVerifyOtherApexSamegradeUpdateTriggersCompilation() throws Exception {
simulateApexUpgrade();
removeCompilationLogToAvoidBackoff();
+ long timeMs = getCurrentTimeMs();
getDevice().executeShellV2Command("odrefresh --compile");
- assertArtifactsNotModifiedAfterBoot(mZygoteArtifacts);
- assertArtifactsModifiedAfterBoot(mSystemServerArtifacts);
+ assertArtifactsNotModifiedAfter(sZygoteArtifacts, timeMs);
+ assertArtifactsModifiedAfter(sSystemServerArtifacts, timeMs);
}
@Test
- public void verifyBootClasspathOtaTriggersCompilation() throws Exception {
+ public void testBVerifyBootClasspathOtaTriggersCompilation() throws Exception {
simulateBootClasspathOta();
removeCompilationLogToAvoidBackoff();
+ long timeMs = getCurrentTimeMs();
getDevice().executeShellV2Command("odrefresh --compile");
- assertArtifactsModifiedAfterBoot(mZygoteArtifacts);
- assertArtifactsModifiedAfterBoot(mSystemServerArtifacts);
+ assertArtifactsModifiedAfter(sZygoteArtifacts, timeMs);
+ assertArtifactsModifiedAfter(sSystemServerArtifacts, timeMs);
}
@Test
- public void verifySystemServerOtaTriggersCompilation() throws Exception {
+ public void testBVerifySystemServerOtaTriggersCompilation() throws Exception {
simulateSystemServerOta();
removeCompilationLogToAvoidBackoff();
+ long timeMs = getCurrentTimeMs();
getDevice().executeShellV2Command("odrefresh --compile");
- assertArtifactsNotModifiedAfterBoot(mZygoteArtifacts);
- assertArtifactsModifiedAfterBoot(mSystemServerArtifacts);
+ assertArtifactsNotModifiedAfter(sZygoteArtifacts, timeMs);
+ assertArtifactsModifiedAfter(sSystemServerArtifacts, timeMs);
}
@Test
- public void verifyNoCompilationWhenCacheIsGood() throws Exception {
+ public void testBVerifyNoCompilationWhenCacheIsGood() throws Exception {
removeCompilationLogToAvoidBackoff();
+ long timeMs = getCurrentTimeMs();
getDevice().executeShellV2Command("odrefresh --compile");
- assertArtifactsNotModifiedAfterBoot(mZygoteArtifacts);
- assertArtifactsNotModifiedAfterBoot(mSystemServerArtifacts);
+ assertArtifactsNotModifiedAfter(sZygoteArtifacts, timeMs);
+ assertArtifactsNotModifiedAfter(sSystemServerArtifacts, timeMs);
}
private boolean haveCompilationLog() throws Exception {
@@ -449,13 +468,14 @@
return result.getExitCode() == 0;
}
- private void removeCompilationLogToAvoidBackoff() throws Exception {
- getDevice().executeShellCommand("rm -f " + ODREFRESH_COMPILATION_LOG);
+ private static void removeCompilationLogToAvoidBackoff() throws Exception {
+ sTestInfo.getDevice().executeShellCommand("rm -f " + ODREFRESH_COMPILATION_LOG);
}
- private void reboot() throws Exception {
- getDevice().reboot();
- boolean success = getDevice().waitForBootComplete(BOOT_COMPLETE_TIMEOUT.toMillis());
+ private static void reboot() throws Exception {
+ sTestInfo.getDevice().reboot();
+ boolean success =
+ sTestInfo.getDevice().waitForBootComplete(BOOT_COMPLETE_TIMEOUT.toMillis());
assertWithMessage("Device didn't boot in %s", BOOT_COMPLETE_TIMEOUT).that(success).isTrue();
}
}