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

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

针对 Fuchsia (CTF) 兼容性测试的要求、目标和上下文。

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

总结

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

在本文档中,我们将 API 和 ABI 统称为平台 Surface 区域平台 Surface 区域元素是与平台 Surface 区域相关联的已命名且有版本控制的标识符(例如方法名称)。日后的 RFC 可能会将这些定义正式化。

设计初衷

目前,针对 Fuchsia 平台行为的所有开源测试都是(2020 年 12 月)作为平台 build 的一部分构建并运行的。随着平台的发展,我们会不断推行测试。因此,我们没有可保证与旧版平台向后兼容的测试。

目前,我们通过多项产品测试来确保兼容性和稳定性。这些产品测试很难进行分类:因为它们依赖于产品的稳定性,并且针对平台的许多不同部分,因此平台工程师很难确定 bug 可能在哪里出现。

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

在我们发布 API 破坏性更改时,我们没有采取任何保护措施来在破坏与最终开发者代码的兼容性时引发标志。在项目期间,未记录的 API 更改经常发布,会导致外部代码停止构建。

此外,我们目前正针对向后兼容的 ABI 兼容性提供强有力的保证。自 2020 年 11 月 9 日起,我们要求有六周的 ABI 兼容性期限,但没有相应的强制执行机制。

我们需要一组可独立于平台 build 执行的测试,以便清楚地识别我们何时违反与最终开发者的合同。这有助于确保我们保持与外部开发的代码的兼容性,并为当前仅由产品测试执行的平台部分提供更容易分类的有针对性的测试覆盖范围。

从长远来看,我们还将需要一套测试,系统集成商可以通过执行这些测试来了解其是否生成了合规的 Fuchsia 实现。

Fuchsia 的 CTF 将提供一种测试平台实现的方法,以确保这些实现与特定平台版本(如 RFC-0002 中所定义)兼容。我们渴望在平台界面区域中对记录的每个行为进行测试。

创建版本时,我们可以使用 CTF 告知我们其 Surface 区域与其他发布版本的兼容性。

如果有人正在开发运行 Fuchsia 的设备,并希望了解它是否与指定 SDK 兼容,他们可以使用 CTF 以及希望证明其兼容性的 SDK,通过测试,并确信其产品正确实现了 Fuchsia 的语义 - 这将是“Fuchsia 兼容”。

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

RFC-0002 可让平台实现为向后兼容性提供部分支持。CTF 将提供了一种用于测试部分兼容性的方法。

请注意,CTF 并不作为平台演进和向后兼容性的完整解决方案。CTF 测试不太可能涵盖所有最后一个用例。API 和 ABI 的设计仍然必须考虑未来的用例。如需进一步的讨论,请参阅有关缺点和替代方案的部分。

设计

CTF 设计涉及到在开发难易程度与在 Fuchsia 代码库之外构建和运行 CTF 本身的需求之间取得平衡。具体要求如下:

  1. 对于每个平台表面区域元素记录的每个行为,都应该进行一项 CTF 测试。虽然我们希望这最终会成为一项硬性要求,但此 RFC 并未指定此类要求。

  2. CTF 测试不得依赖于特定系统映像的任何内部详细信息。如果它们依赖于本身不需要测试的其他平台代码,则必须将这些代码捆绑到 CTF 中,并且不要依赖于特定系统映像的任何内部细节。

  3. 在添加或更改平台 Surface 区域的元素时,开发者必须更新 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 平台表面区域元素的所有更新都应包含执行所述记录表面的测试。这包括但不限于 C/C++ 头文件、FIDL API、FIDL 有线格式,以及 Fuchsia 系统接口文档中所述的任何 surface。如果开发者可以通过 SDK 访问 Surface 区域元素,则必须对其进行测试。

我们知道,此时要求进行测试可能不现实。随着 CTF 和平台的发展,我们预计这项要求会变得更加严格。

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

所有测试都要符合与提交到树状结构的任何其他代码相同的审核要求。请注意,这并不意味着必须将测试作为提交队列的一部分运行,但我们希望大多数测试都会作为提交队列的一部分运行。不适合作为提交队列一部分运行的测试示例包括手动测试以及用时超过提交队列允许时间的测试。

目录结构

//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 开发者不清楚放置测试的位置,应咨询相关目录的所有者。

构建支持

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

您可以在 //sdk/ctf/build/allowed_ctf_deps.gni 中找到非 SDK 代码的许可名单。如果测试作者认为他们需要将其他纳入自己的内容,则应与此目录的所有者联系。

语言

目标端测试

所有 API 测试都必须使用所测试的 SDK 支持的语言编写。在大多数情况下,这意味着使用 C++ 编写 ABI。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 方法并断言返回值正确无误。

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

测试应反映有关使用给定 API 的最佳实践。通俗来说,如果最终开发者复制测试对 API 的使用情况,则测试作者会认为开发者对 API 的使用是正确的。测试应尽可能不依赖于未记录的、特定于应用的不变量。将来,在紫红色树之外广泛使用未载明的行为时,我们可能需要针对不遵循推荐用法的用例添加测试。

测试应尽可能避免为目标设备的内部状态创建测试替身(例如模拟和虚假对象)。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 关联的更改仅供测试,因此隐私权风险较低。测试不应与用户数据交互。

测试

此方案将增加平台的测试矩阵。例如,假设有六周的 ABI 稳定性保证,在给定 build 比给定 build 提前六周生成的 CTF 中生成的所有 ABI 测试都应对该 build 运行并成功完成。

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

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

文档

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

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

该方案的主要缺点是,它会为平台界面区域的所有更改设定了新的重要测试要求。

CTF 致力于提供针对演化和向后兼容性问题的完整解决方案,而不是这样做。必须谨慎设计 API 和 ABI,以确保开发者能够以合理的费用迁移其代码。例如,FIDL 团队在改进语言绑定时非常谨慎:他们明确规范绑定的运作方式,并积极跟踪各种绑定的符合程度

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

  • 只是小心谨慎。根据经验,我们知道这无法自行运作。
  • 不是为了改进平台。显然,只是不进行更改是不切实际的。这种技术的大多数缩小版本(例如,交付应用的大部分依赖项,或为每个应用提供虚拟环境)都与 Fuchsia 的设计原则和产品目标不符。
  • 正式验证。我们认为正式验证不是测试的可扩缩替代方案。

早期技术和参考资料

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

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