树外组件测试支持

  • 项目负责人:shayba@google.com、crjohns@google.com
  • 地区:测试

问题陈述

缺少用于测试的平台界面

以 Fuchsia 为目标的软件开发者可以编写组件构建组件测试组件。不过,这些关键的开发者使用流程仅针对树内开发者进行了全面且持续的测试,而未针对树外开发者进行测试。

目前,有多个团队在树外开发和测试组件。我们有时会将这些团队称为“合作伙伴”,因为 Fuchsia 团队与他们保持着密切的互动。这种安排的维护成本很高,并且无法扩展,原因如下:

  • 树外测试依赖于已弃用的平台功能、协议和工具。最值得注意的是:使用 SSH 协议在目标上发出命令(例如使用 fx shellfssh)、dash 作为系统接口、fx log 在测试期间收集系统范围的日志,以及使用 SCP 协议(例如使用 fx scp)在全局可变文件系统上收集其他测试制品作为副作用。这些协议会产生不可靠的行为,导致测试不稳定,难以排查问题,这至少可以部分归因于基于文本的协议的脆弱性。此外,传输仅适用于单个字符流,非常适合系统级日志(例如串行日志或 syslog),但不适合多个日志流或大型二进制制品,例如测试中的状态转储和屏幕截图。

  • 各种基于文本的协议,缺乏确保 ABI 稳定性或协调 ABI 演变的方法和实践。

  • 以旧版组件(即 CFv1)形式编写的测试隔离程度较低,更容易出现不确定性,并且无法受益于新测试工具

  • 用于定义测试并捕获其结果和相关诊断信息的自定义且不一致的规则和脚本。

  • 对各种测试框架的支持不一致。例如,虽然所有树外合作伙伴都支持 C++ 和 GoogleTest,但只有部分合作伙伴支持 Dart,而尽管 Rust 在树内组件开发中很受欢迎,但没有合作伙伴支持 Rust。

  • 对可为测试增加更多价值的其他插桩(例如 sanitizer覆盖率)的支持不一致。

  • 部分工具和源代码通过 Fuchsia IDK(一套 SDK 工具)分发给合作伙伴。例如,TestWithEnvironment 辅助类是手动复制到 GitHub 上的 Flutter 代码库,以满足集成测试需求。

为了克服这些问题,Fuchsia 团队已向主要合作伙伴提供专门的支持。这种安排通常会产生量身定制的解决方案,但这些解决方案无法在不同客户之间移植。此外,客户问题支持通常在客户的源代码库中进行,这可能对客户来说很方便,但无法扩展到支持一般的开发者受众群体。

现在,我们从实际应用中获得了广泛的经验和观察结果,可据此了解如何创建更通用的测试解决方案。现在正是利用这些数据洞见来构建对这些使用情形的平台支持的好时机,这样不仅可以创建功能更强大的 SDK,还可以减少和移除那些维护成本固定但价值主张不断缩减的定制解决方案。

用于测试的平台/基础设施界面

Fuchsia 的内部测试基础设施(简称“infra”)也存在上述大部分问题,并且受到的影响与 Fuchsia 合作伙伴类似。由于 Fuchsia 的基础架构不会持续运行平台解决方案和 SDK 工具进行测试,因此错失了持续保证上述解决方案和工具质量的机会。

对树外测试的需求日益增长

目前和即将开展的多个项目预计会扩大针对 Fuchsia 的树外开发和测试范围。其中包括:

  • 兼容性测试套件 (CTS) 测试将能够在 Fuchsia 的树内 build 和测试系统之外运行,不过其源代码将托管在 fuchsia.git 上。

  • Flutter-on-Fuchsia Velocity 旨在构建和测试 Fuchsia 上的 Flutter 嵌入器以及用于组件及其测试的树外 Flutter 运行程序,同时至少将一些集成测试上游化到 Flutter 项目。

  • 驱动程序作为组件将演示如何构建和测试树外驱动程序,以通过驱动程序 ABI 稳定性实现 Fuchsia 上强大的硬件支持。

  • 支持在 LLVMRust 项目中在 Fuchsia 上运行现有测试将需要树外 C++ 和 Rust 测试支持。

