GTS 中testPeakPssOfAllApps fail 详解

news2024/11/23 19:52:19

0. 前言

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

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

1. error log

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. source code

    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());
        }
    }

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

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

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

ActivityQueryHelper.java

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

        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"));

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

step3. 轮询确定最终的activity

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

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

step4. 确定最终可以check 的activity

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

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

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

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

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

    ...

    <entry key="max_memory_all_apps_2gb_hd">
        <value>153600</value>
    </entry>

    ...

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

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

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

        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();

step8. 统计超过 max pss

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

3. 解决方案

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

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.

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

 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1010075.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

第十届IEEE电气工程与自动化国际学术论坛(IFEEA 2023)

第十届IEEE电气工程与自动化国际学术论坛&#xff08;IFEEA 2023&#xff09; 2023 10th International Forum on Electrical Engineering and Automation IFEEA论坛属一年一度的国际学术盛会。因其影响力及重要性&#xff0c;IFEEA论坛自创建筹办以来&#xff0c;便受到国内…

【React】面试题5题

1. 说说你对 dangerouslySetInnerHTML 的理解 dangerouslySetInnerHTML是React中的一个属性&#xff0c;用于将HTML代码作为字符串直接插入到组件中的DOM元素中。它可以用来动态地生成HTML内容&#xff0c;但同时也带来了一些潜在的安全风险。 使用dangerouslySetInnerHTML时…

函数递归详解

前言&#xff1a; 函数递归是一种算法&#xff0c;递归是通过将问题分解为更小的子问题来解决问题的办法&#xff0c;递归的优点如下&#xff1a; 简洁性&#xff1a;递归可以用较少的代码实现复杂的功能灵活性&#xff1a;递归可以应对未知深度的数据结构&#xff0c;因为它不…

Spring MVC 中的数据绑定和验证机制是什么,如何使用

在 Spring MVC 应用中&#xff0c;数据绑定和验证是非常重要的一部分&#xff0c;它们可以帮助我们将用户提交的数据绑定到 Java 对象上&#xff0c;并对数据进行验证&#xff0c;保证数据的正确性和可靠性。在 Spring MVC 中&#xff0c;数据绑定和验证机制都是通过注解来实现…

Unity 课时 4 : No.4 模拟面试题

课时 4 : No.4 模拟面试题 C# 1. 请说明字符串中 string str null string str “” string str string.Empty 三者的区别 第一个未作初始化没有值, 第二个为空字符串, 答案&#xff1a; str null 在堆中没有分配内存地址 str "" 和 string.Empty 一样都是…

CentOS7 yum安装报错:“Could not resolve host: mirrorlist.centos.org; Unknown error“

虚拟机通过yum安装东西的时候弹出这个错误&#xff1a; 1、查看安装在本机的网卡 网卡ens33处于disconnected的状态 nmcli d2、输入命令&#xff1a; nmtui3、选择网卡&#xff0c;然后点击edit 4、移动到Automatically connect按空格键选择&#xff0c;然后移动到OK键按空格…

Win7 IIS7解析漏洞复现

一、漏洞说明 文件上传使用白名单做限制&#xff0c;只能上传图片文件&#xff0c;导致脚本文件无法上传&#xff0c;上传图片马绕过白名单文件上传的验证&#xff0c;但是图片马又无法解析&#xff0c;利用IIS7.5文件解析漏洞的特点&#xff1a;任意文件名/任意文件名.php&…

华为云云耀云服务器L实例评测 | Linux系统宝塔运维部署H5游戏

文章目录 前言一、云服务器相对传统服务器有什么优势1.1、可伸缩性&#xff08;Scalability&#xff09;1.2、灵活性&#xff08;Flexibility&#xff09;1.3、高可用性&#xff08;High Availability&#xff09;1.4、备份和恢复&#xff08;Backup and Recovery&#xff09;1…

SVN学习笔记--如何 Merge 分支?保姆级教学,带图片手把手实操。

目录 前言实例具体步骤总结 前言 由于项目中有多个分支&#xff0c;如果修改了一处代码&#xff0c;可能需要保证分支和主分支代码一样&#xff0c;所以需要利用 SVN Merge 代码。 实例 现在有两个分支 一个 trunk&#xff1a;主分支一个 develop&#xff1a;开发分支 我们…

数学实验-迭代(Mathematica实现)

