RFC-0015:Fuchsia (CTF) 的兼容性测试

RFC-0015:Fuchsia 的兼容性测试 (CTF)
状态已接受
区域
  • 治理
  • 测试
说明

Fuchsia 兼容性测试 (CTF) 的要求、目标和背景信息。

问题
Gerrit 更改
作者
审核人
提交日期(年-月-日)2020-11-13
审核日期(年-月-日)2020-12-09

摘要

本文档介绍了 Fuchsia 的一组兼容性测试 (CTF) 的要求、设计和实现策略。CTF 将提供一种测试平台实现的方法,以确保其行为符合 Fuchsia 规范。Fuchsia 开发者将编写测试,以确保在对平台的源代码和行为进行更改时保持兼容性。这些测试通过后,将保证特定版本在特定设备上运行时与目标 API 级别和目标 ABI 修订版兼容,如 RFC-0002 中所定义。

在本文档中,我们将 API 和 ABI 统称为平台接口平台 Surface 区域元素是与平台 Surface 区域关联的命名且具有版本号的标识符(例如方法名称)。未来的 RFC 可能会对这些定义进行形式化。

设计初衷

目前(2020 年 12 月),所有针对 Fuchsia 平台行为的开源测试都是在平台 build 的构建和运行过程中完成的。随着平台不断发展,我们会确保测试始终能通过。因此,我们没有任何测试可保证与旧版平台的向后兼容性。

目前,我们会使用多项产品测试来确保兼容性和稳定性。这些产品测试很难分类:由于它们依赖于产品的稳定性,并且定位到平台的许多不同部分,因此平台工程师很难确定 bug 可能出现的位置。

与此同时,开发者还在编写以较低版本的 Fuchsia 平台 Surface 区域为目标平台的代码。在本文档中,我们将此类开发者称为最终开发者

在发布 API 破坏性更改时,我们没有任何保护措施,在与最终开发者的代码不兼容时不会设置标志。在项目的整个生命周期中,未记录的 API 更改经常发布,导致外部代码停止构建。

此外,我们目前正在构建关于向后 ABI 兼容性的强大保证。自 2020 年 11 月 9 日起,我们要求 ABI 兼容性窗口为 6 周,但没有相应的强制执行机制。

我们需要一组可独立于平台 build 执行的测试,以便明确确定何时违反了与最终开发者之间的合同。这有助于确保我们与外部开发的代码保持兼容性,并为目前仅由产品测试执行的平台部分提供更易于分类的目标测试覆盖率。

从长远来看,我们还需要一组系统集成商可以执行的测试,以便了解他们是否正在生成符合要求的 Fuchsia 实现。

Fuchsia 的 CTF 将提供一种测试平台实现的方法,以确保它们与特定平台版本兼容(如 RFC-0002 中所定义)。我们希望针对平台 Surface 区域中记录的每种行为都提供测试。

创建版本时,我们可以使用 CTF 来了解其接口与其他版本的接口之间的兼容性。

当开发者开发搭载 Fuchsia 的设备并希望了解其是否与给定 SDK 兼容时,可以使用 CTF 和要证明兼容性的 SDK,通过测试,并确信其产品正确实现了 Fuchsia 的语义,即“与 Fuchsia 兼容”。

当开发者想要了解如何针对特定 API 编写代码或使用特定 ABI 时,可以将这些测试用作参考。

RFC-0002 允许平台实现对向后兼容性提供部分支持。CTF 将提供一种测试部分兼容性的方法。

请注意,CTF 并非用于解决平台演变和向后兼容性的完整解决方案。CTF 测试不太可能涵盖所有最终用例。设计 API 和 ABI 时仍需考虑未来的用例。如需了解详情,请参阅缺点和替代方案部分。

设计