目前,这些项目无法成功完成,因为它们依赖于对树外测试的缺失支持。

解决方案陈述

我们将创建一个测试平台解决方案,该解决方案完全基于 Fuchsia SDK 中公开提供的工具和协议。

主机端

我们将使用 FFX 作为树外测试的入口点。我们将完成 ffx test 的开发,以处理测试的所有主机端方面。我们将依赖成熟的 FFX 技术和实践,例如配置管理、目标设备发现和 Overnet 通信套件。

我们将使用 ffx 工具替换现有的主机工具。testrunnerBotanist 等工具目前在 Fuchsia CI/CQ 中执行任务(例如设备发现、设备设置、测试编排、测试工件收集),这些任务可以逐步移交给 ffx。其中一些移交将需要构建等效的 ffx 插件,以实现对等,例如引入 ffx test 支持,以便通过串行连接运行启动测试。这样一来,我们就可以使用现有丰富而强大的树内测试语料库和树内自动化功能,在树内和树外用例之间可移植的现代工具上持续验证我们的工作。

我们将把使用仅在树内提供的工具(例如 tefmocheckcovargs)处理清理器测试覆盖率的各个方面移植到 ffx 插件

目标端

我们将扩展 Test Runner Framework (TRF),以满足树外测试的需求。

TRF 包含设备端 Overnet 守护程序、用于管理/安排测试的组件、用于封闭测试的隔离 realm、支持多种语言和框架的测试运行程序(用于编写测试),以及用于连接上述所有内容的 FIDL 协议。TRF 支持树内和树外测试工作流。它取代了仅在树内工作且仅支持 CFv1 组件的测试运行时。

到目前为止,TRF 的优先客户一直是树内测试,成功与否取决于在 TRF 上运行的测试所占的比例。在撰写本文时,超过 70% 的 Fuchsia 树内测试已迁移到 TRF,现代 (CFv2) 测试完全在 TRF 上运行。到 2021 年底,我们预计除 ZBI 测试之外的所有剩余测试都将在 TRF 下运行,这得益于即将推出的兼容性层。

将所有组件测试迁移到 TRF 后,我们将停用旧版仅限目标平台的树内 v1 测试运行时。这样,我们就可以专注于改进新的测试运行时,这些改进将使树内和树外开发者都能受益。

为了改善开发者体验,树外开发者将能够包含来自 SDK 的测试运行程序。通过此机制,树外开发者将能够访问现有的测试运行程序清单 - gtestrustGo 和任意 ELF 二进制文件 - 以及即将推出的 Dart 和 Flutter 测试运行程序。TRF 还将为开发更高级的测试策略(例如压力测试CTS 测试)奠定基础。这些测试策略将以运行程序的形式表示,这些运行程序也可以在 SDK 中提供。

此外,树外开发者将能够创建和使用自己的测试运行程序。目前认为这是可行的,但尚未得到证实。我们应该创建第一个树外测试运行程序,以便更有把握地介绍此工作流程。

测试作业控制

我们将完成新协议的开发和推出,以控制测试执行。

新协议以 FIDL 形式定义(允许 ABI 稳定性和演变,这对于树外开发至关重要),并由 Overnet 原生承载。新协议不了解 Fuchsia 基础架构,因此可强化所谓的平台/基础架构合同。

新协议可实现更好的分层和关注点分离。例如,主机端负责选择测试并请求在目标设备上执行测试。目标端测试管理器负责实际运行测试,这与旧版系统不同,在旧版系统中,主机工具会在目标设备上手动单独执行每项测试。将并行执行测试以最大限度地利用资源的责任转移到目标,目标更适合承担此责任。

