odrefresh: add test for samegrade ART APEX install
Adds a test that a samegrade ART APEX installation triggers
recompilation of AOT artifacts.
The test exposed situation where the first log entry is incorrectly
logged as zero which is also fixed here.
Bug: 192647837
Test: atest odsign_e2e_tests
Test: atest art_odrefresh_tests
Change-Id: Iefb0fbbca119ed3e47bc17caa2ef8467b241b26c
diff --git a/odrefresh/odrefresh.cc b/odrefresh/odrefresh.cc
index 7ecbe06..6f8fbb8 100644
--- a/odrefresh/odrefresh.cc
+++ b/odrefresh/odrefresh.cc
@@ -501,6 +501,21 @@
return cleanup_return(ExitCode::kCompilationRequired);
}
+ // Generate current module info for the current ART APEX.
+ const auto current_info = GenerateArtModuleInfo();
+ if (!current_info.has_value()) {
+ // This should never happen, further up-to-date checks are not possible if it does.
+ LOG(ERROR) << "Failed to generate cache provenance.";
+ metrics.SetTrigger(OdrMetrics::Trigger::kUnknown);
+ return cleanup_return(ExitCode::kCompilationRequired);
+ }
+
+ // Record ART APEX version for metrics reporting.
+ metrics.SetArtApexVersion(current_info->getVersionCode());
+
+ // Record ART APEX last update milliseconds (used in compilation log).
+ metrics.SetArtApexLastUpdateMillis(current_info->getLastUpdateMillis());
+
if (apex_info->getIsFactory()) {
// Remove any artifacts on /data as they are not necessary and no compilation is necessary.
LOG(INFO) << "Factory APEX mounted.";
@@ -524,21 +539,6 @@
return cleanup_return(ExitCode::kCompilationRequired);
}
- // Generate current module info for the current ART APEX.
- const auto current_info = GenerateArtModuleInfo();
- if (!current_info.has_value()) {
- // This should never happen, further up-to-date checks are not possible if it does.
- LOG(ERROR) << "Failed to generate cache provenance.";
- metrics.SetTrigger(OdrMetrics::Trigger::kUnknown);
- return cleanup_return(ExitCode::kCompilationRequired);
- }
-
- // Record ART APEX version for metrics reporting.
- metrics.SetArtApexVersion(current_info->getVersionCode());
-
- // Record ART APEX last update milliseconds (used in compilation log).
- metrics.SetArtApexLastUpdateMillis(current_info->getLastUpdateMillis());
-
// Check whether the current cache ART module info differs from the current ART module info.
// Always check APEX version.
const auto cached_info = cache_info->getFirstArtModuleInfo();
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 e44bc80..5245698 100644
--- a/test/odsign/test-src/com/android/tests/odsign/OnDeviceSigningHostTest.java
+++ b/test/odsign/test-src/com/android/tests/odsign/OnDeviceSigningHostTest.java
@@ -228,6 +228,62 @@
verifySystemServerLoadedArtifacts();
}
+ @Test
+ public void verifyGeneratedArtifactsLoadedForSamegradeUpdate() throws Exception {
+ // Install the same APEX effecting a samegrade update. The setUp method has installed it
+ // before us.
+ mInstallUtils.installApexes(APEX_FILENAME);
+ reboot();
+
+ final boolean adbEnabled = getDevice().enableAdbRoot();
+ assertTrue("ADB root failed and required to get odrefresh compilation log", adbEnabled);
+
+ // Check that odrefresh logged a compilation attempt due to samegrade ART APEX install.
+ String[] logLines = getDevice().pullFileContents(ODREFRESH_COMPILATION_LOG).split("\n");
+ assertTrue(
+ "Expected 3 lines in " + ODREFRESH_COMPILATION_LOG + ", found " + logLines.length,
+ logLines.length == 3);
+
+ // Check that the compilation log entries are reasonable, ie times move forward.
+ // The first line of the log is the log format version number.
+ String[] firstUpdateEntry = logLines[1].split(" ");
+ String[] secondUpdateEntry = logLines[2].split(" ");
+ final int LOG_ENTRY_FIELDS = 5;
+ assertTrue(
+ "Unexpected number of fields: " + firstUpdateEntry.length + " != " +
+ LOG_ENTRY_FIELDS,
+ firstUpdateEntry.length == LOG_ENTRY_FIELDS);
+ assertTrue(firstUpdateEntry.length == secondUpdateEntry.length);
+
+ final int LAST_UPDATE_MILLIS_INDEX = 1;
+ final int COMPILATION_TIME_INDEX = 3;
+ for (int i = 0; i < firstUpdateEntry.length; ++i) {
+ final long firstField = Long.parseLong(firstUpdateEntry[i]);
+ final long secondField = Long.parseLong(secondUpdateEntry[i]);
+ if (i == LAST_UPDATE_MILLIS_INDEX) {
+ // The second APEX lastUpdateMillis should be after the first.
+ assertTrue(
+ "Last update time same or wrong relation" +
+ firstField + " >= " + secondField,
+ firstField < secondField);
+ } else if (i == COMPILATION_TIME_INDEX) {
+ // Second compilation time should be after the first compilation time.
+ assertTrue(
+ "Compilation time same or wrong relation" +
+ firstField + " >= " + secondField,
+ firstField < secondField);
+ } else {
+ // The remaining fields should be the same, ie trigger for compilation, status, etc
+ assertTrue(
+ "Compilation entries differ for position " + i + ": " +
+ firstField + " != " + secondField,
+ firstField == secondField);
+ }
+ }
+
+ verifyGeneratedArtifactsLoaded();
+ }
+
private boolean haveCompilationLog() throws Exception {
CommandResult result =
getDevice().executeShellV2Command("stat " + ODREFRESH_COMPILATION_LOG);