CTF 设计需要平衡开发难易性与在 Fuchsia 代码库之外构建和运行 CTF 本身的需求。具体要求如下:

  1. 每个平台 Surface Area 元素的每项记录行为都应有 CTF 测试。虽然我们预计这最终会成为一项硬性要求,但本 RFC 并未指定此类要求。

  2. CTF 测试不得依赖于特定系统映像的任何内部详细信息。如果这些测试依赖于本身不受测试的其他平台代码,则该代码必须作为 CTF 的一部分捆绑在一起,并且不得依赖于特定系统映像的任何内部详细信息。

  3. 添加或更改平台界面元素时,开发者必须更新 CTF 测试(即必须添加或修改测试)。

  4. 必须能够确定给定 CTF 工件定位到的 Fuchsia 的 API 级别和 ABI 修订版。

  5. 未作为预构建工件包含在测试套件中的 CTF 测试必须使用用于测试的 SDK 支持的语言编写(如需了解详情,请参阅支持的语言文档以及下文的语言部分)。

编写测试

我们会开发 CTF 测试及其对应的 SDK 元素。目前,这意味着我们在 fuchsia.git 中开发测试。虽然如果 CTF 开发者能获得与使用 SDK 的外部开发者相同的体验,那就太好了,但树内开发有太多优势,无法忽视:

  1. 由于功能开发与测试开发同时进行,因此在树中开发测试将允许测试作者使用他们熟悉的工作流,并在与功能相同的 CL 中提交测试。

  2. 由于功能将与测试同时提交,因此无需任何机制来使 CTF 与其符合条件的版本保持一致。

CTF 测试将使用构建时强制执行,以确保 CTF 测试只能依赖于 SDK 元素或其他预先批准的 CTF 代码。在树中开发的一个危险性在于,我们可能会意外依赖于未通过 SDK 公开的平台实现细节。CTF 测试只能访问平台的公开元素,以免意外依赖于实现细节。CTF 测试可以使用适合编写测试的平台代码(例如 zxtest);此类代码将作为 CTF 工件中的一部分提供。

CTF 测试不得依赖于依赖于 SDK 来提供 Fuchsia 支持的第三方库。需要 SDK 元素支持 Fuchsia 的第三方库将针对特定 SDK 进行构建。我们必须确保我们的测试与任何其他人的 SDK 依赖项尽可能解耦,因为第三方代码可能依赖于我们需要从测试中排除的平台功能。例如,如果我们依赖于大量使用锁定的测试套件,则可能不适合用于测试用于实现锁定的 Zircon 功能。鉴于此限制,我们将使用 zxtest,而不是 gtest。

包含与给定 SDK 相关的 CTF 测试的工件将与该 SDK 一起发布。此工件还将包含足以在树外构建和运行 CTF 测试的构建系统支持。其中不会包含工具链。

测试必须全面测试语言支持。如需了解详情,请参阅语言支持部分。

实现

覆盖范围要求

对 Fuchsia 平台 Surface Area 元素的所有更新都应包含用于运行记录的 Surface 的测试。这包括但不限于 C/C++ 头文件、FIDL API、FIDL 线格格式,以及 Fuchsia 系统接口文档中描述的任何 Surface。如果开发者可以通过 SDK 访问途径区域元素,则必须对其进行测试。

我们知道,目前要求进行测试可能不切实际。随着 CTF 和平台的发展壮大,我们预计这项要求会更加严格。

几乎所有需要 API 审核的更改都应进行 CTF 测试,API 审核人员在审核时应将这一点考虑在内。最终审核将由可测试性审核员进行,他们应仅在 CTF 测试适当涵盖平台外露区域更改的情况下批准这些更改。

所有测试都必须遵循与提交到树中的任何其他代码相同的审核要求。请注意,这并不意味着测试必须作为提交队列的一部分运行,但我们预计大多数测试都会这样运行。可能不会作为提交队列的一部分运行的测试示例包括手动测试和耗时超过提交队列允许时间的测试。

目录结构

