Android VTS测试实践

Android VTS测试实践记录
Views: 289
1 0
Read Time:2 Minute, 55 Second

VTS (Vendor Test Suite)由一套测试框架和测试用例组成,目的是提高安卓系统 ( 如核心硬件抽象层HAL和依赖库libraries ) 与底层系统软件(如,内核kernel,模块modules,固件firmware等)的健壮性,可依赖性和依从性。

Google推出VTS的很重要的一点是由于各Soc厂商对于HAL(Hardware Abstract Layer)的实现都是不同的,为了保证Framework乃至App的正常运行,需要确保各个厂商对于HAL的实现满足规范,基于此推出了VTS,同时也设定了相应的流程认证体系来保证各个厂商对于VTS测试的合规性。

VTS有两种测试套件:

1.自动化测试(如record-and-replay and fuzzing)

2.结构化测试(如gtest and host-driven python)

VTS框架和测试用例是为userdebug或者eng版本的设备而设计的,当然其中有些测试用例可以在user版本下执行,此时需要使用相对应的应用软件,也就是VTS Agent APP。在本示例中,以userdebug版本为例,进行自动化测试。

原理简介

VTS的测试原理简单来讲就是通过编写测试代码,从而与硬件HAL程序进行交互,以测试其接口是否能正常工作;这意味着我们需要接入实际的物理硬件,并运行安卓系统,同时确保我们自己实现的HAL程序正常运行。

而各个模块的VTS的测试代码都是分散的,一般我们可以在hardware/interfaces/MODULE_NAME/VERSION/vts/functional/目录下找到对应的测试用例代码。以Camera HAL为例:

root:~/Android12.1/hardware/interfaces/camera/provider/2.4/vts/functional$ ls -lah
total 408K
drwxrwxr-x 2 4.0K Aug 10 10:55 .
drwxrwxr-x 3 4.0K Aug 10 10:55 ..
-rw-rw-r-- 1 2.3K Aug 10 10:55 Android.bp
-rw-rw-r-- 1 1.6K Aug 10 10:55 AndroidTest.xml
-rw-rw-r-- 1 391K Aug 10 10:55 VtsHalCameraProviderV2_4TargetTest.cpp

这里VtsHalCameraProviderV24TargetTest.cpp即是测试代码的源码文件;所有的Test Case都以TEST_P开头,如下所示:

// In case autofocus is supported verify that it can be cancelled.
TEST_P(CameraHidlTest, cancelAutoFocus) {
    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);

    for (const auto& name : cameraDeviceNames) {
        if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) {
            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
            openCameraDevice(name, mProvider, &device1 /*out*/);
            ASSERT_NE(nullptr, device1.get());

            CameraParameters cameraParams;
            getParameters(device1, &cameraParams /*out*/);

            if (Status::OK !=
                isAutoFocusModeAvailable(cameraParams, CameraParameters::FOCUS_MODE_AUTO)) {
                Return<void> ret = device1->close();
                ASSERT_TRUE(ret.isOk());
                continue;
            }

            // It should be fine to call before preview starts.
            ASSERT_EQ(Status::OK, device1->cancelAutoFocus());

            sp<BufferItemConsumer> bufferItemConsumer;
            sp<BufferItemHander> bufferHandler;
            setupPreviewWindow(device1, &bufferItemConsumer /*out*/, &bufferHandler /*out*/);
            startPreview(device1);

            // It should be fine to call after preview starts too.
            Return<Status> returnStatus = device1->cancelAutoFocus();
            ASSERT_TRUE(returnStatus.isOk());
            ASSERT_EQ(Status::OK, returnStatus);

            returnStatus = device1->autoFocus();
            ASSERT_TRUE(returnStatus.isOk());
            ASSERT_EQ(Status::OK, returnStatus);

            returnStatus = device1->cancelAutoFocus();
            ASSERT_TRUE(returnStatus.isOk());
            ASSERT_EQ(Status::OK, returnStatus);

            stopPreviewAndClose(device1);
        }
    }
}

简单看一下这些测试代码,我们会发现大量类似与断言ASSERT的写法,这是VTS测试框架下的测试桩点,如果ASSERT_XX的部分未能达到预期,则会测试失败。