一、实验名称&#xff1a;迭代 二、实验环境&#xff1a;Mathematica 10.3软件 三、实验目的&#xff1a;本实验通过Mathematica 10.3软件利用迭代求解方程的近似解&#xff0c;了解迭代方法在解决问题的收敛速度的异同&#xff0c;认识到函数的迭代是数学研究中的一个非常重…

PHPword setImageValue 设置高度不生效

phpword 版本 "phpoffice/phpword": "^0.18.3 我正在使用这个代码&#xff0c;使用模板&#xff0c;写入动态图片&#xff0c;但问题是图像的大小太小&#xff0c;我需要增加高度和宽度 模板文件 如下 问题写法&#xff1a; $file_name "简历";…

UWB学习——day4

UWB学习——day4 技术劣势技术细节UWB频段系统调制方式UWB帧结构芯片实例 技术劣势 干扰其它技术&#xff0c;UWB技术目前允许在未授权的3.1 GHz至10.6 GHz频谱上运行&#xff0c;但该频谱上有许多其它无线通讯所在的频带&#xff0c;容易互相产生干扰&#xff0c;反而限制了适…

基因型数据VCF转EXCEL亲测好用

import pandas as pd df pd.read_csv(shuju.vcf, sep\t, comment#, headerNone,encodingutf-8) df.to_excel(outputFile2.xlsx, indexFalse,encodingutf-8) 以上就是转成功的截图&#xff0c;需要注意的是一定要写入编码方式&#xff0c;UTF-8 &#xff0c;第一次我没有写编码…

实景无人直播系统哪个最好用?呆头鹅无人直播系统

软件图片素材来自于公众号&#xff1a;生财风暴 关注进行领取价值1000元的采集软件&#xff0c;和呆头鹅批量剪辑和矩阵管理系统演示 在未来&#xff0c;想要低成本在人工智能领域创业&#xff0c;其实很简单&#xff0c;如果你是想要低成本创业的人&#xff0c;那么请一定要把…

leetcode 1222. 可以攻击国王的皇后(每日一题)

1222. 可以攻击国王的皇后 在一个 8x8 的棋盘上&#xff0c;放置着若干「黑皇后」和一个「白国王」。 给定一个由整数坐标组成的数组 queens &#xff0c;表示黑皇后的位置&#xff1b;以及一对坐标 king &#xff0c;表示白国王的位置&#xff0c;返回所有可以攻击国王的皇后的…

pcl--第三节 关键点

简介 关键点也称为兴趣点&#xff0c;它是 2D 图像或 3D 点云或曲面模型上,可以通过检测标准来获取的具有稳定性、区别性的点集。从技术上来说,关键点的数量比原始点云或图像的数据量少很多&#xff0c;其与局部特征描述子结合组成关键点描述子。常用来构成原始数据的紧凑表示…

Furion api npm web vue混合开发

Furion api npm web vue混合开发 Furion-api项目获取swagger.json文件复制json制作ts包删除非.ts文件上传到npm获取npm包引用 Furion-api项目获取swagger.json文件 使用所有接口合并的配置文件 复制json制作ts包 https://editor.swagger.io 得到 typescript-axios-clien…

封面人物 | 贾楠:向中介费全面开炮

古人云&#xff0c;燕赵之地多慷慨豪侠之士。贾楠便是一个将豪迈的破局精神融入诸多创意项目的探路者&#xff0c;以及醉心于诗意人生的思考者。 上世纪90年代&#xff0c;他曾尾随南下大军在海南淘得第一桶金。之后&#xff0c;贾楠涉足影视投资&#xff0c;投身健康产业……所…

软件测试如何制作一份亮眼的简历?

简历是入职职场的一张名片&#xff0c;也是进入职场的一块“敲门砖”。从某种角度说&#xff0c;简历也是一张专业人员的说明书。 在互联网行业&#xff0c;如果你在一线企业任职、是业内大佬、技术大牛&#xff0c;基本上大把的高薪工作等你来挑。但是对于转行的小白来说&…

【产品实习评审】对推电影项目核心推荐功能的交互设计比较到位

大家好&#xff0c;本篇文章分享【校招VIP】免费商业项目“推电影”第一期电影详情模块产品同学的原型图周最佳作品。该同学来【莱顿大学】“数学”专业。 1、本项目是基于年轻人的喜好&#xff0c;更个性的电影推荐网站。筛选各分类的知名电影&#xff0c;并给出推荐理由和下…