//sdk/ctf/tests 目录的结构与已发布 SDK 的结构一致。测试位于与 SDK 中要测试的接口所在的目录对应的目录中。例如:

  • 主机工具的测试应放在 //sdk/ctf/tests/tools
  • FIDL 接口的测试应放在 //sdk/ctf/tests/fidl 的适当子目录中。例如,fuchsia.sysmem 的测试应放在 //sdk/ctf/tests/fidl/fuchsia.sysmem 中。
  • 库的测试应放在 //sdk/ctf/tests/pkg 的适当子目录中。例如,async-loop 的测试应放在 //sdk/ctf/tests/pkg/async-loop 中。

如果 Fuchsia 开发者不清楚将测试放置在何处,则应咨询相关目录的 OWNERS。

构建支持

CTF 会测试通过外部可用的 SDK 提供的目标 API 和 ABI。build 支持可确保测试仅依赖于通过 SDK 提供或列入 CTF 许可名单的 API 元素。所有未列入许可名单的 build 目标都必须使用 //sdk/ctf/build 中找到的 cts_ 规则变体,而不是标准的 fuchsia.git 规则(即使用 ctf_fuchsia_componentctf_executable 等)。

您可以在 //sdk/ctf/build/allowed_ctf_deps.gni 中找到非 SDK 代码的许可名单。如果测试作者认为需要额外添加内容,应与此目录的 OWNERS 联系。

语言

目标端测试

所有 API 测试都必须使用所测试 SDK 支持的语言编写。在大多数情况下,这意味着 C++。ABI 测试可以用任何语言编写;为了避免必须为我们不通过 SDK 支持的语言构建外部支持,如果 ABI 测试需要使用其他语言,我们将其作为预构建二进制文件或软件包(以较为合适的方式)包含在内。

针对特定标头的测试必须使用支持该标头的语言编写。在撰写本文时,C 头文件以 C11、C++11 及更高版本为目标平台,C++ 头文件以 C++14 及更高版本为目标平台。

CTF 测试可能仅限于特定语言版本。例如,我们可能会决定将特定测试限制为仅使用 C++14,以确保头文件保持 C++14 兼容性。

主机端测试

目标端测试的语言限制不适用于主机端测试。主机端测试的语言因测试而异。如果需要 CTF 依赖于新的工具链,则应在咨询 CTF 团队后做出决定。对于在宿主上运行的端到端测试和脚本,截至本文撰写之时,我们支持使用 Dart(尤其是 sl4f)。随着支持的语言发生变化,我们会提供文档,说明宿主端测试支持哪些语言。

测试要求

测试应包含针对特定 API 或 ABI 的每个记录断言的检查。例如,如果我们有一个类 fit::basic_string_view,并且它有一个方法 size,该方法记录为返回 string_view 的大小,那么我们可以创建一个测试来创建 string_view、调用 size 方法,并断言返回值正确无误。

我们知道,在某些情况下,这可能很难做到,并且某些测试可能需要特定的设备设置,而这些设置可能很难复制。我们建议开发者在开发周期的早期就开始进行测试。我们的长期目标是,要求对平台 Surface 区域的所有更改都进行 CTF 测试。

测试应反映有关给定 API 使用方式的最佳实践。非正式地讲,如果最终开发者复制了测试对 API 的使用方式,测试作者会认为该开发者正确使用了 API。测试应尽可能不依赖于未记录的应用专用不变量。将来,如果在 Fuchsia 树之外广泛使用未记录的行为,我们可能需要针对不遵循建议用法的用例添加测试。

测试应尽可能避免为目标设备的内部状态创建测试双胞胎(例如模拟对象和虚构对象)。CTF 的目的是确保整个设备正常运行,而不是确保特定组件单独运行正常。

不过,这并不意味着在某些环境中 CTF 测试无法从虚构数据中受益。例如,为了使用 CTF 测试来确保平台稳定性,我们可能会发现,在没有这些功能的自动化环境中运行需要使用真实硬件或手动输入的测试(例如音频或连接性测试)会很有用。虽然 CTF 测试本身应避免使用测试双重,但被测设备可以使用用于向测试提供虚假数据的虚假驱动程序。在使用真实硬件不切实际的情况下,CTF 测试可以依赖于此类驱动程序。

