IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    Android VTS测试实践

    FranzKafka95发表于 2023-10-17 14:03:09
    love 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 0 %
    Sad
    Sad
    0 0 %
    Excited
    Excited
    0 0 %
    Sleepy
    Sleepy
    0 0 %
    Angry
    Angry
    0 0 %
    Surprise
    Surprise
    0 0 %

    The post Android VTS测试实践 first appeared on FranzKafka Blog.



沪ICP备19023445号-2号
友情链接