Fuchsia 的构建系统会在 build 输出目录(例如 $FUCHSIA_DIR/out/default/tests.json)中的 tests.json 文件中导出有关 build 中包含的所有测试的结构化信息。
Fuchsia 的持续集成基础架构使用 tests.json 来确定要运行哪些测试,并使用 fx test 来确定哪些测试可以在本地运行。tests.json 及其架构是平台 build 和测试的实现细节,不属于 SDK 的一部分。
本文档介绍了该文件的内容以及该文件的生成方式。
生成 tests.json
tests.json 文件在 regenerator.py 中的 gn-gen 之后立即生成。
tests.json 条目的字段是使用 GN 元数据机制收集的。
tests.json 条目通过使用 test_spec GN 模板从 GN 文件注册。
tests.json 由 fx set 自动生成。tests.json 格式受限于可使用 GN 的相对有限的元数据机制从 GN 轻松生成的内容。为了规避这些限制,Fuchsia build 还会生成一个名为 test-list.json 的文件,该文件是通过对 tests.json 进行后处理生成的,如下所述。
tests.json 消费者
各种工具和脚本都会提取 tests.json 文件,因为它是给定 Fuchsia build 的可用测试的规范列表。本部分将介绍该格式最值得注意的消费者。
test_list_tool
test_list_tool 处理 tests.json。
使用规范的测试列表,它会使用包含的软件包清单信息来加载 build 软件包,并使用有关测试应如何执行的信息以及用于进一步分类的标记来注释每个测试。例如,它可以确定测试组件是否以封闭方式运行,并使用 "hermetic":
true 标记测试。
test_list_tool 会将此信息输出到 tests.json 旁边的 test-list.json 文件中,并且会在所有软件包构建完成后作为最后一个构建步骤之一运行。它使用与 tests.json 相同的唯一 name 键,以便匹配条目。
fx search-tests
fx search-tests 脚本可对测试名称进行模糊匹配,以帮助开发者找到可运行的测试。除了通过源代码树搜索未包含的测试之外,它还使用 tests.json 中的值作为模糊匹配的键。
fx test
fx test 命令是面向开发者的入口点,用于测试 Fuchsia 源代码树中的执行。它使用 tests.json 来确定规范的测试集,然后在 test-list.json 和 test_components.json 中查找关联的数据,以确定测试应如何执行。
植物学家 / testsharder
在 Infra 中,testsharder 依赖于 tests.json,以根据环境维度对测试条目进行分片。该流程的输出是另一个包含从 tests.json 派生的字段的文件,然后该文件会传递给运行测试的机器人上的 botanist。
tests.json 结构
tests.json 是一个包含单个数组的 JSON 文件。数组的每个元素都对应于 build 中的单个测试目标条目。
测试目标条目有两个顶级字段,environments 和 test 分别对应于测试环境和测试信息。
字段
environments 字段
environments 字段是测试环境条目的数组。每个“测试环境”条目都指定了测试可能在其中运行的单个环境,并且 testsharder 会使用此字段在设备配置之间对测试进行分片。
每个“测试环境”条目都有一个字段 dimensions,其中包含任意数量的维度。不过,通常有两组最常见的字段:
device_type- 指定测试所需的设备类型。 例如:"environments": [ { "dimensions": { "device_type": "QEMU" } } ]这表示可以在 QEMU 设备配置上运行的测试。 注意:这并不意味着测试会在任何 QEMU 设备上运行,而是意味着测试会在基于
botanist所用配置的 QEMU 实例上运行。cpu和os- 指定主机测试所需的 CPU 架构和操作系统。例如:"environments": [ { "dimensions": { "cpu": "x64", "os": "Linux" } } ]这指定了一项可在 x64 Linux 系统上运行的测试。
tags- 指定分片的其他属性。例如:"environments": [ { "tags": [ "e2e-isolated" ] } ]这指定了带有“e2e-isolated”标记的测试。
除非 build 配置专门选择运行带有环境标记的测试,否则带有环境标记的测试不会在持续集成 build 中运行,在这种情况下,仅会运行带有该标记的测试。
测试字段
test 字段提供有关如何对测试进行分类、运行和配置的信息。fx test 和 botanist 等测试执行器会使用此数据来确定要执行测试的正确二进制文件和命令行。它还包含对其他工具集成有用的信息,例如,用于在测试调用之间重建测试目标。
测试一般分为两种类型:主机测试和设备测试。主机测试是指在主机系统上运行以执行测试的二进制文件路径。设备测试是指使用 Test Manager 在目标系统上运行的组件网址。
有些主机测试需要 Fuchsia 设备,有些则不需要。端到端测试 (E2E) 具有非“fuchsia”的 os,但在其 environments 中仍指定了 device_type。
test 对象包含以下字段,按测试类型划分:
所有测试
name- 测试的名称。此值在tests.json中是唯一的。 通常包含设备测试的测试组件网址,以及主机测试的测试二进制文件相对于输出目录的路径。cpu- 测试运行所用的 CPU 架构。与主机测试的environments条目冗余,但对于设备测试,这是此信息的唯一来源。os- 测试所运行的操作系统。与主机测试的environments条目冗余,但对于设备测试,这是唯一的信息来源。botanist使用此字段来确定测试应作为宿主机上的子进程运行,还是通过 SSH 在目标设备上运行。label- 生成相应测试条目的 GN 标签。用于在从fx test执行测试时确定要重新构建哪些目标,但仅适用于此标签实际输出真实测试二进制文件的宿主测试。其他类型的测试使用不同的标签字段,例如package_label。source_label- 与测试对应的构建系统无关(GN 或 Bazel)标签。用于确定测试的源代码位置,以确定所有权和其他元数据。
仅限主机测试
path- 测试二进制文件的路径(相对于输出目录)。仅针对主持人测试显示。runtime_deps- JSON 文件的路径(相对于输出目录),该文件包含文件路径(相对于输出目录)的列表,这些文件应放置在主机测试已知的位置,以便在运行时使用。该文件的格式为文件路径字符串的 JSON 数组。list_cases_argument-(可选)用于列出测试套件中各个测试用例的命令行实参。fx test --list使用此属性来发现用于报告和选择的特定测试用例。目前,此功能仅支持主机测试,具体而言,仅支持 Mobly 测试和 Python 单元测试。
仅限设备测试
has_generated_manifest- 如果这是清单由 GN 规则生成的测试组件,则为 True;如果测试是主机测试,则省略;否则为 False。用于测试分类和跟踪使用自定义清单的测试。build_rule- 由 build 生成,用于进一步的测试分类。 例如,了解测试是由fuchsia_unittest_package规则还是fuchsia_test_package规则创建的,具有实际意义。log_settings- 可能包含以下字段的字典:max_severity- 此字段会替换测试的默认最高日志严重程度。默认情况下,发出 ERROR 日志的测试会失败,但此字段会指示测试执行器以不同日志级别会导致失败的模式运行。min_severity- 用于指示测试组件以该级别而非默认级别发出日志。默认情况下,测试会选择自己的最低日志严重程度。
package_label- 生成相应软件包(包含此测试)的 GN 标签。仅在设备测试中存在。由fx test使用,用于在运行包含测试的软件包之前重建这些软件包。component_label- 为此测试生成测试组件的 GN 标签。用于在fx search-tests中找不到匹配的测试时,对测试名称进行模糊匹配(除了所有其他标签字段之外)。仅在设备测试中存在。package_manifests- 用于构建测试软件包的每个软件包清单的路径列表(相对于输出目录)。 用于确定在fx test中构建测试后要重新发布哪些软件包。仅在设备测试中存在。package_url- 与此测试对应的测试组件网址。 这是请求测试管理器执行的网址,用于设备测试。parallel- 替换默认测试运行程序并行性(以整数形式)。通常用于指示测试执行器告知ffx test不要并行运行存在串扰的测试的测试用例。将此值设置为1会停用并行测试用例执行,而数字> 1会强制执行并行测试用例(如果单个测试运行程序支持)。
示例
主机测试
[
{
"environments": [
{
// This test runs on the infra shard for Linux x64.
"dimensions": {
"cpu": "x64",
"os": "Linux"
}
}
],
"test": {
"cpu": "x64",
"label": "//src/performance/trace2json:trace2json_tests(//build/toolchain:host_x64)",
"source_label": "//src/performance/trace2json:trace2json_tests",
"name": "host_x64/trace2json_tests",
"os": "linux",
// This is the path to execute the test both locally and in infra.
"path": "host_x64/trace2json_tests",
// The deps listed in this file must be placed in a known
// location for the test.
"runtime_deps": "host_x64/gen/src/performance/trace2json/trace2json_tests.deps.json"
}
}
]
设备测试
[
{
"environments": [
// This test runs on the AEMU shard in infra.
{
"dimensions": {
"device_type": "AEMU"
}
}
],
"test": {
// This test was created using fuchsia_unittest_package
"build_rule": "fuchsia_unittest_package",
"component_label": "//src/diagnostics/lib/sampler-config:sampler-config-tests_component(//build/toolchain/fuchsia:x64)",
"cpu": "x64",
// This test specified its own manifest.
"has_generated_manifest": false,
"label": "//src/diagnostics/lib/sampler-config:sampler-config-tests_test_sampler-config-tests_component(//build/toolchain/fuchsia:x64)",
"source_label": "//src/diagnostics/lib/sampler-config:sampler-config-tests_test_sampler-config-tests_component",
"log_settings": {
// Any ERROR or FATAL logs will force this test to fail.
"max_severity": "WARN"
},
"name": "fuchsia-pkg://fuchsia.com/sampler-config-tests#meta/sampler-config-tests.cm",
"os": "fuchsia",
"package_label": "//src/diagnostics/lib/sampler-config:sampler-config-tests(//build/toolchain/fuchsia:x64)",
// These manifests can be used for deep inspection of the
// contents of this test.
"package_manifests": [
"obj/src/diagnostics/lib/sampler-config/sampler-config-tests/package_manifest.json"
],
"package_url": "fuchsia-pkg://fuchsia.com/sampler-config-tests#meta/sampler-config-tests.cm"
}
}
]