树外组件测试支持

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

问题陈述

缺少用于测试的平台 Surface

以 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 的内部测试基础架构(也称为“基础架构”)也存在上述大多数问题,并且受到的影响与 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)将使用sanitizer测试覆盖率的部分移植到 ffx 插件

目标端

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

TRF 包括设备端 Overnet 守护程序、用于管理/调度测试的组件、用于进行密封测试的隔离领域、支持各种语言和框架来编写测试的一系列测试运行程序,以及用于连接上述所有内容的 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(适用于 Fuchsia 的脚本层)。该实现包括一些 Fuchsia 映像中包含的目标端守护程序,该守护程序可以执行一组记录在案的系统自动化任务,以及 Fuchsia SDK 中提供的用 Dart 编写的客户端库

此外,存在一些 CFv1 组件测试,可以被视为系统测试。之所以能够这样做,是因为旧版 CFv1 测试运行时允许访问真实的系统服务,这是一种旧版折衷方案,CFv2 测试中故意不支持这种方案。在本讨论中,我们将此类严格非密封 CFv1 组件测试也视为系统测试。

目前,在扩大端到端测试开发规模方面面临的挑战包括:

  • 如需向 SL4F 添加外观,您需要更改平台代码并重新分发 Fuchsia 系统映像。外部开发者无法扩展 SL4F 的功能来实现系统自动化。

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

  • 仅提供 Dart 客户端库。

由于系统测试与组件测试有很大不同,因此我们在单独的路线图文档中介绍了此主题。