文章目录
-
- 词汇表
- [CTS 组件](#CTS 组件)
- [Trade Federation](#Trade Federation)
- [安装 aapt 和 adb](#安装 aapt 和 adb)
- 源码
- 下载
- MCTS
- 使用
- 测试结果
- 日志
- CtsDeqpTestCases
- CtsViewTestCases
- CtsDisplayTestCases
- [list module 中带有 [instant],[secondary_user] 等后缀](#list module 中带有 [instant],[secondary_user] 等后缀)
- [Tradefed 如何处理 `--test` 选项的?](#Tradefed 如何处理
--test选项的?) - [Tradefed 如何处理 `--include-filter` 选项的?](#Tradefed 如何处理
--include-filter选项的?) - [Tradefed 是如何处理非通用选项的?](#Tradefed 是如何处理非通用选项的?)
- [run plan 和 run module 的区别?](#run plan 和 run module 的区别?)
- [测试结果为 `Assumption Failure`](#测试结果为
Assumption Failure) - [测试结果为 `IGNORED`](#测试结果为
IGNORED) - 参考资料
- [一个 plan 是如何知道要运行那些模块的呢?](#一个 plan 是如何知道要运行那些模块的呢?)
- 无法在设备上运行测试
- [加了 Host 的 java 代理后失败](#加了 Host 的 java 代理后失败)
- [ClearcutClient 组建失败](#ClearcutClient 组建失败)
- [运行 CtsDisplayTestCases 报错](#运行 CtsDisplayTestCases 报错)
兼容的目标是可以运行 Android SDK 和 NDK 编写的任何第三方应用。这要求 Android 设备必须遵守 CDD,并通过 CTS 测试。
词汇表
DUT:Device Under Test,被测设备;
CDD:compatibility definition document,兼容性定义文档;AOSP 是 Android 的参考实现,设备厂商应尽可能基于 AOSP 实现。
CTS:compatibility test suite,兼容性测试套件;无法做到面面俱到,主要针对软件行为做测试,无法探测硬件的真实表现。
GMS:Google Mobile Services,谷歌移动服务;会有一个 Google Play Services,管理谷歌应用与谷歌服务器之间的连接,并对应用提供 API,实现 FCM 推送,登录服务,地图服务,支付服务等等。
CTS 组件
Trade Federation:自动化测试框架CTS automated tests:可以运行在 Trade Federation 框架下的测试CTS Verifier (CTS-V) tests:需要手动运行的测试,通常和硬件相关,需要人来判断结果CTS Verifier (CTS-V) app:运行手动测试和收集结果的应用Test case:测试用例Test configuration:由一组测试用例 + 环境配置组成的自动化测试Test module:由一组用于测试相同功能的测试用例组成的测试配置Test plan:由一系列测试模块组成的测试配置,源码位于 aosp 工程的cts/tools/cts-tradefed/res/config/xxx.xml
Trade Federation
Trade Federation 是一款在主机上运行的 Java 应用,它通过 adb 与一部或多部 Android 设备进行通信,专门用于在 Android 设备上运行测试。
工程源码路径:tools/tradefederation/。
build_provider:创建运行测试所需的所有文件,可能会从 google 服务器下载target_preparer:根据测试配置将测试环境设置为必要状态,包括主机和设备test:运行测试result_reporter:向配置的服务报告运行结果
TF 的测试单元是以 XML 格式定义的 .config 文件,上述四个测试配置即在该文件中定义。所有可配置的对象在 IConfiguration 接口 中定义:
xml
<configuration description="<description of the configuration>">
<!-- A build provider that takes local device information -->
<build_provider class="com.android.tradefed.build.BootstrapBuildProvider" />
<!-- Some target preparation, disabled by default -->
<target_preparer class="com.android.tradefed.targetprep.PreloadedClassesPreparer">
<option name="disable" value="true" />
</target_preparer>
<!-- One test running some unit tests -->
<test class="com.android.tradefed.testtype.HostTest">
<option name="class" value="com.android.tradefed.build.BuildInfoTest" />
</test>
<!-- [OPTIONAL] -->
<logger class="com.android.tradefed.log.FileLogger">
<option name="log-level" value="VERBOSE" />
<option name="log-level-display" value="VERBOSE" />
</logger>
<!-- [OPTIONAL] -->
<log_saver class="com.android.tradefed.result.FileSystemLogSaver" />
<!-- As many reporters as we want -->
<result_reporter class="com.android.tradefed.result.ConsoleResultReporter" />
<result_reporter class="com.android.tradefed.result.suite.SuiteResultReporter" />
<result_reporter class="com.android.tradefed.result.MetricsXMLResultReporter"/>
</configuration>
每个对象都有与其关联的 Java 类,该对象在 class= 中进行定义,并在运行时解析;因此,只要包含该类的 JAR 文件在运行时位于 Tradefed Java 类路径上,就会被找到并解析。
安装 aapt 和 adb
sdkmanager 是一个命令行工具,可用于查看、安装、更新和卸载 Android SDK 的软件包。该工具包含在 Command-Line Tools 中。
首先需要从 Android Studio 中下载 Command-Line Tools。
因为下载的包文件路径不满足 sdkmanager 运行时对项目根路径的需求,官方文档用多个手工步骤来建立项目目录,过于复杂。
这里直接明确指定项目根路径 ,并重新下载 Command-Line Tools,自动创建项目路径:
shell
$ unzip commandlinetools-linux-14742923_latest.zip
$ cd cmdline-tools/bin/
$ export JAVA_HOME=/data/cts/android-cts/jdk
$ export JAVA_TOOL_OPTIONS="-Dhttps.proxyHost=127.0.0.1 -Dhttps.proxyPort=18010"
$ ./sdkmanager --install "cmdline-tools;latest" --sdk_root=/data/sdk
此时 /data/sdk 下的工程路径已经准备好了,下面是完整的使用命令行的环境变量配置:
shell
$ export JAVA_HOME=/data/cts/android-cts/jdk
$ export JAVA_TOOL_OPTIONS="-Dhttps.proxyHost=127.0.0.1 -Dhttps.proxyPort=18010"
$ export ANDROID_HOME=/data/sdk
$ export PATH=\
$ANDROID_HOME/cmdline-tools/latest/bin:\
$ANDROID_HOME/build-tools/36.1.0:\
$ANDROID_HOME/platform-tools:\
$PATH
用 sdkmanager 下载另外两个命令行工具:
shell
$ sdkmanager --install "build-tools;36.1.0"
$ sdkmanager --install "platform-tools"
常用命令:
shell
### 可安装的包
$ sdkmanager --list
### 已安装的包
$ sdkmanager --list_installed
### 安装
$ sdkmanager --install "cmdline-tools;latest"
### 卸载
$ sdkmanager --uninstall "cmdline-tools;latest"
### 更新
$ sdkmanager --update
源码
cts/tests/:测试框架、辅助应用、工具等,为测试用例运行提供支持cts/tests/test/:测试用例
下载
下载 cts 环境:
shell
### 自动测试
$ wget https://dl.google.com/dl/android/cts/android-cts-16.1_r3-linux_x86-arm.zip
### 手动确认测试
$ wget https://dl.google.com/dl/android/cts/android-cts-verifier-16.1_r3-linux_x86-arm.zip
如果要运行下面三个测试用例,可以先行下载媒体文件,加快测试速度,并以离线方式部署:
CtsMediaTestCasesCtsMediaStressTestCasesCtsMediaBitstreamsTestCases
shell
$ wget https://dl.google.com/dl/android/cts/android-cts-media-1.5.zip
$ wget https://dl.google.com/dl/android/cts/android-cts-media-1.4.zip
MCTS
MCTS:Mainline Compatibility Test Suite,Mainline CTS;由 Google 管理、独立更新的 Mainline 模块。在 Android 10 之后,谷歌推出了 Project Mainline,它的核心思想是将 Android 系统"模块化",允许谷歌直接通过 Google Play 系统更新来修复核心组件(如 WiFi 驱动、媒体解码器、权限控制器等),而不需要等待手机厂商推送整个系统的 OTA 更新。MCTS 专门用来测试这些可以独立更新的模块。
目前该模块已经遗弃,所有模块均包含在标准侧 cts 包中,该脚本不会下载任何文件。
直接运行:
shell
$ wget -O - \
"https://android.googlesource.com/platform/cts/+/refs/heads/main/tools/mcts/download_mcts.sh?format=TEXT" \
| base64 -d \
| bash -s -- --abi arm64 --android_version 34
先拷贝脚本为 download_mcts.sh 再运行:
shell
$ ./download_mcts.sh --abi arm64 --android_version 36
$ ./download_mcts.sh --abi arm64 --year 2025 --month 12
使用
shell
$ unzip android-cts-16.1_r2-linux_x86-arm.zip
解压后主要是三个文件夹:
jdk:java 运行时testcases:jar 构成的测试用例tools:启动脚本和 Trade 框架(.jar)
shell
$ export ANDROID_HOME=/data/sdk
$ export PATH=\
$ANDROID_HOME/cmdline-tools/latest/bin:\
$ANDROID_HOME/build-tools/36.1.0:\
$ANDROID_HOME/platform-tools:\
$PATH
$ export JAVA_TOOL_OPTIONS="-Dhttps.proxyHost=127.0.0.1 -Dhttps.proxyPort=18010"
$ ./android-cts/tools/cts-tradefed
常用命令:
shell
### 列出测试计划,计划在项目工程的 cts/tools/cts-tradefed/res/config/ 路径下
### 在构建的时候会打包近 TF 的 jar 中
> list plans
### 列出模块
### 列出 CTS 包中 testcases 目录下的模块
### 模块和计划其实都是测试配置(Test configuration),只是计划可能有顶层的 target_preparer 来准备环境
> list modules
### 查看连接的设备及其状态
### Available:空闲设备
### Allocated:正在运行测试
> list devices
### 查看正在排队的命令
> list commands
### 查看正在运行的测试
> list invocations
### 查看测试结果摘要
> list results
测试结果
结果位于 android-cts/results/<start_time>.zip
可直接使用浏览器打开 test_result.html,它会帮忙解析 test_result.xml。在后者中,<StackTrace> 用来标记错误原因。
日志
OLC:OmniLab Client;OmniLab 是 Google 开发的一套用于 自动化测试管理和设备基础设施 的企业级平台。管理成百上千个引擎(Tradefed)、设备和测试任务的"中央指挥部"。
inv_static_xts_:静态模块测试日志device_logcat_setup_*:环境准备日志device_logcat_test_*:测试执行日志device_logcat_teardown_*:清理日志
inv_mcts_:Mainline CTS 模块测试用例日志olc_server_session_logs:OmniLab Client 相关日志
CtsDeqpTestCases
dEQP:drawElements Quality Program;由 drawElements 公司开发的商业套件,后来被 Google 收购并开源,集成到了 Android 系统的开发和测试流程中。
源码:external/deqp/android/cts/AndroidTest.xml
跑完整的模块测试:
shell
> run cts -m CtsDeqpTestCases --abi arm64-v8a
跑几个单独的测试用例:
shell
> run cts \
--abi arm64-v8a \
--include-filter "CtsDeqpTestCases dEQP-EGL.functional.get_frame_timestamps#rgb888_no_depth_stencil" \
--include-filter "CtsDeqpTestCases dEQP-EGL.functional.get_frame_timestamps#rgb888_depth_stencil" \
--include-filter "CtsDeqpTestCases dEQP-EGL.functional.get_frame_timestamps#rgb565_depth_no_stencil"
跑 dEQP-EGL 类测试用例:
shell
> run cts \
--abi arm64-v8a \
--include-filter "CtsDeqpTestCases dEQP-EGL.*"
CtsViewTestCases
验证 Android 屏幕绘制、触摸事件、布局容器等 UI 核心机制是否严格符合 CDD 的 CTS 测试集合。
跑完整的模块测试:
shell
> run cts -m CtsViewTestCases --abi arm64-v8a
跑单独的测试用例:
shell
> run cts \
--abi arm64-v8a \
--include-filter "CtsViewTestCases android.view.cts.SystemGestureExclusionRectsTest#animatingView"
CtsDisplayTestCases
主要目的是确保 Android 设备的显示子系统(包括主屏幕、外部显示器、虚拟显示等)符合 Google 的兼容性标准,从而保证应用在不同设备上拥有一致且正确的显示表现。
为了不锁屏,需要在 Android 上加锁:
shell
$ echo "my_app_lock" > /sys/power/wake_lock
跑完整的测试:
shell
> run cts \
-m CtsDisplayTestCases
只跑 32 位,并且排除 instant 模式:
shell
> run cts \
--abi armeabi-v7a \
-m CtsDisplayTestCases \
--exclude-filter "CtsDisplayTestCases[instant]"
只跑 32 位 instant 模式:
shell
> run cts \
--abi armeabi-v7a \
--include-filter "CtsDisplayTestCases[instant]"
list module 中带有 [instant],[secondary_user] 等后缀
这是在 android-cts/testcases 的 xxx.config 中,有 config-descriptor:metadata 描述,Tradefed 会自动为这些后缀生成相应的测试用例:
xml
<option name="config-descriptor:metadata" key="component" value="sysui" />
<option name="config-descriptor:metadata" key="parameter" value="instant_app" />
<option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
<option name="config-descriptor:metadata" key="parameter" value="secondary_user" />
<option name="config-descriptor:metadata" key="parameter" value="secondary_user_on_secondary_display" />
<option name="config-descriptor:metadata" key="parameter" value="run_on_sdk_sandbox" />
<option name="config-descriptor:metadata" key="parameter" value="all_foldable_states" />
Tradefed 如何处理 --test 选项的?
--test 选项会直接透传给 test runner 去解析,而不是 Tradefed 框架解析。
以最常见的 com.android.tradefed.testtype.AndroidJUnitTest 执行器为例:在 CtsMediaMiscTestCases 模块中包含了 android.media.misc.cts 包的 ThumbnailUtilsTest 类,并通过 @Test 装饰器定义了 testCreateImageThumbnail 方法:
java
cts/tests/tests/media/misc/src/android/media/misc/cts/ThumbnailUtilsTest.java
package android.media.misc.cts;
......
public class ThumbnailUtilsTest {
......
@Test
public void testCreateImageThumbnail() throws Exception {
final File file = stageFile("volantis.jpg", new File(mDir, "cts.jpg"));
for (Size size : TEST_SIZES) {
assertSaneThumbnail(size, ThumbnailUtils.createImageThumbnail(file, size, null));
}
}
......
}
则可以在运行 cts 时通过 --test 参数将 包名 + 类名 + 方法名 传入 apk 中,指定只执行这个方法:
shell
$ run cts \
--abi arm64-v8a \
--module=CtsMediaMiscTestCases \
--test=android.media.misc.cts.ThumbnailUtilsTest#testCreateImageThumbnail
Tradefed 如何处理 --include-filter 选项的?
其实 --abi, --module, --test 就是 --include-filter 的特例,如果只指定单个模块、测试,可以使用前者;而如果有多个模块和测试,就需要使用后者。
- 不允许
--module与--include-filter一起使用 - 不允许多个
--test使用
shell
> run cts \
--abi arm64-v8a \
--include-filter "CtsDeqpTestCases dEQP-EGL.functional.get_frame_timestamps#rgb888_no_depth_stencil" \
--include-filter "CtsDeqpTestCases dEQP-EGL.functional.get_frame_timestamps#rgb888_depth_stencil" \
--include-filter "CtsDeqpTestCases dEQP-EGL.functional.get_frame_timestamps#rgb565_depth_no_stencil"
Tradefed 是如何处理非通用选项的?
下面是一个 java 类定义,其中两个变量(mWaitTime, mCalls)通过 @Option 装饰,可以在 java 外部通过 name 字段的映射(timeout, call)来修改这两个变量的值:
java
public class PhoneCallFuncTest extends IRemoteTest {
@Option(name = "timeout", description = "How long to wait for connection, in millis")
private long mWaitTime = 30 * 1000; // 30 seconds
@Option(name = "call", description = "Key: Phone number to attempt. " +
"Value: DTMF to expect. May be repeated.")
private Map<String, String> mCalls = new HashMap<String, String>;
public PhoneCallFuncTest() {
mCalls.add("123-456-7890", "01134"); // default
}
可以在测试配置的 XML 文件中通过在 class 中指定 java 类,在 <option/> 中修改:
xml
<?xml version="1.0" encoding="utf-8"?>
<configuration description="low-latency default test; low-latency.xml">
<test class="com.example.PhoneCallFuncTest">
<option name="timeout" value="5000" />
</test>
</configuration>
xml
<?xml version="1.0" encoding="utf-8"?>
<configuration description="call a bunch of numbers; many-numbers.xml">
<test class="com.example.PhoneCallFuncTest">
<option name="call" key="111-111-1111" value="#*#*TEST1*#*#" />
<option name="call" key="222-222-2222" value="#*#*TEST2*#*#" />
<!-- ... -->
</test>
</configuration>
还可以在 tf 的命令行中通过选项修改:
shell
tf> run low-latency.xml --call 111-111-1111 #*#*TEST1*#*# --call 222-222-2222 #*#*TEST2*#*#
tf> run many-numbers.xml --timeout 5000
run plan 和 run module 的区别?
plan 可能包含顶层的 target_preparer 来准备环境
测试结果为 Assumption Failure
这意味着不满足运行条件,测试被跳过了。DeviceConfig 维护了一组数据库,Java 层可以通过 DeviceConfig.getBoolean 来获取值,实现特性开关 (Feature Flag) 的功能。特性开关在 Android 10 引入,将"代码部署"与"功能发布"解耦,代码即使已经运行在用户的手机或服务器上,依然可以在不重新发布版本的情况下,远程开启或关闭某个特定的功能。
可通过 device_config list 查看动态特性开关的值。
| Test | Result | Details |
|---|---|---|
| android.view.animation.cts.AnimationUtilsTest#testGetExpectedPresentationTimeNanos | ASSUMPTION_FAILURE | org.junit.AssumptionViolatedException: Flag android.view.flags.expected_presentation_time_api required to be enabled, but is disabled |
测试结果为 IGNORED
测试用例被 @Ignore 或者 @Disabled 装饰,不会运行。
参考资料
一个 plan 是如何知道要运行那些模块的呢?
- 用户输入:
run cts - 加载
cts.xml:- 读取其引用的
cts-suite.xml。 - 启动
TestSuiteRunner。
- 读取其引用的
- 扫描文件系统: Runner 在
testcases/目录找到CtsSensorTestCases.config。 - 匹配标签: 发现该
.config里有<option name="test-suite-tag" value="cts" />。 - 检查过滤器:
- cts.xml 里有没有排除它?(没有)
- 如果有包含列表,它在不在里面?(在,或者没有定义包含列表则默认全选)
- 确定调用: 该模块被加入执行队列。
无法在设备上运行测试
DynamicConfigPusher 希望从 Google 拉取最新的 DeviceConfig 配置,但网络通信失败。
04-20 16:46:05 E/TestInvocation: Caught exception while running invocation
04-20 16:46:05 E/TestInvocation: Trying to access android partner remote server over internet but failed: Connection timed out
com.android.tradefed.targetprep.TargetSetupError[ANDROID_PARTNER_SERVER_ERROR|500505|DEPENDENCY_ISSUE]: Trying to access android partner remote server over internet but failed: Connection timed out
at com.android.compatibility.common.tradefed.targetprep.DynamicConfigPusher.resolveUrl(DynamicConfigPusher.java:318)
at com.android.compatibility.common.tradefed.targetprep.DynamicConfigPusher.setUp(DynamicConfigPusher.java:172)
at com.android.tradefed.invoker.InvocationExecution.runPreparationOnDevice(InvocationExecution.java:672)
at com.android.tradefed.invoker.InvocationExecution.runPreparersSetup(InvocationExecution.java:573)
at com.android.tradefed.invoker.InvocationExecution.doSetup(InvocationExecution.java:407)
at com.android.tradefed.invoker.TestInvocation.prepareAndRun(TestInvocation.java:667)
at com.android.tradefed.invoker.TestInvocation.performInvocation(TestInvocation.java:304)
at com.android.tradefed.invoker.TestInvocation.invoke(TestInvocation.java:1523)
at com.android.tradefed.command.CommandScheduler$InvocationThread.run(CommandScheduler.java:723)
Caused by: java.net.ConnectException: Connection timed out
at java.base/sun.nio.ch.Net.connect0(Native Method)
at java.base/sun.nio.ch.Net.connect(Net.java:589)
at java.base/sun.nio.ch.Net.connect(Net.java:578)
at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:583)
at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327)
at java.base/java.net.Socket.connect(Socket.java:751)
at java.base/sun.security.ssl.SSLSocketImpl.connect(SSLSocketImpl.java:304)
at java.base/sun.security.ssl.BaseSSLSocketImpl.connect(BaseSSLSocketImpl.java:181)
at java.base/sun.net.NetworkClient.doConnect(NetworkClient.java:183)
at java.base/sun.net.www.http.HttpClient.openServer(HttpClient.java:531)
at java.base/sun.net.www.http.HttpClient.openServer(HttpClient.java:636)
at java.base/sun.net.www.protocol.https.HttpsClient.<init>(HttpsClient.java:264)
at java.base/sun.net.www.protocol.https.HttpsClient.New(HttpsClient.java:377)
at java.base/sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.getNewHttpClient(AbstractDelegateHttpsURLConnection.java:193)
at java.base/sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1237)
at java.base/sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:1123)
at java.base/sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:179)
at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1675)
at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1599)
at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:223)
at java.base/java.net.URL.openStream(URL.java:1325)
at com.android.compatibility.common.tradefed.targetprep.DynamicConfigPusher.resolveUrl(DynamicConfigPusher.java:315)
... 8 more
需要给 Host 上的 java 运行时添加代理:
shell
$ export JAVA_TOOL_OPTIONS="-Dhttps.proxyHost=127.0.0.1 -Dhttps.proxyPort=18010"
加了 Host 的 java 代理后失败
$ cat test_result.html
com.android.tradefed.targetprep.TargetSetupError[APK_INSTALLATION_FAILED|520001|DEPENDENCY_ISSUE]: Failed to install com.drawelements.deqp with [/tmp/tradefed-root-dir-11d0a0ba-773c-425b-addd-e0724ad8e661/android-cts/testcases/CtsDeqpTestCases/com.drawelements.deqp.apk] on 00000014150F18ZF. Reason: 'INSTALL_FAILED_INSUFFICIENT_STORAGE: Failed to override installation location' [00000014150F18ZF pd2508:pd2508 BP4A.251205.006] at com.android.tradefed.targetprep.TestAppInstallSetup.installSinglePackage(TestAppInstallSetup.java:608) at com.android.tradefed.targetprep.TestAppInstallSetup.installer(TestAppInstallSetup.java:568) at com.android.tradefed.targetprep.TestAppInstallSetup.setUp(TestAppInstallSetup.java:449) at com.android.tradefed.testtype.suite.ModuleDefinition.runPreparerSetup(ModuleDefinition.java:1111) at com.android.tradefed.testtype.suite.ModuleDefinition.runTargetPreparation(ModuleDefinition.java:1597) at com.android.tradefed.testtype.suite.ModuleDefinition.runPreparation(ModuleDefinition.java:1070) at com.android.tradefed.testtype.suite.ModuleDefinition.run(ModuleDefinition.java:542) at com.android.tradefed.testtype.suite.ITestSuite.runSingleModule(ITestSuite.java:1504) at com.android.tradefed.testtype.suite.ITestSuite.run(ITestSuite.java:1118) at com.android.tradefed.invoker.InvocationExecution.runTest(InvocationExecution.java:1538) at com.android.tradefed.invoker.InvocationExecution.runTests(InvocationExecution.java:1313) at com.android.tradefed.invoker.TestInvocation.prepareAndRun(TestInvocation.java:685) at com.android.tradefed.invoker.TestInvocation.performInvocation(TestInvocation.java:304) at com.android.tradefed.invoker.TestInvocation.invoke(TestInvocation.java:1523) at com.android.tradefed.command.CommandScheduler$InvocationThread.run(CommandScheduler.java:723)
Failed to override installation,需要扩盘
ClearcutClient 组建失败
用于上报日志给 google 服务器。
没有认证无法上传?已经给 Host 的 Java 添加了代理。
可以忽略该报错,不影响测试结果。
04-23 11:59:36 E/ClearcutClient: Read timed out
java.net.SocketTimeoutException: Read timed out
at java.base/sun.nio.ch.NioSocketImpl.timedRead(NioSocketImpl.java:278)
at java.base/sun.nio.ch.NioSocketImpl.implRead(NioSocketImpl.java:304)
at java.base/sun.nio.ch.NioSocketImpl.read(NioSocketImpl.java:346)
at java.base/sun.nio.ch.NioSocketImpl$1.read(NioSocketImpl.java:796)
at java.base/java.net.Socket$SocketInputStream.read(Socket.java:1099)
at java.base/java.io.BufferedInputStream.fill(BufferedInputStream.java:291)
at java.base/java.io.BufferedInputStream.read1(BufferedInputStream.java:347)
at java.base/java.io.BufferedInputStream.implRead(BufferedInputStream.java:420)
at java.base/java.io.BufferedInputStream.read(BufferedInputStream.java:399)
at java.base/sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:827)
at java.base/sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:759)
at java.base/sun.net.www.protocol.http.HttpURLConnection.doTunneling0(HttpURLConnection.java:2179)
at java.base/sun.net.www.protocol.http.HttpURLConnection.doTunneling(HttpURLConnection.java:2143)
at java.base/sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
at java.base/sun.net.www.protocol.http.HttpURLConnection.getOutputStream0(HttpURLConnection.java:1446)
at java.base/sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1417)
at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:219)
at com.android.tradefed.clearcut.ClearcutClient.sendToClearcut(ClearcutClient.java:344)
at com.android.tradefed.clearcut.ClearcutClient.lambda$flushEvents$1(ClearcutClient.java:322)
at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1768)
at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.exec(CompletableFuture.java:1760)
at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:387)
at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1312)
at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1843)
at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1808)
at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:188)
04-23 11:59:36 E/ClearcutClient: Read timed out
java.net.SocketTimeoutException: Read timed out
at java.base/sun.nio.ch.NioSocketImpl.timedRead(NioSocketImpl.java:278)
at java.base/sun.nio.ch.NioSocketImpl.implRead(NioSocketImpl.java:304)
at java.base/sun.nio.ch.NioSocketImpl.read(NioSocketImpl.java:346)
at java.base/sun.nio.ch.NioSocketImpl$1.read(NioSocketImpl.java:796)
at java.base/java.net.Socket$SocketInputStream.read(Socket.java:1099)
at java.base/java.io.BufferedInputStream.fill(BufferedInputStream.java:291)
at java.base/java.io.BufferedInputStream.read1(BufferedInputStream.java:347)
at java.base/java.io.BufferedInputStream.implRead(BufferedInputStream.java:420)
at java.base/java.io.BufferedInputStream.read(BufferedInputStream.java:399)
at java.base/sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:827)
at java.base/sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:759)
at java.base/sun.net.www.protocol.http.HttpURLConnection.doTunneling0(HttpURLConnection.java:2179)
at java.base/sun.net.www.protocol.http.HttpURLConnection.doTunneling(HttpURLConnection.java:2143)
at java.base/sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
at java.base/sun.net.www.protocol.http.HttpURLConnection.getOutputStream0(HttpURLConnection.java:1446)
at java.base/sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1417)
at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:219)
at com.android.tradefed.clearcut.ClearcutClient.sendToClearcut(ClearcutClient.java:344)
运行 CtsDisplayTestCases 报错
04-28 16:19:10 D/NativeDevice: Device 10.31.95.204:5555 state is now NOT_AVAILABLE
04-28 16:19:10 E/AdbTcpConnection: Adb connection to 10.31.95.204:5555 was refused.
04-28 16:19:10 D/NativeDevice: Device 10.31.95.204:5555 state is now ONLINE
04-28 16:19:15 W/ShellStatusChecker: This module unexpectedly started in a root shell. Leaked from earlier module?
04-28 16:19:15 W/ITestSuite: System status checker [com.android.tradefed.suite.checker.ShellStatusChecker] failed.
04-28 16:19:16 W/ITestSuite: There are failed system status checkers: {com.android.tradefed.suite.checker.ShellStatusChecker=This module unexpectedly started in a root shell. Leaked from earlier module?}
04-28 16:19:16 D/ModuleDefinition: Running module arm64-v8a CtsDisplayTestCases[instant]
04-28 16:19:16 E/AaptParser: aapt2 dump badging stderr: 04-28 16:19:16.330 3789037 3789037 E aapt2 : Entry at index 0 is too small (0)
04-28 16:19:16.330 3789037 3789037 E aapt2 : Entry offset at index 0 points outside the Type's boundaries
04-28 16:19:16.330 3789037 3789037 E aapt2 : Entry offset at index 1 points outside the Type's boundaries
04-28 16:19:16 E/AaptParser: aapt2 dump xmltree AndroidManifest.xml stderr: 04-28 16:19:16.345 3789039 3789039 E aapt2 : Entry at index 0 is too small (0)
04-28 16:19:16.345 3789039 3789039 E aapt2 : Entry offset at index 0 points outside the Type's boundaries
04-28 16:19:16.345 3789039 3789039 E aapt2 : Entry offset at index 1 points outside the Type's boundaries
04-28 16:19:21 E/AaptParser: aapt2 dump badging stderr: 04-28 16:19:19.708 3789356 3789356 E aapt2 : Entry at index 0 is too small (0)
04-28 16:19:19.708 3789356 3789356 E aapt2 : Entry offset at index 0 points outside the Type's boundaries
04-28 16:19:19.708 3789356 3789356 E aapt2 : Entry offset at index 1 points outside the Type's boundaries
04-28 16:19:19.708 3789356 3789356 E aapt2 : Entry offset at index 2 points outside the Type's boundaries
04-28 16:19:19.708 3789356 3789356 E aapt2 : Index 3 points to entry with unaligned offset 0x03080001
04-28 16:19:19.708 3789356 3789356 E aapt2 : Entry at index 4 is too small (1)
04-28 16:19:19.708 3789356 3789356 E aapt2 : Index 5 points to entry with unaligned offset 0x03080002
......
04-28 16:24:14.571 3814797 3814797 E aapt2 : Index 20 points to entry with unaligned offset 0x019c0183
04-28 16:24:14.571 3814797 3814797 E aapt2 : Index 21 points to entry with unaligned offset 0x01b001a3
04-28 16:24:14.571 3814797 3814797 E aapt2 : Entry offset at index 22 points outside the Type's boundaries
04-28 16:24:15 E/AaptParser: Failed to run aapt2 on /tmp/tradefed-root-dir-94291d92-5965-4c6a-a2ce-45e6bf869e40/android-cts/testcases/CtsDisplayTestCases/CtsAppTestStubs.apk. stdout:
04-28 16:24:15 E/ModuleDefinition: Unexpected Exception from preparer: com.android.tradefed.targetprep.suite.SuiteApkInstaller
04-28 16:24:15 E/ModuleDefinition: AaptParser failed for file CtsAppTestStubs.apk. The APK won't be installed
com.android.tradefed.targetprep.TargetSetupError[AAPT_PARSER_FAILED|520050|DEPENDENCY_ISSUE]: AaptParser failed for file CtsAppTestStubs.apk. The APK won't be installed
at com.android.tradefed.targetprep.TestAppInstallSetup.parsePackageName(TestAppInstallSetup.java:788)
at com.android.tradefed.targetprep.TestAppInstallSetup.resolveApkFiles(TestAppInstallSetup.java:676)
at com.android.tradefed.targetprep.TestAppInstallSetup.setUp(TestAppInstallSetup.java:448)
at com.android.tradefed.testtype.suite.ModuleDefinition.runPreparerSetup(ModuleDefinition.java:1111)
at com.android.tradefed.testtype.suite.ModuleDefinition.runTargetPreparation(ModuleDefinition.java:1597)
at com.android.tradefed.testtype.suite.ModuleDefinition.runPreparation(ModuleDefinition.java:1070)
at com.android.tradefed.testtype.suite.ModuleDefinition.run(ModuleDefinition.java:542)
at com.android.tradefed.testtype.suite.ITestSuite.runSingleModule(ITestSuite.java:1504)
at com.android.tradefed.testtype.suite.ITestSuite.run(ITestSuite.java:1118)
at com.android.tradefed.invoker.InvocationExecution.runTest(InvocationExecution.java:1538)
at com.android.tradefed.invoker.InvocationExecution.runTests(InvocationExecution.java:1313)
at com.android.tradefed.invoker.TestInvocation.prepareAndRun(TestInvocation.java:685)
at com.android.tradefed.invoker.TestInvocation.performInvocation(TestInvocation.java:304)
at com.android.tradefed.invoker.TestInvocation.invoke(TestInvocation.java:1523)
at com.android.tradefed.command.CommandScheduler$InvocationThread.run(CommandScheduler.java:723)
04-28 16:24:15 E/ModuleDefinition: Some preparation step failed. failing the module armeabi-v7a CtsDisplayTestCases
反复出现 AaptParser 错误,以及 Entry at index 0 is too small (0) 这类解析异常,都是 aapt2 版本不兼容的典型特征。需要下载最新的 aapt2 工具。