此外,CTF 测试应彼此隔离。如果某个测试失败,或者被测系统的一个方面出现异常行为,理想情况下,此失败应该是局部的,而不是影响其他测试。测试之间缺乏隔离有时也称为“测试串扰”。例如,假设有一个测试会更改设备设置组件中的全局状态。如果测试在终止之前未能恢复原始状态,或者系统上的其他组件在测试执行期间更改了全局状态,则可能会发生串扰。为了隔离此类测试,测试作者可以考虑为本地范围的设置创建功能,而不是修改全局状态。

如有必要,测试可能需要人工干预才能通过。我们建议开发者彻底调查自动化操作的可能性。

部署

CTF 工件将与包含相关平台 Surface 元素的 SDK 工件一起生成。由于 RFC-0002 的软过渡要求,我们希望每个 SDK build 都能成功执行与同一 SDK 的先前 build 关联的 CTF。作为概念验证,我们将实现基础架构来保证这一点。

CTF 工件将包含 gn 的测试框架和构建规则。它们不会包含构建系统或工具链;必须在测试执行环境中提供这些内容。我们将记录已知与给定 CTF 兼容的工具链。

示例

您可以在 fuchsia.git 的 //sdk/ctf/ 中找到测试示例。

性能

此项变更将产生以下性能影响:

  • 由于测试数量增加,运行所有平台测试所需的时间增加。
  • 对生产环境性能没有影响,因为这些更改仅用于测试。

安全注意事项

由于与此 RFC 相关的更改仅用于测试,因此安全风险较低。测试不应与来自外部来源的不受信任数据进行交互。

隐私注意事项

由于与此 RFC 相关的更改仅用于测试,因此隐私风险较低。测试不应与用户数据互动。

测试

此提案将增加平台的测试矩阵。例如,鉴于 6 周的 ABI 稳定性保证,对于给定 build 而言,CTF 中生成的所有 ABI 测试都应针对该 build 运行并成功完成,且生成时间应早于该 build 的 6 周。

此提案中新的要求还会增加平台测试的总数量。

系统会尽可能自动强制执行测试框架的许多必需属性;例如,该框架会自动检查是否仅包含允许的依赖项。

文档

//docs 中将包含有关如何编写 CTF 测试的文档。可测试性和 API 流程文档将更新,以反映新的 CTF 测试作者身份要求。我们将记录在树外运行 CTF 所需的步骤,以便最终开发者和系统集成商能够独立完成这些步骤。

缺点、替代方案和未知情况

此方案的主要缺点是,它会对平台界面中的所有更改提出新的重大测试要求。

CTF 工作组的目标不是为演变和向后兼容性问题提供完整的解决方案。必须精心设计 API 和 ABI,以确保开发者能够以合理的成本迁移其代码。例如,FIDL 团队会非常谨慎地改进语言绑定:他们制定了有关绑定应如何运作的明确规范,并积极跟踪各种绑定的一致性

CTF 方法是保持向后兼容性的标准业界方法。其他方法包括:

  • 只是要小心。我们从经验上知道,这本身并不起作用。
  • 不改进平台。显然,永远不进行更改是不可行的。大多数缩减版(例如,随应用一起提供应用的大部分依赖项,或为每个应用提供虚拟环境)与 Fuchsia 的设计原则和产品目标不符。
  • 形式验证。我们不认为正式验证是可扩展的测试替代方案。

在先技术和参考文档

Android 通过在其产品中发布 CTF 来解决此问题。新 Android 设备的开发者必须确保其设备通过了 CTF 测试。

作为其 Windows 硬件兼容性计划的一部分,Microsoft 会制作 Windows 硬件实验室套件,并将其分发给开发新 Windows 硬件的开发者。