树外组件测试支持

  • 项目负责人: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(尽管 Rust 在树内组件开发中很受欢迎)。

  • 对会增加测试价值的其他插桩(例如排错程序覆盖率)的支持不一致。

  • 某些工具和源代码并非通过 Fuchsia IDK(即 SDK 工具集)分发给合作伙伴。例如,系统会手动将 TestWithEnvironment 帮助程序类复制到 GitHub 上的 Flutter 代码库,以满足集成测试需求。

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

现在,我们获得了广泛的经验和观察结果,并据此制定如何创建更通用的测试解决方案。是时候获取这些数据洞见并为这些用例构建平台支持,从而打造功能更强大的 SDK,并减少和移除具有固定维护费用但价值主张不断减少的定制解决方案。

用于测试的平台/基础架构 surface

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

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

有多个当前和即将推出的项目预计会扩大以 Fuchsia 为目标的树外开发和测试范围。这些文件包括:

  • 兼容性测试套件 (CTS) 测试可以在 Fuchsia 的树内构建和测试系统之外运行,但其源代码将托管在 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 支持,以便通过串行连接运行 Bringup 测试。结果是,我们可以利用现有的丰富且稳健的树内测试语料库和树内自动化,持续验证我们在树内和树外用例之间可移植的现代工具的工作。

我们会将使用排错程序测试覆盖率的各个方面从仅在树内可用的工具(如 tefmocheckcovargs)移植到 ffx 插件中。

目标端

我们将发展测试运行程序框架 (TRF),以满足树外测试的需求。

TRF 包含一个设备端 Overnet 守护程序、一个用于管理/安排测试的组件、一个用于封闭测试的独立领域、一系列支持各种语言和框架的测试运行程序,以及用于连接上述所有项的 FIDL 协议。TRF 支持树内和树外测试工作流。它取代了只能在树内运行且仅支持 CFv1 组件的测试运行时。

到目前为止,TRF 的优先客户一直是树内测试,其成功与否取决于在 TRF 上运行的测试部分。在编写时,超过 70% 的 Fuchsia 树内测试已迁移到 TRF,而现代 (CFv2) 测试仅在 TRF 上运行。由于即将推出兼容性层,我们预计其余所有测试(ZBI 测试除外)到 2021 年底都能在 TRF 下运行。

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

为了提升开发者体验,树外开发者将能够添加 SDK 中的测试运行程序。通过这种机制,树外开发者将可以访问现有的测试运行程序目录(gtestrustGo 和任意 ELF 二进制文件),以及即将推出的 Dart 和 Flutter 测试运行程序。TRF 还将为开发更高级的测试策略(例如压力测试CTS 测试)奠定基础。这些测试策略将表示为运行程序,SDK 中也可能会提供这些测试程序。

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

测试执行控制

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

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

新协议有助于更好地分层和分离关注点。例如,主机端负责选择测试并请求在目标上执行。目标端测试管理器负责实际运行测试,而在旧版系统中,主机工具会在目标设备上单独手动执行每个测试。而通过并行执行测试作业以最大限度地提高资源利用率,则由目标转移给目标,后者能够更好地处理这种责任。

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

测试结果

测试结果将不再受限于套件级别的通过/失败结果,而是将以结构化格式详细说明枚举。在测试期间收集的诊断信息(例如在测试期间从测试领域获取的日志)将按照与生成这些诊断信息的测试相关联的方式进行组织。将对来自测试的其他工件(例如测试运行时期间收集的配置文件)或大型测试输出(例如在测试期间截取的屏幕截图)提供标准支持。结果格式的架构将在 SDK 中发布,以便支持树外工具的处理。

文档

我们会审核、修改并简化诸如此处的开发者指南,以便对树外的开发者有用。树内测试工作流和树外测试工作流将保持统一,这样这些指南就不会包含特定于 Fuchsia 树内/树外开发者的信息,也不会针对此类不同的目标设备单独提供不同的部分。

我们将编写一份新的新手入门指南,详细说明“测试历程”。 本指南将为需要确保通过单元测试和集成测试正确测试其代码的开发者提供一个入口点。本指南的目标是:1) 帮助开发者正确选择要编写哪种类型的测试,并 2) 快速让开发者做好准备,使他们的测试能够利用更高级的测试策略(例如 CTS压力测试)。

虚拟化支持

虚拟目标(例如模拟器)对于测试非常有用且广受欢迎。Fuchsia 目前支持下载经过测试可与 Fuchsia 搭配使用的 qemu 发行版。不过,还有一些其他工具可用于处理虚拟化目标,例如 fx qemufx gce,这些工具仅在树内提供。

我们将映射在虚拟化目标上运行 Fuchsia 的树内和树外支持之间的差距,并根据需要予以解决,以缩小测试工作流差距。

依赖项

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

风险和缓解措施

不适用

不在范围内

端到端测试(也称为系统测试)

此方案侧重于组件测试,这种测试采用对单个组件进行单元测试或跨越多个组件的集成测试的形式。系统测试也称为端到端(或 e2e)测试,不会测试特定的组件实例,而是测试整个被测系统。因此,它们与组件测试在很多方面都有所不同,例如开发者需求和用例,以及平台在 e2e 测试之间隔离的能力。

e2e 测试当前的热门解决方案是 SL4F(适用于 Fuchsia 的脚本层)。该实现包括一个目标端守护程序(包含在某些 Fuchsia 映像中,可执行一组规定的系统自动化任务)以及一个用 Dart 编写的客户端库(可在 Fuchsia SDK 中使用)。

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

扩大端到端测试开发规模的当前挑战包括:

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

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

  • 仅提供 Dart 客户端库。

由于系统测试与组件测试截然不同,因此本主题将在单独的路线图文档中进行介绍。