• GTS 中testPeakPssOfAllApps fail 详解


    0. 前言

    GTS 在测试 case armeabi-v7a GtsMemoryHostTestCases 的时候出现下面异常,本文总结一下。

    com.google.android.memory.gts.AllAppsMemoryHostTest#testPeakPssOfAllApps

    1. error log

    1. 09-14 10:16:34 I/TestFailureListener: FailureListener.testFailed com.google.android.memory.gts.AllAppsMemoryHostTest#testPeakPssOfAllApps false
    2. 09-14 10:16:34 D/PrettyTestEventLogger:
    3. ==================== com.google.android.memory.gts.AllAppsMemoryHostTest#testPeakPssOfAllApps ENDED: Thu Sep 14 10:16:34 CST 2023 ====================
    4. 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.
    5. at com.android.tradefed.device.NativeDevice.performDeviceAction(NativeDevice.java:2577)
    6. at com.android.tradefed.device.NativeDevice.executeShellCommand(NativeDevice.java:902)
    7. at com.android.tradefed.device.NativeDevice.executeShellCommand(NativeDevice.java:959)
    8. at com.google.android.memory.gts.AllAppsMemoryHostTest.testPeakPssOfAllApps(AllAppsMemoryHostTest.java:109)
    9. at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    10. at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    11. at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    12. at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    13. at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
    14. at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    15. at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:61)
    16. at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    17. at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    18. at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
    19. at org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:54)
    20. at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
    21. at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
    22. at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
    23. at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
    24. at com.android.tradefed.testtype.DeviceJUnit4ClassRunner.runChild(DeviceJUnit4ClassRunner.java:111)
    25. at com.android.tradefed.testtype.DeviceJUnit4ClassRunner.runChild(DeviceJUnit4ClassRunner.java:63)
    26. at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
    27. at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
    28. at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
    29. at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
    30. at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
    31. at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
    32. at com.android.tradefed.testtype.DeviceJUnit4ClassRunner.run(DeviceJUnit4ClassRunner.java:147)
    33. at com.android.tradefed.testtype.junit4.ExceptionThrowingRunnerWrapper.run(ExceptionThrowingRunnerWrapper.java:43)
    34. at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    35. at com.android.tradefed.testtype.HostTest.runJUnit4Tests(HostTest.java:736)
    36. at com.android.tradefed.testtype.HostTest.runTestClasses(HostTest.java:616)
    37. at com.android.tradefed.testtype.HostTest.run(HostTest.java:564)
    38. at com.android.compatibility.common.tradefed.testtype.JarHostTest.run(JarHostTest.java:56)
    39. at com.android.tradefed.testtype.suite.GranularRetriableTestWrapper.intraModuleRun(GranularRetriableTestWrapper.java:379)
    40. at com.android.tradefed.testtype.suite.GranularRetriableTestWrapper.run(GranularRetriableTestWrapper.java:289)
    41. at com.android.tradefed.testtype.suite.ModuleDefinition.run(ModuleDefinition.java:595)
    42. at com.android.tradefed.testtype.suite.ITestSuite.runSingleModule(ITestSuite.java:951)
    43. at com.android.tradefed.testtype.suite.ITestSuite.run(ITestSuite.java:828)
    44. at com.android.tradefed.invoker.InvocationExecution.runTest(InvocationExecution.java:1359)
    45. at com.android.tradefed.invoker.InvocationExecution.runTests(InvocationExecution.java:1138)
    46. at com.android.tradefed.invoker.TestInvocation.prepareAndRun(TestInvocation.java:626)
    47. at com.android.tradefed.invoker.TestInvocation.performInvocation(TestInvocation.java:278)
    48. at com.android.tradefed.invoker.TestInvocation.invoke(TestInvocation.java:1357)
    49. at com.android.tradefed.command.CommandScheduler$InvocationThread.run(CommandScheduler.java:686)
    50. Caused by: com.android.ddmlib.ShellCommandUnresponsiveException
    51. at com.android.ddmlib.AdbHelper.executeRemoteCommand(AdbHelper.java:731)
    52. at com.android.ddmlib.AdbHelper.executeRemoteCommand(AdbHelper.java:511)
    53. at com.android.ddmlib.internal.DeviceImpl.executeShellCommand(DeviceImpl.java:722)
    54. at com.android.tradefed.device.NativeDevice$2.run(NativeDevice.java:897)
    55. at com.android.tradefed.device.NativeDevice.performDeviceAction(NativeDevice.java:2525)
    56. ... 44 more

    2. source code

    1. public void testPeakPssOfAllApps() throws Exception {
    2. final int flags = 268468224;
    3. //------------step1
    4. final String[] activities = ActivityQueryHelper.ALL_APPS_QUERY.run(this.getDevice());
    5. Assert.assertTrue("No activities found", activities.length > 0);
    6. final Set exemptedActivities = new HashSet();
    7. for (final ActivityQuery query : ActivityQueryHelper.APPS_BY_CATEGORY) {
    8. exemptedActivities.addAll(Arrays.asList(query.run(this.getDevice())));
    9. }
    10. //------------step2
    11. final Set exemptedPackages = new HashSet();
    12. exemptedPackages.addAll(this.readExemptions("gallery_exemptions"));
    13. exemptedPackages.addAll(this.readExemptions("streaming_music_apps"));
    14. exemptedPackages.addAll(this.readExemptions("streaming_video_apps"));
    15. exemptedPackages.addAll(this.readExemptions("all_apps_memory_exemptions"));
    16. final List activityList = new ArrayList(Arrays.asList(activities));
    17. //------------step3
    18. final Iterator it = activityList.iterator();
    19. while (it.hasNext()) {
    20. final String activity = it.next();
    21. final String packageName = activity.split("/")[0];
    22. if (exemptedPackages.contains(packageName)) {
    23. LogUtil.CLog.d("exempt package " + packageName);
    24. it.remove();
    25. }
    26. else {
    27. if (!exemptedActivities.contains(activity)) {
    28. continue;
    29. }
    30. LogUtil.CLog.d("exempt activity " + activity);
    31. it.remove();
    32. }
    33. }
    34. //------------step4
    35. LogUtil.CLog.d("These apps will be checked: " + String.join(",", activityList));
    36. //------------step5
    37. final long maxPeakPssAllowed = this.calculateMaxAllowedPeakPssUsage("max_memory_all_apps");
    38. final StringBuilder violations = new StringBuilder();
    39. for (final String activity2 : activityList) {
    40. //------------step6
    41. final String packageName2 = activity2.split("/")[0];
    42. this.runPostNotificationPermissionTest("grantRuntimePermission", packageName2);
    43. final String amOutput = this.getDevice().executeShellCommand(this.buildStartActivityCommand(activity2, 268468224));
    44. Assert.assertTrue(activity2 + " failed to start", amOutput.contains("Status: ok"));
    45. TimeUnit.SECONDS.sleep(30L);
    46. if (this.shouldExemptTopActivity(exemptedActivities)) {
    47. continue;
    48. }
    49. //------------step7
    50. final long memoryKb = this.getMemoryUsage(packageName2);
    51. this.stopApplication(packageName2);
    52. if (memoryKb >= maxPeakPssAllowed) {
    53. violations.append(packageName2).append(" ").append(memoryKb).append(",");
    54. }
    55. this.runPostNotificationPermissionTest("revokeRuntimePermission", packageName2);
    56. }
    57. //------------step8
    58. if (violations.length() > 0) {
    59. violations.append(" failed to keep to the max pss of ");
    60. violations.append(maxPeakPssAllowed);
    61. Assert.fail(violations.toString());
    62. }
    63. }

    源码比较多,都封装在 GtsMemoryHostTestCases.jar 中。这里只是来看下 test 接口。

    step1. 查找所有符合要求的activity

    通过 ActivityQueryHelper.ALL_APPS_QUERY 来查询所有符合条件的 activities:

    1. ActivityQueryHelper.java
    2. ALL_APPS_QUERY = new ActivityQuery().setAction("android.intent.action.MAIN").setCategory("android.intent.category.LAUNCHER");

    要求Action 为 android.intent.action.MAIN,category 为 android.intent.category.LAUNCHER 的所有 Activities。

    step2. 确定免除的package

    1. final Set exemptedPackages = new HashSet();
    2. exemptedPackages.addAll(this.readExemptions("gallery_exemptions"));
    3. exemptedPackages.addAll(this.readExemptions("streaming_music_apps"));
    4. exemptedPackages.addAll(this.readExemptions("streaming_video_apps"));
    5. exemptedPackages.addAll(this.readExemptions("all_apps_memory_exemptions"));

    这些可以免除的 package 都定义在 GtsMemoryHostTestCases.dynamic 文件中。

    step3. 轮询确定最终的activity

    被免除的应用会在 log 中打印出来:

    1. 09-14 10:02:54 D/AllAppsMemoryHostTest: exempt activity com.android.chrome/com.google.android.apps.chrome.Main
    2. 09-14 10:02:54 D/AllAppsMemoryHostTest: exempt activity com.google.android.apps.photosgo/.home.HomeActivity
    3. 09-14 10:02:54 D/AllAppsMemoryHostTest: exempt package com.google.android.youtube
    4. 09-14 10:02:54 D/AllAppsMemoryHostTest: exempt activity org.codeaurora.dialer/com.android.dialer.main.impl.MainActivity
    5. 09-14 10:02:54 D/AllAppsMemoryHostTest: exempt package com.google.android.apps.nbu.files

    step4. 确定最终可以check 的activity

    在经过 step3 之后,log 中会打印出最终需要 check 的acitivity:

    1. 09-14 10:02:54 D/AllAppsMemoryHostTest: These apps will be checked: com.android.mms/.ui.ConversationList,
    2. com.android.settings/.Settings,
    3. com.android.soundrecorder/.SoundRecorder,
    4. com.android.vending/.AssetBrowserActivity,
    5. com.google.android.apps.assistant/.go.MainActivity,
    6. com.google.android.apps.messaging/.ui.ConversationListActivity,
    7. com.google.android.apps.tachyon/.MainActivity,
    8. com.google.android.calculator/com.android.calculator2.Calculator,
    9. com.google.android.calendar/com.android.calendar.AllInOneActivity,
    10. com.google.android.contacts/com.android.contacts.activities.PeopleActivity,
    11. com.google.android.deskclock/com.android.deskclock.DeskClock,
    12. com.google.android.dialer/.extensions.GoogleDialtactsActivity,
    13. org.codeaurora.snapcam/com.android.camera.CameraLauncher,
    14. com.caf.fmradio/.FMRadio,
    15. com.google.android.apps.mapslite/com.google.maps.lite.twa.MapsLiteTwaLauncherActivity,
    16. com.google.android.apps.searchlite/.ui.SearchActivity

     step5. 确定设备的 layout size,并确定peakPss

    设备的layout size 在《GTS 中testPersistentProcessMemory fail 详解》一文中已经分析过,详细看第 2.1 节。

    这里最终根据 layout size 确定 peakPss,该属性值都定义  GtsMemoryHostTestCases.dynamic 文件中:

    1. ...
    2. "max_memory_all_apps_2gb_hd">
    3. 153600
    4. ...

    step6. 轮询待check的activities,确定package name,并申请 android.permission.POST_NOTIFICATIONS 权限。

    step7. 确定进程内存,并关闭notification 权限

    通过 dumpsys -t 30 meminfo --package packageName 的命令确定进程内存,依然通过 Pattern 类确定内存:

    1. final List usages = new ArrayList();
    2. final Matcher matcher = Pattern.compile("TOTAL\\s+([\\d]+)").matcher(output);
    3. while (matcher.find()) {
    4. usages.add(matcher.group(1));
    5. }
    6. Assert.assertFalse("Could not get meminfo total for " + packageName, usages.isEmpty());
    7. return usages.stream().mapToLong((ToLongFunctionsuper Object>)Long::valueOf).sum();

    step8. 统计超过 max pss

    如果有进程的 memory 超过了 peakPss,则会打印显示

    3. 解决方案

    本文中的 error log 从host log 中比较清晰:

    1. 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.
    2. 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.
    3. 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.
    4. 09-14 10:16:34 I/TestFailureListener: FailureListener.testFailed com.google.android.memory.gts.AllAppsMemoryHostTest#testPeakPssOfAllApps false
    5. ...
    6. 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.

    根本原因是启动这个 acitivity 没有返回 Staatus: ok 的状态

    另外,同 《testPersistentProcessMemory failed》 一文,如果是非 GO device,该case 会被 skip,也就是说只有在 GO 平台才会出现这样的failed case:

    1. 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
    2. at org.junit.Assume.assumeTrue(Assume.java:68)
    3. at com.google.android.memory.gts.MemoryHostTestBase.checkGoDevice(MemoryHostTestBase.java:89)
    4. at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    5. at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    6. at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    7. at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    8. at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
    9. at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    10. at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:61)
    11. at org.junit.internal.runners.statements.RunBefores.invokeMethod(RunBefores.java:33)
    12. at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
    13. at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
    14. at org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:54)
    15. at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
    16. at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
    17. at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
    18. at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
    19. at com.android.tradefed.testtype.DeviceJUnit4ClassRunner.runChild(DeviceJUnit4ClassRunner.java:111)
    20. at com.android.tradefed.testtype.DeviceJUnit4ClassRunner.runChild(DeviceJUnit4ClassRunner.java:63)
    21. at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
    22. at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
    23. at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
    24. at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
    25. at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
    26. at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
    27. at com.android.tradefed.testtype.DeviceJUnit4ClassRunner.run(DeviceJUnit4ClassRunner.java:147)
    28. at com.android.tradefed.testtype.junit4.ExceptionThrowingRunnerWrapper.run(ExceptionThrowingRunnerWrapper.java:43)
    29. at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    30. at com.android.tradefed.testtype.HostTest.runJUnit4Tests(HostTest.java:736)
    31. at com.android.tradefed.testtype.HostTest.runTestClasses(HostTest.java:616)
    32. at com.android.tradefed.testtype.HostTest.run(HostTest.java:564)
    33. at com.android.compatibility.common.tradefed.testtype.JarHostTest.run(JarHostTest.java:56)
    34. at com.android.tradefed.testtype.suite.GranularRetriableTestWrapper.intraModuleRun(GranularRetriableTestWrapper.java:379)
    35. at com.android.tradefed.testtype.suite.GranularRetriableTestWrapper.run(GranularRetriableTestWrapper.java:289)
    36. at com.android.tradefed.testtype.suite.ModuleDefinition.run(ModuleDefinition.java:595)
    37. at com.android.tradefed.testtype.suite.ITestSuite.runSingleModule(ITestSuite.java:951)
    38. at com.android.tradefed.testtype.suite.ITestSuite.run(ITestSuite.java:828)
    39. at com.android.tradefed.invoker.InvocationExecution.runTest(InvocationExecution.java:1359)
    40. at com.android.tradefed.invoker.InvocationExecution.runTests(InvocationExecution.java:1138)
    41. at com.android.tradefed.invoker.TestInvocation.prepareAndRun(TestInvocation.java:626)
    42. at com.android.tradefed.invoker.TestInvocation.performInvocation(TestInvocation.java:278)
    43. at com.android.tradefed.invoker.TestInvocation.invoke(TestInvocation.java:1357)
    44. at com.android.tradefed.command.CommandScheduler$InvocationThread.run(CommandScheduler.java:686)

  • 相关阅读:
    计算机网络概念入门(十一)
    React三属性之:props
    Redis热key如何发现和解决
    Mysql忽略大小写问题
    游戏显示分辨率的逆向分析
    聊聊啥项目适合做自动化测试
    “NPM”的全称(github.com/npm/npm-expansions)
    七夕节赚取徽章啦
    MongoDB语言命令
    Android_三MSM8953_android10_移植nmap
  • 原文地址:https://blog.csdn.net/jingerppp/article/details/132889895