测试步骤

首先我们需要编译测试工具,相关源码已在AOSP源码树中:

1.cd ${AOSP_SRC_TOP_DIR} && source build/envsetup.sh
2.lunch PRODUCT_NAME 
3.make vts -j32 

最终的生成产物位于: ${AOSP_SRC_TOP_DIR}/out/target/${PRODUCT_NAME}/testcases文件夹内;在该目录下我们可以看到每个模块对应的vts测试文件,我们可以将其推入我们的Android环境内手动进行执行;如下所示:

root:/data # ./VtsHalEvsV1_1TargetTest
Running main() from external/googletest/googletest/src/gtest_main.cc
[==========] Running 34 tests from 1 test suite.
[----------] Global test environment set-up.
[----------] 34 tests from PerInstance/EvsHidlTest
[ RUN      ] PerInstance/EvsHidlTest.CameraOpenClean/0_default
……

在完整的测试完成后,会输出总结,包含成功项与失败项,以及失败的具体项目明细;

上述测试流程比较适合每个模块对自己负责的模块进行测试,但是无法或者说不便于一次性对所有的模块进行测试;Google为此也提供了其他更为方便的方式进行测试。

如果我们的编译环境已经接入了Android ADB设备,此时,我们可以在编译环境内直接执行vts-tradefed命令;如果我们的编译环境未接入Android ADB设备,我们可以找到${AOSP_SRC_TOP_DIR}/out/host/linux-x86/cts/android-vts.zip,将其拷贝到其他接入了Android ADB设备的Linux服务器,解压后手动执行vts-tradefed,如下所示:

此时我们会进入一个二级控制台,执行run vts命令即开始vts测试,这时执行的vts将会是全量的,会自动针对每个模块进行测试;如果我们需要执行某个单独的模块,可以使用:run vts -m MODULE_NAME的方式执行单个模块的vts测试,在执行完成之后,我们可以看到具体的执行结果;如下所示:

问题解析

在执行VTS的过程中,我们难免会遇到一些fail项,针对测试失败的测试用例,我们在测试结果中可以看到具体的错误信息,包含行号,期待结果与实际结果等信息,如下所示:

[ RUN      ] PerInstance/EvsHidlTest.CameraOpenClean/0_default
hardware/interfaces/automotive/evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp:317: Failure
Expected: (pCam) != (nullptr), actual: 8-byte object <00-00 00-00 00-00 00-00> vs (nullptr)
[  FAILED  ] PerInstance/EvsHidlTest.CameraOpenClean/0_default, where GetParam() = "default" (3 ms)
[ RUN      ] PerInstance/EvsHidlTest.CameraOpenClean/1_hw_1
hardware/interfaces/automotive/evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp:312: Failure
Expected: (targetCfg.width) > (0), actual: 0 vs 0
[  FAILED  ] PerInstance/EvsHidlTest.CameraOpenClean/1_hw_1, where GetParam() = "hw/1" (1 ms)

如上述的错误显示,在VtsHalEvsV1_1TargetTest.cpp,CameraOpenClean 测试中,以default和hw/1两种硬件状态进行测试,测试执行结果都失败,两者失败的原因都不一样。

前者:具体fail的源码位于 VtsHalEvsV1_1TargetTest.cpp第317行,

Expected: (pCam) != (nullptr), actual: 8-byte object <00-00 00-00 00-00 00-00> vs (nullptr)

后者: 具体fail的源码位于 VtsHalEvsV1_1TargetTest.cpp第312行,

Expected: (targetCfg.width) > (0), actual: 0 vs 0

通过这些错误信息,我们可以直接找到测试代码的位置查看代码执行逻辑,结合HAL日志来进行问题定位。

Happy
Happy
0 %
Sad
Sad
0 %
Excited
Excited
0 %
Sleepy
Sleepy
0 %
Angry
Angry
0 %
Surprise
Surprise
0 %
FranzKafka95
FranzKafka95

极客,文学爱好者。如果你也喜欢我,那你大可不必害羞。

Articles: 78

Leave a Reply

Your email address will not be published. Required fields are marked *

en_USEN