0. Vorwort
GTS ist beim Testen des Falls armeabi-v7a GtsMemoryHostTestCases auf die folgende Ausnahme gestoßen. Dieser Artikel fasst sie zusammen.
com.google.android.memory.gts.AllAppsMemoryHostTest#testPeakPssOfAllApps
1. Fehlerprotokoll
09-14 10:16:34 I/TestFailureListener: FailureListener.testFailed com.google.android.memory.gts.AllAppsMemoryHostTest#testPeakPssOfAllApps false
09-14 10:16:34 D/PrettyTestEventLogger:
==================== com.google.android.memory.gts.AllAppsMemoryHostTest#testPeakPssOfAllApps ENDED: Thu Sep 14 10:16:34 CST 2023 ====================
09-14 10:16:34 I/ModuleListener: [1/1] d4081bc5 com.android.compatibility.common.tradefed.testtype.JarHostTest com.google.android.memory.gts.AllAppsMemoryHostTest#testPeakPssOfAllApps FAILURE: com.android.tradefed.device.DeviceUnresponsiveException[DEVICE_UNRESPONSIVE|520751|LOST_SYSTEM_UNDER_TEST]: Attempted shell am start -W -S -f 10008000 'com.google.android.apps.mapslite/com.google.maps.lite.twa.MapsLiteTwaLauncherActivity' multiple times on device d4081bc5 without communication success. Aborting.
at com.android.tradefed.device.NativeDevice.performDeviceAction(NativeDevice.java:2577)
at com.android.tradefed.device.NativeDevice.executeShellCommand(NativeDevice.java:902)
at com.android.tradefed.device.NativeDevice.executeShellCommand(NativeDevice.java:959)
at com.google.android.memory.gts.AllAppsMemoryHostTest.testPeakPssOfAllApps(AllAppsMemoryHostTest.java:109)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:61)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:54)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
at com.android.tradefed.testtype.DeviceJUnit4ClassRunner.runChild(DeviceJUnit4ClassRunner.java:111)
at com.android.tradefed.testtype.DeviceJUnit4ClassRunner.runChild(DeviceJUnit4ClassRunner.java:63)
at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
at com.android.tradefed.testtype.DeviceJUnit4ClassRunner.run(DeviceJUnit4ClassRunner.java:147)
at com.android.tradefed.testtype.junit4.ExceptionThrowingRunnerWrapper.run(ExceptionThrowingRunnerWrapper.java:43)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.android.tradefed.testtype.HostTest.runJUnit4Tests(HostTest.java:736)
at com.android.tradefed.testtype.HostTest.runTestClasses(HostTest.java:616)
at com.android.tradefed.testtype.HostTest.run(HostTest.java:564)
at com.android.compatibility.common.tradefed.testtype.JarHostTest.run(JarHostTest.java:56)
at com.android.tradefed.testtype.suite.GranularRetriableTestWrapper.intraModuleRun(GranularRetriableTestWrapper.java:379)
at com.android.tradefed.testtype.suite.GranularRetriableTestWrapper.run(GranularRetriableTestWrapper.java:289)
at com.android.tradefed.testtype.suite.ModuleDefinition.run(ModuleDefinition.java:595)
at com.android.tradefed.testtype.suite.ITestSuite.runSingleModule(ITestSuite.java:951)
at com.android.tradefed.testtype.suite.ITestSuite.run(ITestSuite.java:828)
at com.android.tradefed.invoker.InvocationExecution.runTest(InvocationExecution.java:1359)
at com.android.tradefed.invoker.InvocationExecution.runTests(InvocationExecution.java:1138)
at com.android.tradefed.invoker.TestInvocation.prepareAndRun(TestInvocation.java:626)
at com.android.tradefed.invoker.TestInvocation.performInvocation(TestInvocation.java:278)
at com.android.tradefed.invoker.TestInvocation.invoke(TestInvocation.java:1357)
at com.android.tradefed.command.CommandScheduler$InvocationThread.run(CommandScheduler.java:686)
Caused by: com.android.ddmlib.ShellCommandUnresponsiveException
at com.android.ddmlib.AdbHelper.executeRemoteCommand(AdbHelper.java:731)
at com.android.ddmlib.AdbHelper.executeRemoteCommand(AdbHelper.java:511)
at com.android.ddmlib.internal.DeviceImpl.executeShellCommand(DeviceImpl.java:722)
at com.android.tradefed.device.NativeDevice$2.run(NativeDevice.java:897)
at com.android.tradefed.device.NativeDevice.performDeviceAction(NativeDevice.java:2525)
... 44 more
2. Quellcode
public void testPeakPssOfAllApps() throws Exception {
final int flags = 268468224;
//------------step1
final String[] activities = ActivityQueryHelper.ALL_APPS_QUERY.run(this.getDevice());
Assert.assertTrue("No activities found", activities.length > 0);
final Set<String> exemptedActivities = new HashSet<String>();
for (final ActivityQuery query : ActivityQueryHelper.APPS_BY_CATEGORY) {
exemptedActivities.addAll(Arrays.asList(query.run(this.getDevice())));
}
//------------step2
final Set<String> exemptedPackages = new HashSet<String>();
exemptedPackages.addAll(this.readExemptions("gallery_exemptions"));
exemptedPackages.addAll(this.readExemptions("streaming_music_apps"));
exemptedPackages.addAll(this.readExemptions("streaming_video_apps"));
exemptedPackages.addAll(this.readExemptions("all_apps_memory_exemptions"));
final List<String> activityList = new ArrayList<String>(Arrays.asList(activities));
//------------step3
final Iterator<String> it = activityList.iterator();
while (it.hasNext()) {
final String activity = it.next();
final String packageName = activity.split("/")[0];
if (exemptedPackages.contains(packageName)) {
LogUtil.CLog.d("exempt package " + packageName);
it.remove();
}
else {
if (!exemptedActivities.contains(activity)) {
continue;
}
LogUtil.CLog.d("exempt activity " + activity);
it.remove();
}
}
//------------step4
LogUtil.CLog.d("These apps will be checked: " + String.join(",", activityList));
//------------step5
final long maxPeakPssAllowed = this.calculateMaxAllowedPeakPssUsage("max_memory_all_apps");
final StringBuilder violations = new StringBuilder();
for (final String activity2 : activityList) {
//------------step6
final String packageName2 = activity2.split("/")[0];
this.runPostNotificationPermissionTest("grantRuntimePermission", packageName2);
final String amOutput = this.getDevice().executeShellCommand(this.buildStartActivityCommand(activity2, 268468224));
Assert.assertTrue(activity2 + " failed to start", amOutput.contains("Status: ok"));
TimeUnit.SECONDS.sleep(30L);
if (this.shouldExemptTopActivity(exemptedActivities)) {
continue;
}
//------------step7
final long memoryKb = this.getMemoryUsage(packageName2);
this.stopApplication(packageName2);
if (memoryKb >= maxPeakPssAllowed) {
violations.append(packageName2).append(" ").append(memoryKb).append(",");
}
this.runPostNotificationPermissionTest("revokeRuntimePermission", packageName2);
}
//------------step8
if (violations.length() > 0) {
violations.append(" failed to keep to the max pss of ");
violations.append(maxPeakPssAllowed);
Assert.fail(violations.toString());
}
}
Es gibt eine Menge Quellcode, der vollständig in GtsMemoryHostTestCases.jar gekapselt ist. Hier schauen wir uns nur die Testoberfläche an.
Schritt 1. Finden Sie alle Aktivitäten, die den Anforderungen entsprechen
Verwenden Sie ActivityQueryHelper.ALL_APPS_QUERY, um alle Aktivitäten abzufragen, die die Bedingungen erfüllen:
ActivityQueryHelper.java
ALL_APPS_QUERY = new ActivityQuery().setAction("android.intent.action.MAIN").setCategory("android.intent.category.LAUNCHER");
Erfordert alle Aktivitäten, deren Aktion android.intent.action.MAIN und deren Kategorie android.intent.category.LAUNCHER ist.
Schritt 2. Bestimmen Sie die ausgenommenen Pakete
final Set<String> exemptedPackages = new HashSet<String>();
exemptedPackages.addAll(this.readExemptions("gallery_exemptions"));
exemptedPackages.addAll(this.readExemptions("streaming_music_apps"));
exemptedPackages.addAll(this.readExemptions("streaming_video_apps"));
exemptedPackages.addAll(this.readExemptions("all_apps_memory_exemptions"));
Diese ausgenommenen Pakete sind in der Datei GtsMemoryHostTestCases.dynamic definiert .
Schritt 3. Umfrage zur Bestimmung der endgültigen Aktivität
Ausgenommene Anträge werden im Protokoll ausgedruckt:
09-14 10:02:54 D/AllAppsMemoryHostTest: exempt activity com.android.chrome/com.google.android.apps.chrome.Main
09-14 10:02:54 D/AllAppsMemoryHostTest: exempt activity com.google.android.apps.photosgo/.home.HomeActivity
09-14 10:02:54 D/AllAppsMemoryHostTest: exempt package com.google.android.youtube
09-14 10:02:54 D/AllAppsMemoryHostTest: exempt activity org.codeaurora.dialer/com.android.dialer.main.impl.MainActivity
09-14 10:02:54 D/AllAppsMemoryHostTest: exempt package com.google.android.apps.nbu.files
Schritt 4. Bestimmen Sie die Aktivität, die abschließend überprüft werden kann
Nach Schritt 3 wird die Aktivität, die letztendlich überprüft werden muss, im Protokoll ausgedruckt:
09-14 10:02:54 D/AllAppsMemoryHostTest: These apps will be checked: com.android.mms/.ui.ConversationList,
com.android.settings/.Settings,
com.android.soundrecorder/.SoundRecorder,
com.android.vending/.AssetBrowserActivity,
com.google.android.apps.assistant/.go.MainActivity,
com.google.android.apps.messaging/.ui.ConversationListActivity,
com.google.android.apps.tachyon/.MainActivity,
com.google.android.calculator/com.android.calculator2.Calculator,
com.google.android.calendar/com.android.calendar.AllInOneActivity,
com.google.android.contacts/com.android.contacts.activities.PeopleActivity,
com.google.android.deskclock/com.android.deskclock.DeskClock,
com.google.android.dialer/.extensions.GoogleDialtactsActivity,
org.codeaurora.snapcam/com.android.camera.CameraLauncher,
com.caf.fmradio/.FMRadio,
com.google.android.apps.mapslite/com.google.maps.lite.twa.MapsLiteTwaLauncherActivity,
com.google.android.apps.searchlite/.ui.SearchActivity
Schritt 5. Bestimmen Sie die Layoutgröße des Geräts und bestimmen Sie den PeakPss
Die Layoutgröße des Geräts wurde im Artikel „Detaillierte Erläuterung des TestPersistentProcessMemory-Fehlers in GTS“ analysiert. Weitere Informationen finden Sie in Abschnitt 2.1 .
Hier wird PeakPss schließlich anhand der Layoutgröße bestimmt. Dieser Attributwert ist in der Datei GtsMemoryHostTestCases.dynamic definiert:
...
<entry key="max_memory_all_apps_2gb_hd">
<value>153600</value>
</entry>
...
Schritt 6. Fragen Sie die zu überprüfenden Aktivitäten ab, ermitteln Sie den Paketnamen und beantragen Sie die Berechtigung android.permission.POST_NOTIFICATIONS .
Schritt 7. Bestimmen Sie den Prozessspeicher und deaktivieren Sie die Benachrichtigungsberechtigungen
Bestimmen Sie den Prozessspeicher mit dem Befehl dumpsys -t 30 meminfo --package packageName und bestimmen Sie den Speicher weiterhin mit der Pattern-Klasse:
final List<String> usages = new ArrayList<String>();
final Matcher matcher = Pattern.compile("TOTAL\\s+([\\d]+)").matcher(output);
while (matcher.find()) {
usages.add(matcher.group(1));
}
Assert.assertFalse("Could not get meminfo total for " + packageName, usages.isEmpty());
return usages.stream().mapToLong((ToLongFunction<? super Object>)Long::valueOf).sum();
Schritt 8. Die Statistiken überschreiten die maximale PSS
Wenn der Speicher eines Prozesses PeakPss überschreitet, wird er gedruckt und angezeigt.
3. Lösung
Das Fehlerprotokoll in diesem Artikel ist aus dem Hostprotokoll relativ klar:
09-14 10:12:33 W/NativeDevice: Command: 'shell am start -W -S -f 10008000 'com.google.android.apps.mapslite/com.google.maps.lite.twa.MapsLiteTwaLauncherActivity'' on 'd4081bc5' went over its timeout for outputing a response.
09-14 10:14:34 W/NativeDevice: Command: 'shell am start -W -S -f 10008000 'com.google.android.apps.mapslite/com.google.maps.lite.twa.MapsLiteTwaLauncherActivity'' on 'd4081bc5' went over its timeout for outputing a response.
09-14 10:16:34 W/NativeDevice: Command: 'shell am start -W -S -f 10008000 'com.google.android.apps.mapslite/com.google.maps.lite.twa.MapsLiteTwaLauncherActivity'' on 'd4081bc5' went over its timeout for outputing a response.
09-14 10:16:34 I/TestFailureListener: FailureListener.testFailed com.google.android.memory.gts.AllAppsMemoryHostTest#testPeakPssOfAllApps false
...
09-14 10:16:34 W/GranularRetriableTestWrapper: com.android.tradefed.device.DeviceUnresponsiveException[DEVICE_UNRESPONSIVE|520751|LOST_SYSTEM_UNDER_TEST]: Attempted shell am start -W -S -f 10008000 'com.google.android.apps.mapslite/com.google.maps.lite.twa.MapsLiteTwaLauncherActivity' multiple times on device d4081bc5 without communication success. Aborting.
Der Hauptgrund dafür ist, dass der Start dieser Aktivität nicht den Status „Status: ok“ zurückgibt
Darüber hinaus wird, wie im Artikel „testPersistentProcessMemory failed“ , dieser Fall übersprungen, wenn es sich um ein Nicht-GO-Gerät handelt, was bedeutet, dass ein solcher fehlgeschlagener Fall nur auf der GO-Plattform angezeigt wird:
09-22 14:21:31 I/ModuleListener: [1/1] cb080378 com.android.compatibility.common.tradefed.testtype.JarHostTest com.google.android.memory.gts.AllAppsMemoryHostTest#testPeakPssOfAllApps ASSUMPTION_FAILURE: org.junit.AssumptionViolatedException: Skipping AllAppsMemoryHostTest on non-Go device
at org.junit.Assume.assumeTrue(Assume.java:68)
at com.google.android.memory.gts.MemoryHostTestBase.checkGoDevice(MemoryHostTestBase.java:89)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:61)
at org.junit.internal.runners.statements.RunBefores.invokeMethod(RunBefores.java:33)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:54)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
at com.android.tradefed.testtype.DeviceJUnit4ClassRunner.runChild(DeviceJUnit4ClassRunner.java:111)
at com.android.tradefed.testtype.DeviceJUnit4ClassRunner.runChild(DeviceJUnit4ClassRunner.java:63)
at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
at com.android.tradefed.testtype.DeviceJUnit4ClassRunner.run(DeviceJUnit4ClassRunner.java:147)
at com.android.tradefed.testtype.junit4.ExceptionThrowingRunnerWrapper.run(ExceptionThrowingRunnerWrapper.java:43)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.android.tradefed.testtype.HostTest.runJUnit4Tests(HostTest.java:736)
at com.android.tradefed.testtype.HostTest.runTestClasses(HostTest.java:616)
at com.android.tradefed.testtype.HostTest.run(HostTest.java:564)
at com.android.compatibility.common.tradefed.testtype.JarHostTest.run(JarHostTest.java:56)
at com.android.tradefed.testtype.suite.GranularRetriableTestWrapper.intraModuleRun(GranularRetriableTestWrapper.java:379)
at com.android.tradefed.testtype.suite.GranularRetriableTestWrapper.run(GranularRetriableTestWrapper.java:289)
at com.android.tradefed.testtype.suite.ModuleDefinition.run(ModuleDefinition.java:595)
at com.android.tradefed.testtype.suite.ITestSuite.runSingleModule(ITestSuite.java:951)
at com.android.tradefed.testtype.suite.ITestSuite.run(ITestSuite.java:828)
at com.android.tradefed.invoker.InvocationExecution.runTest(InvocationExecution.java:1359)
at com.android.tradefed.invoker.InvocationExecution.runTests(InvocationExecution.java:1138)
at com.android.tradefed.invoker.TestInvocation.prepareAndRun(TestInvocation.java:626)
at com.android.tradefed.invoker.TestInvocation.performInvocation(TestInvocation.java:278)
at com.android.tradefed.invoker.TestInvocation.invoke(TestInvocation.java:1357)
at com.android.tradefed.command.CommandScheduler$InvocationThread.run(CommandScheduler.java:686)