最后,新协议不是基于字符流 (SSH) 的。这样一来,信息就可以双向流动,同时传输多条指令、结果和诊断信息,以及可能采用二进制格式的大型测试输入和输出。

测试结果

测试结果将不再仅限于套件级通过/失败结果,而是会以结构化格式详细列出。在测试期间收集的诊断信息(例如在整个测试期间从测试大区捕获的日志)将以与生成这些诊断信息的测试相关联的方式进行整理。系统将为测试中的其他制品提供标准支持,例如在测试运行时收集的配置文件或大型测试输出(例如在测试期间拍摄的屏幕截图)。结果格式的架构将发布在 SDK 中,以支持通过树外工具进行处理。

文档

我们将审核、修改并简化类开发者指南,使其对树外开发者有用。树内和树外测试工作流将统一,因此这些指南不会包含针对 Fuchsia 树内/树外开发者的特定信息,也不会针对不同的受众群体设置单独的部分。

我们将开发新的初始配置指南,详细介绍“测试之旅”。 本指南将为需要确保其代码通过单元测试和集成测试进行适当测试的开发者提供入门指导。本指南旨在:1) 帮助开发者正确选择要编写的测试类型;2) 帮助开发者快速做好准备,以便利用更高级的测试策略(例如 CTS压力测试)。

虚拟化支持

模拟器等虚拟目标非常有用,也深受测试人员的欢迎。 Fuchsia 目前提供 qemu 分发版下载,该分发版已通过测试,可与 Fuchsia 搭配使用。不过,还有一些用于处理虚拟化目标的额外工具(例如 fx qemufx gce)只能在树内使用。

我们将找出在虚拟化目标上运行 Fuchsia 的树内支持和树外支持之间的差距,并根据需要解决该差距,以弥合测试工作流的缺口。

依赖项

  • FFX 工具和关联的堆栈。
  • Fuchsia IDK 以及树外开发者使用的任何 SDK 前端。
  • 使 RealmBuilder 可在树外使用。
  • 通过 SDK 公开 RealmBuilder。这包括底层协议和至少一个客户端库。
  • 扩展 RealmBuilder 以支持其他语言

风险和缓解措施

不适用

不在范围内

端到端测试(又称系统测试)

此提案侧重于组件测试,即对单个组件进行单元测试或对多个组件进行集成测试。系统测试(也称为端到端 [e2e] 测试)不会测试特定的组件实例,而是测试整个系统。因此,它们在许多方面都不同于组件测试,例如在开发者需求和使用情形方面,以及在平台提供 e2e 测试隔离的能力方面。

目前,端到端测试的热门解决方案是 SL4F (Scripting Layer for Fuchsia)。该实现包括一个包含在某些 Fuchsia 映像中的目标端守护程序,该守护程序可以执行一组已记录的系统自动化任务;还包括一个 用 Dart 编写的客户端库,该库可在 Fuchsia SDK 中使用。

此外,还有一些 CFv1 组件测试也可以说是系统测试。 之所以会发生这种情况,是因为旧版 CFv1 测试运行时允许访问真实系统服务,这是旧版的一种妥协方案,在 CFv2 测试中故意不支持。为便于讨论,我们将此类严格的非密封 CFv1 组件测试也视为系统测试。

目前在扩展端到端测试开发方面面临的挑战包括:

  • 向 SL4F 添加 facade 需要更改平台代码并重新分发 Fuchsia 系统映像。树外开发者无法扩展 SL4F 的功能来自动执行系统操作。

  • SL4F 不依赖于 ffx,而是使用自己的传输层、协议、目标发现和配置。这些差异会增加持续维护成本,并导致开发者体验不一致和摩擦。

  • 仅提供 Dart 客户端库。

由于系统测试与组件测试的差异非常大,因此我们将在单独的路线图文档中介绍此主题。