summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Yurii Zubrytskyi <zyy@google.com> 2024-08-30 16:18:08 -0700
committer Yurii Zubrytskyi <zyy@google.com> 2024-09-05 15:35:38 +0000
commitb02e968c32df215a5150b8fd9a6f5359b8b3035f (patch)
tree7b3f29811a432870dab45592f88a7a3527030fbb
parentebb6e2e6f311bde51c9943317e2f972b39712431 (diff)
[res] Fix OverlayManagerPerfTest
The test was implemented in a really flaky way: - It didn't wait for the overlay disablement propagation correctly, making the setEnabled() tests measure the phase of the Moon. Now the test is more reliable, but unfortunately it also depends on the broadcast delivery timings and activity restarts and redraws, so I doubt there's a way to make it that much more precise. - It installed some APKs that Play Protect doesn't see often and brings up a popup asking to upload them for scanning, and the popup default timeout is 1hr *per APK*. Now the timeout is 10s and the installation happens in parallel, making the whole wait to be about 10-20s Test: atest OverlayManagerPerfTest Flag: EXEMPT tests-only change Change-Id: Iac9f85866cc0dbdc1b567ac599a92b2fd8998932
-rw-r--r--apct-tests/perftests/core/AndroidTest.xml11
-rw-r--r--apct-tests/perftests/core/src/android/app/OverlayManagerPerfTest.java129
2 files changed, 87 insertions, 53 deletions
diff --git a/apct-tests/perftests/core/AndroidTest.xml b/apct-tests/perftests/core/AndroidTest.xml
index 86f41e1f496c..c2d54707d9f2 100644
--- a/apct-tests/perftests/core/AndroidTest.xml
+++ b/apct-tests/perftests/core/AndroidTest.xml
@@ -17,6 +17,17 @@
<option name="test-suite-tag" value="apct" />
<option name="test-suite-tag" value="apct-metric-instrumentation" />
+ // Deal with Play Protect blocking apk installations.
+ // The first setting disables the verification, the second one lowers the timeout from
+ // 1hr to 10s, the third one resets the value after the test is complete, and the final
+ // setting skips the device reboot after modifying the settings.
+ <target_preparer class="com.android.tradefed.targetprep.DeviceSetup">
+ <option name="set-global-setting" key="verifier_verify_adb_installs" value="0" />
+ <option name="set-global-setting" key="verifier_engprod" value="1" />
+ <option name="restore-settings" value="true" />
+ <option name="force-skip-system-props" value="true" />
+ </target_preparer>
+
<target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
<target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
<option name="push-file" key="trace_config_detailed.textproto" value="/data/misc/perfetto-traces/trace_config.textproto" />
diff --git a/apct-tests/perftests/core/src/android/app/OverlayManagerPerfTest.java b/apct-tests/perftests/core/src/android/app/OverlayManagerPerfTest.java
index fcb13a8d51f1..a12121fd13f7 100644
--- a/apct-tests/perftests/core/src/android/app/OverlayManagerPerfTest.java
+++ b/apct-tests/perftests/core/src/android/app/OverlayManagerPerfTest.java
@@ -37,9 +37,13 @@ import org.junit.Rule;
import org.junit.Test;
import java.util.ArrayList;
-import java.util.concurrent.Executor;
-import java.util.concurrent.FutureTask;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.concurrent.Callable;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
+import java.util.stream.Stream;
/**
* Benchmarks for {@link android.content.om.OverlayManager}.
@@ -49,7 +53,6 @@ public class OverlayManagerPerfTest {
private static final int OVERLAY_PKG_COUNT = 10;
private static Context sContext;
private static OverlayManager sOverlayManager;
- private static Executor sExecutor;
private static ArrayList<TestPackageInstaller.InstalledPackage> sSmallOverlays =
new ArrayList<>();
private static ArrayList<TestPackageInstaller.InstalledPackage> sLargeOverlays =
@@ -58,18 +61,45 @@ public class OverlayManagerPerfTest {
@Rule
public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+ // Uncheck the checked exceptions in a callable for convenient stream usage.
+ // Any exception will fail the test anyway.
+ private static <T> T uncheck(Callable<T> c) {
+ try {
+ return c.call();
+ } catch (RuntimeException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
@BeforeClass
public static void classSetUp() throws Exception {
sContext = InstrumentationRegistry.getTargetContext();
sOverlayManager = new OverlayManager(sContext);
- sExecutor = (command) -> new Thread(command).start();
- // Install all of the test overlays.
- TestPackageInstaller installer = new TestPackageInstaller(sContext);
+ // Install all of the test overlays. Play Protect likes to block these for 10 sec each
+ // so let's install them in parallel to speed up the wait.
+ final var installer = new TestPackageInstaller(sContext);
+ final var es = Executors.newFixedThreadPool(2 * OVERLAY_PKG_COUNT);
+ final var smallFutures = new ArrayList<Future<TestPackageInstaller.InstalledPackage>>(
+ OVERLAY_PKG_COUNT);
+ final var largeFutures = new ArrayList<Future<TestPackageInstaller.InstalledPackage>>(
+ OVERLAY_PKG_COUNT);
for (int i = 0; i < OVERLAY_PKG_COUNT; i++) {
- sSmallOverlays.add(installer.installPackage("Overlay" + i +".apk"));
- sLargeOverlays.add(installer.installPackage("LargeOverlay" + i +".apk"));
+ final var index = i;
+ smallFutures.add(es.submit(() -> installer.installPackage("Overlay" + index + ".apk")));
+ largeFutures.add(
+ es.submit(() -> installer.installPackage("LargeOverlay" + index + ".apk")));
}
+ es.shutdown();
+ assertTrue(es.awaitTermination(15 * 2 * OVERLAY_PKG_COUNT, TimeUnit.SECONDS));
+ sSmallOverlays.addAll(smallFutures.stream().map(f -> uncheck(f::get)).sorted(
+ Comparator.comparing(
+ TestPackageInstaller.InstalledPackage::getPackageName)).toList());
+ sLargeOverlays.addAll(largeFutures.stream().map(f -> uncheck(f::get)).sorted(
+ Comparator.comparing(
+ TestPackageInstaller.InstalledPackage::getPackageName)).toList());
}
@AfterClass
@@ -77,7 +107,6 @@ public class OverlayManagerPerfTest {
for (TestPackageInstaller.InstalledPackage overlay : sSmallOverlays) {
overlay.uninstall();
}
-
for (TestPackageInstaller.InstalledPackage overlay : sLargeOverlays) {
overlay.uninstall();
}
@@ -86,37 +115,39 @@ public class OverlayManagerPerfTest {
@After
public void tearDown() throws Exception {
// Disable all test overlays after each test.
- for (TestPackageInstaller.InstalledPackage overlay : sSmallOverlays) {
- assertSetEnabled(sContext, overlay.getPackageName(), false);
- }
-
- for (TestPackageInstaller.InstalledPackage overlay : sLargeOverlays) {
- assertSetEnabled(sContext, overlay.getPackageName(), false);
- }
+ assertSetEnabled(false, sContext,
+ Stream.concat(sSmallOverlays.stream(), sLargeOverlays.stream()).map(
+ p -> p.getPackageName()));
}
/**
- * Enables the overlay and waits for the APK path change sto be propagated to the context
+ * Enables the overlay and waits for the APK path changes to be propagated to the context
* AssetManager.
*/
- private void assertSetEnabled(Context context, String overlayPackage, boolean eanabled)
- throws Exception {
- sOverlayManager.setEnabled(overlayPackage, true, UserHandle.SYSTEM);
+ private void assertSetEnabled(boolean enabled, Context context, Stream<String> packagesStream) {
+ final var overlayPackages = packagesStream.toList();
+ overlayPackages.forEach(
+ name -> sOverlayManager.setEnabled(name, enabled, UserHandle.SYSTEM));
// Wait for the overlay changes to propagate
- FutureTask<Boolean> task = new FutureTask<>(() -> {
- while (true) {
- for (String path : context.getAssets().getApkPaths()) {
- if (eanabled == path.contains(overlayPackage)) {
- return true;
- }
- }
+ final var endTime = System.nanoTime() + TimeUnit.SECONDS.toNanos(20);
+ final var expectedPackagesFound = enabled ? overlayPackages.size() : 0;
+ boolean assetsUpdated = false;
+ do {
+ final var packagesFound = Arrays.stream(context.getAssets().getApkPaths()).filter(
+ assetPath -> overlayPackages.stream().anyMatch(assetPath::contains)).count();
+ if (packagesFound == expectedPackagesFound) {
+ assetsUpdated = true;
+ break;
}
- });
+ Thread.yield();
+ } while (System.nanoTime() < endTime);
+ assertTrue("Failed to set state to " + enabled + " for overlays " + overlayPackages,
+ assetsUpdated);
+ }
- sExecutor.execute(task);
- assertTrue("Failed to load overlay " + overlayPackage,
- task.get(20, TimeUnit.SECONDS));
+ private void assertSetEnabled(boolean enabled, Context context, String overlayPackage) {
+ assertSetEnabled(enabled, context, Stream.of(overlayPackage));
}
@Test
@@ -124,11 +155,11 @@ public class OverlayManagerPerfTest {
String packageName = sSmallOverlays.get(0).getPackageName();
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
- assertSetEnabled(sContext, packageName, true);
+ assertSetEnabled(true, sContext, packageName);
// Disable the overlay for the next iteration of the test
state.pauseTiming();
- assertSetEnabled(sContext, packageName, false);
+ assertSetEnabled(false, sContext, packageName);
state.resumeTiming();
}
}
@@ -138,11 +169,11 @@ public class OverlayManagerPerfTest {
String packageName = sSmallOverlays.get(0).getPackageName();
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
- assertSetEnabled(sContext, packageName, true);
+ assertSetEnabled(true, sContext, packageName);
// Disable the overlay and remove the idmap for the next iteration of the test
state.pauseTiming();
- assertSetEnabled(sContext, packageName, false);
+ assertSetEnabled(false, sContext, packageName);
sOverlayManager.invalidateCachesForOverlay(packageName, UserHandle.SYSTEM);
state.resumeTiming();
}
@@ -153,11 +184,11 @@ public class OverlayManagerPerfTest {
String packageName = sLargeOverlays.get(0).getPackageName();
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
- assertSetEnabled(sContext, packageName, true);
+ assertSetEnabled(true, sContext, packageName);
// Disable the overlay and remove the idmap for the next iteration of the test
state.pauseTiming();
- assertSetEnabled(sContext, packageName, false);
+ assertSetEnabled(false, sContext, packageName);
sOverlayManager.invalidateCachesForOverlay(packageName, UserHandle.SYSTEM);
state.resumeTiming();
}
@@ -169,30 +200,28 @@ public class OverlayManagerPerfTest {
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
state.pauseTiming();
- assertSetEnabled(sContext, packageName, true);
+ assertSetEnabled(true, sContext, packageName);
state.resumeTiming();
- assertSetEnabled(sContext, packageName, false);
+ assertSetEnabled(false, sContext, packageName);
}
}
@Test
public void getStringOneSmallOverlay() throws Exception {
String packageName = sSmallOverlays.get(0).getPackageName();
- assertSetEnabled(sContext, packageName, true);
+ assertSetEnabled(true, sContext, packageName);
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
sContext.getString(R.string.short_text);
}
-
- assertSetEnabled(sContext, packageName, false);
}
@Test
public void getStringOneLargeOverlay() throws Exception {
String packageName = sLargeOverlays.get(0).getPackageName();
- assertSetEnabled(sContext, packageName, true);
+ assertSetEnabled(true, sContext, packageName);
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
@@ -200,16 +229,12 @@ public class OverlayManagerPerfTest {
sContext.getString(resId);
}
}
-
- assertSetEnabled(sContext, packageName, false);
}
@Test
public void getStringTenOverlays() throws Exception {
- // Enable all test overlays
- for (TestPackageInstaller.InstalledPackage overlay : sSmallOverlays) {
- assertSetEnabled(sContext, overlay.getPackageName(), true);
- }
+ // Enable all small test overlays
+ assertSetEnabled(true, sContext, sSmallOverlays.stream().map(p -> p.getPackageName()));
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
@@ -219,10 +244,8 @@ public class OverlayManagerPerfTest {
@Test
public void getStringLargeTenOverlays() throws Exception {
- // Enable all test overlays
- for (TestPackageInstaller.InstalledPackage overlay : sLargeOverlays) {
- assertSetEnabled(sContext, overlay.getPackageName(), true);
- }
+ // Enable all large test overlays
+ assertSetEnabled(true, sContext, sLargeOverlays.stream().map(p -> p.getPackageName()));
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {