Refactor odsign_e2e_tests.
No-op change, just to make the next CL smaller.
Bug: 272245228
Test: atest odsign_e2e_tests_full:OdrefreshHostTest
Change-Id: I854ca839411bf6ef6b4b1a4eccac98ef3fe596c4
diff --git a/test/odsign/test-src/com/android/tests/odsign/DeviceState.java b/test/odsign/test-src/com/android/tests/odsign/DeviceState.java
index 012908c..8379cba 100644
--- a/test/odsign/test-src/com/android/tests/odsign/DeviceState.java
+++ b/test/odsign/test-src/com/android/tests/odsign/DeviceState.java
@@ -43,6 +43,8 @@
private static final String APEX_INFO_FILE = "/apex/apex-info-list.xml";
private static final String TEST_JAR_RESOURCE_NAME = "/art-gtest-jars-Main.jar";
private static final String PHENOTYPE_FLAG_NAMESPACE = "runtime_native_boot";
+ private static final String ART_APEX_DALVIK_CACHE_BACKUP_DIRNAME =
+ OdsignTestUtils.ART_APEX_DALVIK_CACHE_DIRNAME + ".bak";
private final TestInformation mTestInfo;
private final OdsignTestUtils mTestUtils;
@@ -51,6 +53,7 @@
private Set<String> mMountPoints = new HashSet<>();
private Map<String, String> mMutatedProperties = new HashMap<>();
private Set<String> mMutatedPhenotypeFlags = new HashSet<>();
+ private boolean mHasArtifactsBackup = false;
public DeviceState(TestInformation testInfo) throws Exception {
mTestInfo = testInfo;
@@ -81,6 +84,14 @@
mTestInfo.getDevice().executeShellV2Command(
"device_config set_sync_disabled_for_tests none");
}
+
+ if (mHasArtifactsBackup) {
+ mTestInfo.getDevice().executeShellV2Command(
+ String.format("rm -rf '%s'", OdsignTestUtils.ART_APEX_DALVIK_CACHE_DIRNAME));
+ mTestInfo.getDevice().executeShellV2Command(
+ String.format("mv '%s' '%s'", ART_APEX_DALVIK_CACHE_BACKUP_DIRNAME,
+ OdsignTestUtils.ART_APEX_DALVIK_CACHE_DIRNAME));
+ }
}
/** Simulates that the ART APEX has been upgraded. */
@@ -163,6 +174,15 @@
}
}
+ public void backupArtifacts() throws Exception {
+ mTestInfo.getDevice().executeShellV2Command(
+ String.format("rm -rf '%s'", ART_APEX_DALVIK_CACHE_BACKUP_DIRNAME));
+ mTestUtils.assertCommandSucceeds(
+ String.format("cp -r '%s' '%s'", OdsignTestUtils.ART_APEX_DALVIK_CACHE_DIRNAME,
+ ART_APEX_DALVIK_CACHE_BACKUP_DIRNAME));
+ mHasArtifactsBackup = true;
+ }
+
/**
* Pushes the file to a temporary location and bind-mount it at the given path. This is useful
* when the path is readonly.
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 ab0297b..83424ce 100644
--- a/test/odsign/test-src/com/android/tests/odsign/OdrefreshHostTest.java
+++ b/test/odsign/test-src/com/android/tests/odsign/OdrefreshHostTest.java
@@ -17,9 +17,7 @@
package com.android.tests.odsign;
import static com.google.common.truth.Truth.assertThat;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
+import static com.google.common.truth.Truth.assertWithMessage;
import com.android.tradefed.invoker.TestInformation;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
@@ -32,7 +30,6 @@
import org.junit.Test;
import org.junit.runner.RunWith;
-import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
@@ -42,16 +39,6 @@
*/
@RunWith(DeviceJUnit4ClassRunner.class)
public class OdrefreshHostTest extends BaseHostJUnit4Test {
- private static final String CACHE_INFO_FILE =
- OdsignTestUtils.ART_APEX_DALVIK_CACHE_DIRNAME + "/cache-info.xml";
- private static final String ODREFRESH_BIN = "odrefresh";
- private static final String ART_APEX_DALVIK_CACHE_BACKUP_DIRNAME =
- OdsignTestUtils.ART_APEX_DALVIK_CACHE_DIRNAME + ".bak";
-
- private static final String TAG = "OdrefreshHostTest";
- private static final String ZYGOTE_ARTIFACTS_KEY = TAG + ":ZYGOTE_ARTIFACTS";
- private static final String SYSTEM_SERVER_ARTIFACTS_KEY = TAG + ":SYSTEM_SERVER_ARTIFACTS";
-
private OdsignTestUtils mTestUtils;
private DeviceState mDeviceState;
@@ -60,30 +47,10 @@
OdsignTestUtils testUtils = new OdsignTestUtils(testInfo);
testUtils.installTestApex();
testUtils.reboot();
-
- HashSet<String> zygoteArtifacts = new HashSet<>();
- for (String zygoteName : testUtils.ZYGOTE_NAMES) {
- zygoteArtifacts.addAll(
- testUtils.getZygoteLoadedArtifacts(zygoteName).orElse(new HashSet<>()));
- }
- Set<String> systemServerArtifacts = testUtils.getSystemServerLoadedArtifacts();
-
- testInfo.properties().put(ZYGOTE_ARTIFACTS_KEY, String.join(":", zygoteArtifacts));
- testInfo.properties()
- .put(SYSTEM_SERVER_ARTIFACTS_KEY, String.join(":", systemServerArtifacts));
-
- // Backup the artifacts.
- testInfo.getDevice().executeShellV2Command(
- String.format("rm -rf '%s'", ART_APEX_DALVIK_CACHE_BACKUP_DIRNAME));
- testUtils.assertCommandSucceeds(
- String.format("cp -r '%s' '%s'", OdsignTestUtils.ART_APEX_DALVIK_CACHE_DIRNAME,
- ART_APEX_DALVIK_CACHE_BACKUP_DIRNAME));
}
@AfterClassWithInfo
public static void afterClassWithDevice(TestInformation testInfo) throws Exception {
- testInfo.getDevice().executeShellV2Command(
- String.format("rm -rf '%s'", ART_APEX_DALVIK_CACHE_BACKUP_DIRNAME));
OdsignTestUtils testUtils = new OdsignTestUtils(testInfo);
testUtils.uninstallTestApex();
testUtils.reboot();
@@ -93,13 +60,7 @@
public void setUp() throws Exception {
mTestUtils = new OdsignTestUtils(getTestInformation());
mDeviceState = new DeviceState(getTestInformation());
-
- // Restore the artifacts to ensure a clean initial state.
- getDevice().executeShellV2Command(
- String.format("rm -rf '%s'", OdsignTestUtils.ART_APEX_DALVIK_CACHE_DIRNAME));
- mTestUtils.assertCommandSucceeds(
- String.format("cp -r '%s' '%s'", ART_APEX_DALVIK_CACHE_BACKUP_DIRNAME,
- OdsignTestUtils.ART_APEX_DALVIK_CACHE_DIRNAME));
+ mDeviceState.backupArtifacts();
}
@After
@@ -111,56 +72,56 @@
public void verifyArtSamegradeUpdateTriggersCompilation() throws Exception {
mDeviceState.simulateArtApexUpgrade();
long timeMs = mTestUtils.getCurrentTimeMs();
- runOdrefresh();
+ mTestUtils.runOdrefresh();
- assertArtifactsModifiedAfter(getZygoteArtifacts(), timeMs);
- assertArtifactsModifiedAfter(getSystemServerArtifacts(), timeMs);
+ mTestUtils.assertModifiedAfter(mTestUtils.getZygotesExpectedArtifacts(), timeMs);
+ mTestUtils.assertModifiedAfter(mTestUtils.getSystemServerExpectedArtifacts(), timeMs);
}
@Test
public void verifyOtherApexSamegradeUpdateTriggersCompilation() throws Exception {
mDeviceState.simulateApexUpgrade();
long timeMs = mTestUtils.getCurrentTimeMs();
- runOdrefresh();
+ mTestUtils.runOdrefresh();
- assertArtifactsNotModifiedAfter(getZygoteArtifacts(), timeMs);
- assertArtifactsModifiedAfter(getSystemServerArtifacts(), timeMs);
+ mTestUtils.assertNotModifiedAfter(mTestUtils.getZygotesExpectedArtifacts(), timeMs);
+ mTestUtils.assertModifiedAfter(mTestUtils.getSystemServerExpectedArtifacts(), timeMs);
}
@Test
public void verifyBootClasspathOtaTriggersCompilation() throws Exception {
mDeviceState.simulateBootClasspathOta();
long timeMs = mTestUtils.getCurrentTimeMs();
- runOdrefresh();
+ mTestUtils.runOdrefresh();
- assertArtifactsModifiedAfter(getZygoteArtifacts(), timeMs);
- assertArtifactsModifiedAfter(getSystemServerArtifacts(), timeMs);
+ mTestUtils.assertModifiedAfter(mTestUtils.getZygotesExpectedArtifacts(), timeMs);
+ mTestUtils.assertModifiedAfter(mTestUtils.getSystemServerExpectedArtifacts(), timeMs);
}
@Test
public void verifySystemServerOtaTriggersCompilation() throws Exception {
mDeviceState.simulateSystemServerOta();
long timeMs = mTestUtils.getCurrentTimeMs();
- runOdrefresh();
+ mTestUtils.runOdrefresh();
- assertArtifactsNotModifiedAfter(getZygoteArtifacts(), timeMs);
- assertArtifactsModifiedAfter(getSystemServerArtifacts(), timeMs);
+ mTestUtils.assertNotModifiedAfter(mTestUtils.getZygotesExpectedArtifacts(), timeMs);
+ mTestUtils.assertModifiedAfter(mTestUtils.getSystemServerExpectedArtifacts(), timeMs);
}
@Test
public void verifyMissingArtifactTriggersCompilation() throws Exception {
Set<String> missingArtifacts = simulateMissingArtifacts();
Set<String> remainingArtifacts = new HashSet<>();
- remainingArtifacts.addAll(getZygoteArtifacts());
- remainingArtifacts.addAll(getSystemServerArtifacts());
+ remainingArtifacts.addAll(mTestUtils.getZygotesExpectedArtifacts());
+ remainingArtifacts.addAll(mTestUtils.getSystemServerExpectedArtifacts());
remainingArtifacts.removeAll(missingArtifacts);
mTestUtils.removeCompilationLogToAvoidBackoff();
long timeMs = mTestUtils.getCurrentTimeMs();
- runOdrefresh();
+ mTestUtils.runOdrefresh();
- assertArtifactsNotModifiedAfter(remainingArtifacts, timeMs);
- assertArtifactsModifiedAfter(missingArtifacts, timeMs);
+ mTestUtils.assertNotModifiedAfter(remainingArtifacts, timeMs);
+ mTestUtils.assertModifiedAfter(missingArtifacts, timeMs);
}
@Test
@@ -168,37 +129,37 @@
mDeviceState.setPhenotypeFlag("enable_uffd_gc", "false");
long timeMs = mTestUtils.getCurrentTimeMs();
- runOdrefresh();
+ mTestUtils.runOdrefresh();
// Artifacts should be re-compiled.
- assertArtifactsModifiedAfter(getZygoteArtifacts(), timeMs);
- assertArtifactsModifiedAfter(getSystemServerArtifacts(), timeMs);
+ mTestUtils.assertModifiedAfter(mTestUtils.getZygotesExpectedArtifacts(), timeMs);
+ mTestUtils.assertModifiedAfter(mTestUtils.getSystemServerExpectedArtifacts(), timeMs);
mDeviceState.setPhenotypeFlag("enable_uffd_gc", "true");
timeMs = mTestUtils.getCurrentTimeMs();
- runOdrefresh();
+ mTestUtils.runOdrefresh();
// Artifacts should be re-compiled.
- assertArtifactsModifiedAfter(getZygoteArtifacts(), timeMs);
- assertArtifactsModifiedAfter(getSystemServerArtifacts(), timeMs);
+ mTestUtils.assertModifiedAfter(mTestUtils.getZygotesExpectedArtifacts(), timeMs);
+ mTestUtils.assertModifiedAfter(mTestUtils.getSystemServerExpectedArtifacts(), timeMs);
// Run odrefresh again with the flag unchanged.
timeMs = mTestUtils.getCurrentTimeMs();
- runOdrefresh();
+ mTestUtils.runOdrefresh();
// Artifacts should not be re-compiled.
- assertArtifactsNotModifiedAfter(getZygoteArtifacts(), timeMs);
- assertArtifactsNotModifiedAfter(getSystemServerArtifacts(), timeMs);
+ mTestUtils.assertNotModifiedAfter(mTestUtils.getZygotesExpectedArtifacts(), timeMs);
+ mTestUtils.assertNotModifiedAfter(mTestUtils.getSystemServerExpectedArtifacts(), timeMs);
mDeviceState.setPhenotypeFlag("enable_uffd_gc", null);
timeMs = mTestUtils.getCurrentTimeMs();
- runOdrefresh();
+ mTestUtils.runOdrefresh();
// Artifacts should be re-compiled.
- assertArtifactsModifiedAfter(getZygoteArtifacts(), timeMs);
- assertArtifactsModifiedAfter(getSystemServerArtifacts(), timeMs);
+ mTestUtils.assertModifiedAfter(mTestUtils.getZygotesExpectedArtifacts(), timeMs);
+ mTestUtils.assertModifiedAfter(mTestUtils.getSystemServerExpectedArtifacts(), timeMs);
}
@Test
@@ -207,37 +168,37 @@
mDeviceState.setPhenotypeFlag("systemservercompilerfilter_override", null);
long timeMs = mTestUtils.getCurrentTimeMs();
- runOdrefresh();
+ mTestUtils.runOdrefresh();
// Artifacts should not be re-compiled.
- assertArtifactsNotModifiedAfter(getZygoteArtifacts(), timeMs);
- assertArtifactsNotModifiedAfter(getSystemServerArtifacts(), timeMs);
+ mTestUtils.assertNotModifiedAfter(mTestUtils.getZygotesExpectedArtifacts(), timeMs);
+ mTestUtils.assertNotModifiedAfter(mTestUtils.getSystemServerExpectedArtifacts(), timeMs);
mDeviceState.setPhenotypeFlag("systemservercompilerfilter_override", "speed");
timeMs = mTestUtils.getCurrentTimeMs();
- runOdrefresh();
+ mTestUtils.runOdrefresh();
// Artifacts should be re-compiled.
- assertArtifactsModifiedAfter(getZygoteArtifacts(), timeMs);
- assertArtifactsModifiedAfter(getSystemServerArtifacts(), timeMs);
+ mTestUtils.assertModifiedAfter(mTestUtils.getZygotesExpectedArtifacts(), timeMs);
+ mTestUtils.assertModifiedAfter(mTestUtils.getSystemServerExpectedArtifacts(), timeMs);
// Run odrefresh again with the flag unchanged.
timeMs = mTestUtils.getCurrentTimeMs();
- runOdrefresh();
+ mTestUtils.runOdrefresh();
// Artifacts should not be re-compiled.
- assertArtifactsNotModifiedAfter(getZygoteArtifacts(), timeMs);
- assertArtifactsNotModifiedAfter(getSystemServerArtifacts(), timeMs);
+ mTestUtils.assertNotModifiedAfter(mTestUtils.getZygotesExpectedArtifacts(), timeMs);
+ mTestUtils.assertNotModifiedAfter(mTestUtils.getSystemServerExpectedArtifacts(), timeMs);
mDeviceState.setPhenotypeFlag("systemservercompilerfilter_override", "verify");
timeMs = mTestUtils.getCurrentTimeMs();
- runOdrefresh();
+ mTestUtils.runOdrefresh();
// Artifacts should be re-compiled.
- assertArtifactsModifiedAfter(getZygoteArtifacts(), timeMs);
- assertArtifactsModifiedAfter(getSystemServerArtifacts(), timeMs);
+ mTestUtils.assertModifiedAfter(mTestUtils.getZygotesExpectedArtifacts(), timeMs);
+ mTestUtils.assertModifiedAfter(mTestUtils.getSystemServerExpectedArtifacts(), timeMs);
}
@Test
@@ -245,77 +206,77 @@
// Change a system property from empty to a value.
mDeviceState.setProperty("dalvik.vm.foo", "1");
long timeMs = mTestUtils.getCurrentTimeMs();
- runOdrefresh();
+ mTestUtils.runOdrefresh();
// Artifacts should be re-compiled.
- assertArtifactsModifiedAfter(getZygoteArtifacts(), timeMs);
- assertArtifactsModifiedAfter(getSystemServerArtifacts(), timeMs);
+ mTestUtils.assertModifiedAfter(mTestUtils.getZygotesExpectedArtifacts(), timeMs);
+ mTestUtils.assertModifiedAfter(mTestUtils.getSystemServerExpectedArtifacts(), timeMs);
// Run again with the same value.
timeMs = mTestUtils.getCurrentTimeMs();
- runOdrefresh();
+ mTestUtils.runOdrefresh();
// Artifacts should not be re-compiled.
- assertArtifactsNotModifiedAfter(getZygoteArtifacts(), timeMs);
- assertArtifactsNotModifiedAfter(getSystemServerArtifacts(), timeMs);
+ mTestUtils.assertNotModifiedAfter(mTestUtils.getZygotesExpectedArtifacts(), timeMs);
+ mTestUtils.assertNotModifiedAfter(mTestUtils.getSystemServerExpectedArtifacts(), timeMs);
// Change the system property to another value.
mDeviceState.setProperty("dalvik.vm.foo", "2");
timeMs = mTestUtils.getCurrentTimeMs();
- runOdrefresh();
+ mTestUtils.runOdrefresh();
// Artifacts should be re-compiled.
- assertArtifactsModifiedAfter(getZygoteArtifacts(), timeMs);
- assertArtifactsModifiedAfter(getSystemServerArtifacts(), timeMs);
+ mTestUtils.assertModifiedAfter(mTestUtils.getZygotesExpectedArtifacts(), timeMs);
+ mTestUtils.assertModifiedAfter(mTestUtils.getSystemServerExpectedArtifacts(), timeMs);
// Run again with the same value.
timeMs = mTestUtils.getCurrentTimeMs();
- runOdrefresh();
+ mTestUtils.runOdrefresh();
// Artifacts should not be re-compiled.
- assertArtifactsNotModifiedAfter(getZygoteArtifacts(), timeMs);
- assertArtifactsNotModifiedAfter(getSystemServerArtifacts(), timeMs);
+ mTestUtils.assertNotModifiedAfter(mTestUtils.getZygotesExpectedArtifacts(), timeMs);
+ mTestUtils.assertNotModifiedAfter(mTestUtils.getSystemServerExpectedArtifacts(), timeMs);
// Change the system property to empty.
mDeviceState.setProperty("dalvik.vm.foo", "");
timeMs = mTestUtils.getCurrentTimeMs();
- runOdrefresh();
+ mTestUtils.runOdrefresh();
// Artifacts should be re-compiled.
- assertArtifactsModifiedAfter(getZygoteArtifacts(), timeMs);
- assertArtifactsModifiedAfter(getSystemServerArtifacts(), timeMs);
+ mTestUtils.assertModifiedAfter(mTestUtils.getZygotesExpectedArtifacts(), timeMs);
+ mTestUtils.assertModifiedAfter(mTestUtils.getSystemServerExpectedArtifacts(), timeMs);
// Run again with the same value.
timeMs = mTestUtils.getCurrentTimeMs();
- runOdrefresh();
+ mTestUtils.runOdrefresh();
// Artifacts should not be re-compiled.
- assertArtifactsNotModifiedAfter(getZygoteArtifacts(), timeMs);
- assertArtifactsNotModifiedAfter(getSystemServerArtifacts(), timeMs);
+ mTestUtils.assertNotModifiedAfter(mTestUtils.getZygotesExpectedArtifacts(), timeMs);
+ mTestUtils.assertNotModifiedAfter(mTestUtils.getSystemServerExpectedArtifacts(), timeMs);
}
@Test
public void verifyNoCompilationWhenCacheIsGood() throws Exception {
mTestUtils.removeCompilationLogToAvoidBackoff();
long timeMs = mTestUtils.getCurrentTimeMs();
- runOdrefresh();
+ mTestUtils.runOdrefresh();
- assertArtifactsNotModifiedAfter(getZygoteArtifacts(), timeMs);
- assertArtifactsNotModifiedAfter(getSystemServerArtifacts(), timeMs);
+ mTestUtils.assertNotModifiedAfter(mTestUtils.getZygotesExpectedArtifacts(), timeMs);
+ mTestUtils.assertNotModifiedAfter(mTestUtils.getSystemServerExpectedArtifacts(), timeMs);
}
@Test
public void verifyUnexpectedFilesAreCleanedUp() throws Exception {
String unexpected = OdsignTestUtils.ART_APEX_DALVIK_CACHE_DIRNAME + "/unexpected";
getDevice().pushString("" /* contents */, unexpected);
- runOdrefresh();
+ mTestUtils.runOdrefresh();
- assertFalse(getDevice().doesFileExist(unexpected));
+ assertThat(getDevice().doesFileExist(unexpected)).isFalse();
}
@Test
public void verifyCacheInfoOmitsIrrelevantApexes() throws Exception {
- String cacheInfo = getDevice().pullFileContents(CACHE_INFO_FILE);
+ String cacheInfo = getDevice().pullFileContents(OdsignTestUtils.CACHE_INFO_FILE);
// cacheInfo should list all APEXes that have compilable JARs and
// none that do not.
@@ -332,12 +293,12 @@
mTestUtils.removeCompilationLogToAvoidBackoff();
mDeviceState.simulateApexUpgrade();
long timeMs = mTestUtils.getCurrentTimeMs();
- runOdrefresh("--compilation-os-mode");
+ mTestUtils.runOdrefresh("--compilation-os-mode");
- assertArtifactsNotModifiedAfter(getZygoteArtifacts(), timeMs);
- assertArtifactsModifiedAfter(getSystemServerArtifacts(), timeMs);
+ mTestUtils.assertNotModifiedAfter(mTestUtils.getZygotesExpectedArtifacts(), timeMs);
+ mTestUtils.assertModifiedAfter(mTestUtils.getSystemServerExpectedArtifacts(), timeMs);
- String cacheInfo = getDevice().pullFileContents(CACHE_INFO_FILE);
+ String cacheInfo = getDevice().pullFileContents(OdsignTestUtils.CACHE_INFO_FILE);
assertThat(cacheInfo).contains("compilationOsMode=\"true\"");
// Compilation OS does not write the compilation log to the host.
@@ -345,116 +306,57 @@
// Simulate the odrefresh invocation on the next boot.
timeMs = mTestUtils.getCurrentTimeMs();
- runOdrefresh();
+ mTestUtils.runOdrefresh();
// odrefresh should not re-compile anything.
- assertArtifactsNotModifiedAfter(getZygoteArtifacts(), timeMs);
- assertArtifactsNotModifiedAfter(getSystemServerArtifacts(), timeMs);
+ mTestUtils.assertNotModifiedAfter(mTestUtils.getZygotesExpectedArtifacts(), timeMs);
+ mTestUtils.assertNotModifiedAfter(mTestUtils.getSystemServerExpectedArtifacts(), timeMs);
}
@Test
public void verifyMinimalCompilation() throws Exception {
mTestUtils.removeCompilationLogToAvoidBackoff();
getDevice().executeShellV2Command(
- "rm -rf " + OdsignTestUtils.ART_APEX_DALVIK_CACHE_DIRNAME);
- runOdrefresh("--minimal");
+ "rm -rf " + OdsignTestUtils.ART_APEX_DALVIK_CACHE_DIRNAME);
+ mTestUtils.runOdrefresh("--minimal");
mTestUtils.restartZygote();
// The minimal boot image should be loaded.
- Set<String> minimalZygoteArtifacts =
- mTestUtils.verifyZygotesLoadedArtifacts("boot_minimal");
+ mTestUtils.verifyZygotesLoadedArtifacts("boot_minimal");
// Running the command again should not overwrite the minimal boot image.
mTestUtils.removeCompilationLogToAvoidBackoff();
long timeMs = mTestUtils.getCurrentTimeMs();
- runOdrefresh("--minimal");
+ mTestUtils.runOdrefresh("--minimal");
- assertArtifactsNotModifiedAfter(minimalZygoteArtifacts, timeMs);
+ Set<String> minimalZygoteArtifacts = mTestUtils.getZygotesExpectedArtifacts("boot_minimal");
+ mTestUtils.assertNotModifiedAfter(minimalZygoteArtifacts, timeMs);
// A normal odrefresh invocation should replace the minimal boot image with a full one.
mTestUtils.removeCompilationLogToAvoidBackoff();
timeMs = mTestUtils.getCurrentTimeMs();
- runOdrefresh();
+ mTestUtils.runOdrefresh();
for (String artifact : minimalZygoteArtifacts) {
- assertFalse(
+ assertWithMessage(
String.format(
- "Artifact %s should be cleaned up while it still exists", artifact),
- getDevice().doesFileExist(artifact));
+ "Artifact %s should be cleaned up while it still exists", artifact))
+ .that(getDevice().doesFileExist(artifact))
+ .isFalse();
}
- assertArtifactsModifiedAfter(getZygoteArtifacts(), timeMs);
+ mTestUtils.assertModifiedAfter(mTestUtils.getZygotesExpectedArtifacts(), timeMs);
}
private Set<String> simulateMissingArtifacts() throws Exception {
Set<String> missingArtifacts = new HashSet<>();
- String sample = getSystemServerArtifacts().iterator().next();
+ String sample = mTestUtils.getSystemServerExpectedArtifacts().iterator().next();
for (String extension : OdsignTestUtils.APP_ARTIFACT_EXTENSIONS) {
- String artifact = replaceExtension(sample, extension);
+ String artifact = OdsignTestUtils.replaceExtension(sample, extension);
getDevice().deleteFile(artifact);
missingArtifacts.add(artifact);
}
return missingArtifacts;
}
-
- private void assertArtifactsModifiedAfter(Set<String> artifacts, long timeMs) throws Exception {
- for (String artifact : artifacts) {
- long modifiedTime = mTestUtils.getModifiedTimeMs(artifact);
- assertTrue(
- String.format(
- "Artifact %s is not re-compiled. Modified time: %d, Reference time: %d",
- artifact,
- modifiedTime,
- timeMs),
- modifiedTime > timeMs);
- }
- }
-
- private void assertArtifactsNotModifiedAfter(Set<String> artifacts, long timeMs)
- throws Exception {
- for (String artifact : artifacts) {
- long modifiedTime = mTestUtils.getModifiedTimeMs(artifact);
- assertTrue(
- String.format(
- "Artifact %s is unexpectedly re-compiled. " +
- "Modified time: %d, Reference time: %d",
- artifact,
- modifiedTime,
- timeMs),
- modifiedTime < timeMs);
- }
- }
-
- private String replaceExtension(String filename, String extension) throws Exception {
- int index = filename.lastIndexOf(".");
- assertTrue("Extension not found in filename: " + filename, index != -1);
- return filename.substring(0, index) + extension;
- }
-
- private Set<String> getColonSeparatedSet(String key) {
- String value = getTestInformation().properties().get(key);
- if (value == null || value.isEmpty()) {
- return new HashSet<>();
- }
- return new HashSet<>(Arrays.asList(value.split(":")));
- }
-
- private Set<String> getZygoteArtifacts() {
- return getColonSeparatedSet(ZYGOTE_ARTIFACTS_KEY);
- }
-
- private Set<String> getSystemServerArtifacts() {
- return getColonSeparatedSet(SYSTEM_SERVER_ARTIFACTS_KEY);
- }
-
- private void runOdrefresh() throws Exception {
- runOdrefresh("" /* extraArgs */);
- }
-
- private void runOdrefresh(String extraArgs) throws Exception {
- getDevice().executeShellV2Command(ODREFRESH_BIN + " --check");
- getDevice().executeShellV2Command(
- ODREFRESH_BIN + " --partial-compilation --no-refresh " + extraArgs + " --compile");
- }
}
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 a11139e..83cd881 100644
--- a/test/odsign/test-src/com/android/tests/odsign/OdsignTestUtils.java
+++ b/test/odsign/test-src/com/android/tests/odsign/OdsignTestUtils.java
@@ -21,8 +21,6 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;
@@ -30,7 +28,6 @@
import com.android.tradefed.device.DeviceNotAvailableException;
import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.device.ITestDevice.ApexInfo;
import com.android.tradefed.device.TestDeviceOptions;
import com.android.tradefed.invoker.TestInformation;
import com.android.tradefed.result.FileInputStreamSource;
@@ -48,20 +45,24 @@
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
-import java.util.Optional;
+import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import java.util.stream.Collectors;
import java.util.stream.Stream;
public class OdsignTestUtils {
public static final String ART_APEX_DALVIK_CACHE_DIRNAME =
"/data/misc/apexdata/com.android.art/dalvik-cache";
+ public static final String CACHE_INFO_FILE = ART_APEX_DALVIK_CACHE_DIRNAME + "/cache-info.xml";
- public static final List<String> ZYGOTE_NAMES = List.of("zygote", "zygote64");
+ private static final String ODREFRESH_BIN = "odrefresh";
+
+ public static final String ZYGOTE_32_NAME = "zygote";
+ public static final String ZYGOTE_64_NAME = "zygote64";
public static final List<String> APP_ARTIFACT_EXTENSIONS = List.of(".art", ".odex", ".vdex");
public static final List<String> BCP_ARTIFACT_EXTENSIONS = List.of(".art", ".oat", ".vdex");
@@ -75,11 +76,17 @@
private static final String TAG = "OdsignTestUtils";
private static final String PACKAGE_NAME_KEY = TAG + ":PACKAGE_NAME";
+ // Keep in sync with `ABI_TO_INSTRUCTION_SET_MAP` in
+ // libcore/libart/src/main/java/dalvik/system/VMRuntime.java.
+ private static final Map<String, String> ABI_TO_INSTRUCTION_SET_MAP =
+ Map.of("armeabi", "arm", "armeabi-v7a", "arm", "x86", "x86", "x86_64", "x86_64",
+ "arm64-v8a", "arm64", "arm64-v8a-hwasan", "arm64", "riscv64", "riscv64");
+
private final InstallUtilsHost mInstallUtils;
private final TestInformation mTestInfo;
public OdsignTestUtils(TestInformation testInfo) throws Exception {
- assertNotNull(testInfo.getDevice());
+ assertThat(testInfo.getDevice()).isNotNull();
mInstallUtils = new InstallUtilsHost(testInfo);
mTestInfo = testInfo;
}
@@ -93,17 +100,13 @@
String packagesOutput =
mTestInfo.getDevice().executeShellCommand("pm list packages -f --apex-only");
Pattern p = Pattern.compile(
- "^package:(.*)=(com(?:\\.google)?\\.android(?:\\.go)?\\.art)$",
- Pattern.MULTILINE);
+ "^package:(.*)=(com(?:\\.google)?\\.android(?:\\.go)?\\.art)$", Pattern.MULTILINE);
Matcher m = p.matcher(packagesOutput);
assertTrue("ART module not found. Packages are:\n" + packagesOutput, m.find());
String artApexPath = m.group(1);
String artApexName = m.group(2);
- CommandResult result = mTestInfo.getDevice().executeShellV2Command(
- "pm install --apex " + artApexPath);
- assertWithMessage("Failed to install APEX. Reason: " + result.toString())
- .that(result.getExitCode()).isEqualTo(0);
+ assertCommandSucceeds("pm install --apex " + artApexPath);
mTestInfo.properties().put(PACKAGE_NAME_KEY, artApexName);
@@ -119,14 +122,14 @@
}
public Set<String> getMappedArtifacts(String pid, String grepPattern) throws Exception {
- final String grepCommand = String.format("grep \"%s\" /proc/%s/maps", grepPattern, pid);
- CommandResult result = mTestInfo.getDevice().executeShellV2Command(grepCommand);
- assertTrue(result.toString(), result.getExitCode() == 0);
+ String grepCommand = String.format("grep \"%s\" /proc/%s/maps", grepPattern, pid);
Set<String> mappedFiles = new HashSet<>();
- for (String line : result.getStdout().split("\\R")) {
+ for (String line : assertCommandSucceeds(grepCommand).split("\\R")) {
int start = line.indexOf(ART_APEX_DALVIK_CACHE_DIRNAME);
- if (line.contains("[")) {
- continue; // ignore anonymously mapped sections which are quoted in square braces.
+ if (line.contains("[") || line.contains("(deleted)")) {
+ // Ignore anonymously mapped sections, which are quoted in square braces, and
+ // deleted mapped files.
+ continue;
}
mappedFiles.add(line.substring(start));
}
@@ -134,110 +137,88 @@
}
/**
- * Returns the mapped artifacts of the Zygote process, or {@code Optional.empty()} if the
- * process does not exist.
+ * Returns the mapped artifacts of the Zygote process.
*/
- public Optional<Set<String>> getZygoteLoadedArtifacts(String zygoteName) throws Exception {
- final CommandResult result =
- mTestInfo.getDevice().executeShellV2Command("pidof " + zygoteName);
- if (result.getExitCode() != 0) {
- return Optional.empty();
- }
+ public Set<String> getZygoteLoadedArtifacts(String zygoteName) throws Exception {
// There may be multiple Zygote processes when Zygote just forks and has not executed any
// app binary. We can take any of the pids.
// We can't use the "-s" flag when calling `pidof` because the Toybox's `pidof`
// implementation is wrong and it outputs multiple pids regardless of the "-s" flag, so we
// split the output and take the first pid ourselves.
- final String zygotePid = result.getStdout().trim().split("\\s+")[0];
+ String zygotePid = assertCommandSucceeds("pidof " + zygoteName).split("\\s+")[0];
assertTrue(!zygotePid.isEmpty());
- final String grepPattern = ART_APEX_DALVIK_CACHE_DIRNAME + ".*boot";
- return Optional.of(getMappedArtifacts(zygotePid, grepPattern));
+ String grepPattern = ART_APEX_DALVIK_CACHE_DIRNAME + "/.*/boot";
+ return getMappedArtifacts(zygotePid, grepPattern);
}
public Set<String> getSystemServerLoadedArtifacts() throws Exception {
- final CommandResult result =
- mTestInfo.getDevice().executeShellV2Command("pidof system_server");
- assertTrue(result.toString(), result.getExitCode() == 0);
- final String systemServerPid = result.getStdout().trim();
+ String systemServerPid = assertCommandSucceeds("pidof system_server");
assertTrue(!systemServerPid.isEmpty());
- assertTrue(
- "There should be exactly one `system_server` process",
+ assertTrue("There should be exactly one `system_server` process",
systemServerPid.matches("\\d+"));
// system_server artifacts are in the APEX data dalvik cache and names all contain
// the word "@classes". Look for mapped files that match this pattern in the proc map for
// system_server.
- final String grepPattern = ART_APEX_DALVIK_CACHE_DIRNAME + ".*@classes";
+ String grepPattern = ART_APEX_DALVIK_CACHE_DIRNAME + "/.*@classes";
return getMappedArtifacts(systemServerPid, grepPattern);
}
- public void verifyZygoteLoadedArtifacts(String zygoteName, Set<String> mappedArtifacts,
- String bootImageStem) throws Exception {
- assertTrue("Expect 3 bootclasspath artifacts", mappedArtifacts.size() == 3);
-
- String allArtifacts = mappedArtifacts.stream().collect(Collectors.joining(","));
+ public Set<String> getZygoteExpectedArtifacts(String bootImageStem, String isa)
+ throws Exception {
+ Set<String> artifacts = new HashSet<>();
for (String extension : 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);
+ artifacts.add(String.format(
+ "%s/%s/%s%s", ART_APEX_DALVIK_CACHE_DIRNAME, isa, bootImageStem, extension));
}
+ return artifacts;
}
- // Verifies that boot image files with the given stem are loaded by Zygote for each instruction
- // set. Returns the verified files.
- public HashSet<String> verifyZygotesLoadedArtifacts(String bootImageStem) 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;
- HashSet<String> verifiedArtifacts = new HashSet<>();
- for (String zygoteName : ZYGOTE_NAMES) {
- final Optional<Set<String>> mappedArtifacts = getZygoteLoadedArtifacts(zygoteName);
- if (!mappedArtifacts.isPresent()) {
- continue;
- }
- verifyZygoteLoadedArtifacts(zygoteName, mappedArtifacts.get(), bootImageStem);
- zygoteCount += 1;
- verifiedArtifacts.addAll(mappedArtifacts.get());
+ public Set<String> getZygotesExpectedArtifacts(String bootImageStem) throws Exception {
+ Set<String> artifacts = new HashSet<>();
+ for (String isa : getZygoteNamesAndIsas().values()) {
+ artifacts.addAll(getZygoteExpectedArtifacts(bootImageStem, isa));
}
- assertTrue("No zygote processes found", zygoteCount > 0);
- return verifiedArtifacts;
+ return artifacts;
}
- public void verifySystemServerLoadedArtifacts() throws Exception {
+ public Set<String> getZygotesExpectedArtifacts() throws Exception {
+ return getZygotesExpectedArtifacts("boot");
+ }
+
+ public Set<String> getSystemServerExpectedArtifacts() 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);
+ String[] allSystemServerJars =
+ Stream.concat(Arrays.stream(classpathElements), Arrays.stream(standaloneJars))
+ .toArray(String[] ::new);
+ String isa = getSystemServerIsa();
- final Set<String> mappedArtifacts = getSystemServerLoadedArtifacts();
- assertTrue(
- "No mapped artifacts under " + ART_APEX_DALVIK_CACHE_DIRNAME,
- mappedArtifacts.size() > 0);
- final String isa = getSystemServerIsa(mappedArtifacts.iterator().next());
- final String isaCacheDirectory = String.format("%s/%s", 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 : APP_ARTIFACT_EXTENSIONS) {
- final String fullArtifactPath =
- String.format("%s/%s@classes%s", isaCacheDirectory, escapedPath, extension);
- assertTrue("Missing " + fullArtifactPath, mappedArtifacts.contains(fullArtifactPath));
- }
+ Set<String> artifacts = new HashSet<>();
+ for (String jar : allSystemServerJars) {
+ artifacts.addAll(getApexDataDalvikCacheFilenames(jar, isa));
}
- for (String mappedArtifact : mappedArtifacts) {
- // Check the mapped artifact has a .art, .odex or .vdex extension.
- final boolean knownArtifactKind =
- APP_ARTIFACT_EXTENSIONS.stream().anyMatch(e -> mappedArtifact.endsWith(e));
- assertTrue("Unknown artifact kind: " + mappedArtifact, knownArtifactKind);
+ return artifacts;
+ }
+
+ // Verifies that boot image files with the given stem are loaded by Zygote for each instruction
+ // set.
+ public void verifyZygotesLoadedArtifacts(String bootImageStem) throws Exception {
+ for (var entry : getZygoteNamesAndIsas().entrySet()) {
+ assertThat(getZygoteLoadedArtifacts(entry.getKey()))
+ .containsAtLeastElementsIn(
+ getZygoteExpectedArtifacts(bootImageStem, entry.getValue()));
}
}
+ public void verifySystemServerLoadedArtifacts() throws Exception {
+ assertThat(getSystemServerLoadedArtifacts())
+ .containsAtLeastElementsIn(getSystemServerExpectedArtifacts());
+ }
+
public boolean haveCompilationLog() throws Exception {
CommandResult result =
mTestInfo.getDevice().executeShellV2Command("stat " + ODREFRESH_COMPILATION_LOG);
@@ -253,7 +234,7 @@
// store default value and increase time-out for reboot
int rebootTimeout = options.getRebootTimeout();
long onlineTimeout = options.getOnlineTimeout();
- options.setRebootTimeout((int)BOOT_COMPLETE_TIMEOUT.toMillis());
+ options.setRebootTimeout((int) BOOT_COMPLETE_TIMEOUT.toMillis());
options.setOnlineTimeout(BOOT_COMPLETE_TIMEOUT.toMillis());
mTestInfo.getDevice().setOptions(options);
@@ -273,9 +254,10 @@
// `waitForBootComplete` relies on `dev.bootcomplete`.
mTestInfo.getDevice().executeShellCommand("setprop dev.bootcomplete 0");
mTestInfo.getDevice().executeShellCommand("setprop ctl.restart zygote");
- boolean success = mTestInfo.getDevice()
- .waitForBootComplete(RESTART_ZYGOTE_COMPLETE_TIMEOUT.toMillis());
- assertWithMessage("Zygote didn't start in %s", BOOT_COMPLETE_TIMEOUT).that(success)
+ boolean success = mTestInfo.getDevice().waitForBootComplete(
+ RESTART_ZYGOTE_COMPLETE_TIMEOUT.toMillis());
+ assertWithMessage("Zygote didn't start in %s", BOOT_COMPLETE_TIMEOUT)
+ .that(success)
.isTrue();
}
@@ -303,16 +285,45 @@
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 static String getInstructionSet(String abi) {
+ String instructionSet = ABI_TO_INSTRUCTION_SET_MAP.get(abi);
+ assertThat(instructionSet).isNotNull();
+ return instructionSet;
+ }
+
+ public Map<String, String> getZygoteNamesAndIsas() throws Exception {
+ Map<String, String> namesAndIsas = new HashMap<>();
+ String abiList64 = mTestInfo.getDevice().getProperty("ro.product.cpu.abilist64");
+ if (abiList64 != null && !abiList64.isEmpty()) {
+ namesAndIsas.put(ZYGOTE_64_NAME, getInstructionSet(abiList64.split(",")[0]));
+ }
+ String abiList32 = mTestInfo.getDevice().getProperty("ro.product.cpu.abilist32");
+ if (abiList32 != null && !abiList32.isEmpty()) {
+ namesAndIsas.put(ZYGOTE_32_NAME, getInstructionSet(abiList32.split(",")[0]));
+ }
+ return namesAndIsas;
+ }
+
+ public String getSystemServerIsa() throws Exception {
+ return getInstructionSet(
+ mTestInfo.getDevice().getProperty("ro.product.cpu.abilist").split(",")[0]);
+ }
+
+ // Keep in sync with `GetApexDataDalvikCacheFilename` in art/libartbase/base/file_utils.cc.
+ public static Set<String> getApexDataDalvikCacheFilenames(String dexLocation, String isa)
+ throws Exception {
+ Set<String> filenames = new HashSet<>();
+ String escapedPath = dexLocation.substring(1).replace('/', '@');
+ for (String extension : APP_ARTIFACT_EXTENSIONS) {
+ filenames.add(String.format("%s/%s/%s@classes%s", ART_APEX_DALVIK_CACHE_DIRNAME, isa,
+ escapedPath, extension));
+ }
+ return filenames;
}
private long parseFormattedDateTime(String dateTimeStr) throws Exception {
- DateTimeFormatter formatter = DateTimeFormatter.ofPattern(
- "yyyy-MM-dd HH:mm:ss.nnnnnnnnn Z");
+ DateTimeFormatter formatter =
+ DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.nnnnnnnnn Z");
ZonedDateTime zonedDateTime = ZonedDateTime.parse(dateTimeStr, formatter);
return zonedDateTime.toInstant().toEpochMilli();
}
@@ -380,4 +391,41 @@
}
return file;
}
+
+ public void assertModifiedAfter(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, Reference time: %d",
+ artifact, modifiedTime, timeMs),
+ modifiedTime > timeMs);
+ }
+ }
+
+ public void assertNotModifiedAfter(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, Reference time: %d",
+ artifact, modifiedTime, timeMs),
+ modifiedTime < timeMs);
+ }
+ }
+
+ public static String replaceExtension(String filename, String extension) throws Exception {
+ int index = filename.lastIndexOf(".");
+ assertTrue("Extension not found in filename: " + filename, index != -1);
+ return filename.substring(0, index) + extension;
+ }
+
+ public void runOdrefresh() throws Exception {
+ runOdrefresh("" /* extraArgs */);
+ }
+
+ public void runOdrefresh(String extraArgs) throws Exception {
+ mTestInfo.getDevice().executeShellV2Command(ODREFRESH_BIN + " --check");
+ mTestInfo.getDevice().executeShellV2Command(
+ ODREFRESH_BIN + " --partial-compilation --no-refresh " + extraArgs + " --compile");
+ }
}