RFC-0202:测试管理器即服务

RFC-0202:测试管理器即服务
状态已接受
领域
  • 测试
说明

“测试管理器即服务”的设计。

问题
Gerrit 更改
作者
审核人
提交日期(年-月-日)2022-07-22
审核日期(年-月-日)2022-12-14

摘要

目前,Fuchsia 上的测试会作为 Test Manager 的动态子级执行。 这种设计使测试管理器能够在任何领域(即该产品 所有者有权创建),从而允许测试作者 所需的运行程序和功能,而无需更改测试管理器。

设计初衷

测试管理器将测试作为动态子项启动,并为该测试提供各种 封闭/非封闭功能和树内运行程序。目前的 测试管理器是使用一组静态的内置测试运行程序来运行, 领域。它不允许树外 (OOT) 和树内客户包含 自己的测试运行程序和所需功能,但随着我们获得更多客户, 我们需要为他们的应用场景提供支持。本文档提出了“Test Manager” 即服务”这样,我们的客户就可以在 可能在测试经理的领域之外。这样可以减少 测试经理负责将所需的系统功能路由到 测试。

利益相关方

教员:davemoore@google.com

审核者:geb@google.com、shayba@google.com、richkadel@google.com、 kjharland@google.com、crjohns@google.com、cgonyeo@google.com、 aaronwood@google.com、satsukiu@google.com、xbhatnag@google.com、 yaneury@google.com、hjfreyer@google.com、akbiggs@google.com

已咨询

就功能相关问题咨询了组件框架团队 此设计中使用的路由、框架和测试 API。

社交化

此 RFC 通过了测试架构和 组件框架团队

设计

在此设计中,产品所有者将决定在何处运行测试和测试 执行程序 (ffx test/run-test-suite) 会将必需的信息传递给 测试管理器。我们将在 RunBuilder 协议中添加一个新方法 调用 AddSuiteInRealm 并传入所需的领域信息。

  AddSuiteInRealm(resource struct {
      // The realm which contains the collection to launch the test in
      realm client_end:fuchsia.component.Realm;
      // All offers from the realm to the test collection
      offers: Vec<Capabilities>
      // the test collection to launch the test in.
      test_collection: string

      // ... existing fields from AddSuite
  });

测试管理器会使用上述信息在指定的 使用 Realm Builder 进行收集,同时提供隔离的日志记录器和覆盖率 集合、树内运行程序等,以支持测试执行。组件管理器 会将 LifecycleController 和 RealmQuery 协议(范围为“/”)路由到 测试执行器

测试领域可以由平台本身编写,也可以由产品所有者编写 采用某种现有的/新的机制来应对这种情况。到目前为止,只有平台可以定义 测试领域,并且这项工作旨在促进测试领域的定义普及化 和管理。

此设计假设用户分为两种类型。

  • Test Realm author(测试领域作者):此用户将创建并维护 (他们应有权在 拓扑)。
  • 测试作者:测试的作者,将在 。

Test Realm 作者将创建测试领域,对其进行设置并与 build 集成 供测试作者运行测试的工具。他们需要安装 为此,请在测试领域中进行 Realm Builder 分片

测试领域示例:

{
  include: [
      "sys/component/realm_builder.shard.cml",
  ],
  collections: [
      // The collection to launch test in
      {
          name: "tests",
          environment: "#test_env",
          durability: "transient",
      },
  ],
  offer: [
      {
          protocol: [
              // Some system or mocked protocol
              "fuchsia.foo.bar",
              ...
          ],
          from: "parent",
          to: [
              "#tests",
          ],
      },
      ...
  ],
  environments: [
      {
          name: "test_env",
          extends: "realm",
          runners: [
              // Offer some OOT runner to the test
              {
                  runner: "fuchsia_oot_runner",
                  from: "parent",
              },
              // TODO(https://fxbug.dev/42063673): Abstract out into a shard.
              // This is important so that Realm Builder can work.
              {
                  runner: "realm_builder",
                  from: "#realm_builder_server",
              },
          ],
          resolvers: [
              // This is important so that Realm Builder can work.
              {
                  resolver: "realm_builder_resolver",
                  from: "#realm_builder_server",
                  scheme: "realm-builder",
              },
          ],
      },
  ]
}

Realm 作者将提供与构建工具的集成,以便测试 Executor 可以在执行期间读取标记和测试集合。

人体工程学部分简要介绍了一些需要传入的解决方案 命名器和测试集合名称对测试执行器进行详细讨论 不在本文档的讨论范围内。

测试作者将使用某个人体工程学解决方案 (TBD) 运行测试, 它将向测试执行器传递信息以运行测试。

测试执行器将使用 RealmQuery API 来查询 Realm 对象,并将所有优惠发送到测试收集和传递 使用建议的 AddSuiteInRealm API 将用户发送到 Test Manager。

它还将使用 LifecycleController API 来解析 名称(如果需要的话)。

此设计需要进行以下更改:

  • 将 RealmQuery API 修改为读取“offer”声明。
  • Realm Builder Rust 客户端库将修改为允许构建 一个大区,其中包含提供的 fuchsia.component/Realm 代理。
  • 测试管理器将使用 Realm Builder 库中的新方法启动 测试实例。
  • 测试管理器将使用提供的 offers 并使用 Realm 进行路由 Builder。
  • 测试管理器将设置隔离的日志记录器、调试数据协议、树内功能 运行程序等

测试管理器可以连接到测试领域中的所有功能, 包含组件实例的句柄。

测试管理器将收集所有工件并上传测试结果, 测试结束。测试将有权访问其父级领域的任何功能 以及测试架构提供的所有封闭功能

这种方法的优势

  • 开发者可以自带运行程序。
  • 现在就可以实现。无需等待 功能。

其他福利

  • 开发者可以按照自己的需要配置其测试领域,而无需 核心产品或测试架构所需的更改。
  • 无需支持自定义测试类型。

此解决方案的缺点如下:

  • 开发者可以创建自己的非封闭领域来启动测试, 我们最终可能会进行一大堆非封闭测试 不费吹灰之力即可实现
  • 直接使用“ffx test”的开发者需要提供自己的名字和 向工具添加集合名称
    • ffx 测试是基础工具,因此开发者应使用其他工具 调用 ffx 测试,因此无需手动通过 名称。

测试管理器可以用作 服务。

测试拓扑

实现

  • 通过以下方法更改 Realm Builder 以允许其在任意领域启动组件: 接受 fuchsia.component.Realm 对象。
  • 更改测试执行器,以接受所需领域信息查询的别名 信息。
  • 更改测试管理器以实现新的 FIDL API 并启动提供的测试 领域和集合。
  • 记录更改和帮助指南
  • 与 OOT 开发者合作,创建包含 OOT 运行程序的大区。
  • 将当前的 OOT 测试移植到新领域

未来工作:

  • 将使用自定义测试类型的当前测试移植到它们自己的领域。
  • 探索如何消除对名称的依赖。
  • 从测试管理者中移除所有测试领域,并在产品内发布它们 领域。

性能

这项更改不会对性能产生任何影响,也不会受到轻微影响 测试的启动方式,只会影响测试在

工效学设计

本部分介绍了一些要在名称集合和测试集合中传递的解决方案 测试执行器。详细的解决方案不在本文档的讨论范围内。

与 build 集成

定义自定义领域后,产品所有者可以在 构建系统测试作者将使用该类别和构建系统 将生成相应的别名和测试集合作为测试的输入 Executor。

向测试清单添加信息

我们可以在测试分面中嵌入标记和测试集合信息。测试 执行器需要解析并读取组件清单文件,以获取 信息。

为了更好地实现人体工程学,Test Realm 作者将提供清单分片,这些分片用于 测试作者可以包含在他们的测试清单中。

向后兼容性

我们将继续支持当前的测试,并始终支持封闭测试 Realm,它不需要自定义运行程序。

安全注意事项

  • 开发者可以在系统中的任何领域启动测试,但随着测试将 在 eng build 上运行,用户设备不会受此更改的影响。
    • 我们还将在测试执行器中添加一个标志,用于在 共享机器和构建作业。
  • 我们需要将 RealmQuery 和 LifecycleController 路由到所有测试 执行器。这可能有一定的安全问题,具体取决于我们如何决定。 我们将在下一个文档中对此进行讨论,以设计测试执行器 访问这些信息的权限。

隐私注意事项

我们不会收集任何个人数据,因此此设计不会保护任何隐私 效果。

测试

当前测试以及新的集成和单元测试,以便在其中启动测试 自定义领域应全面测试此功能。

文档

记录此功能,以说明 供开发者创建自己的测试领域。

此外,还应记录测试开发者使用自定义领域的方式。

缺点、替代方案和未知问题

替代方案:客户端启动自己的测试管理器

测试开发者将在拓扑中启动自己的测试管理器。FFX 测试 将使用 RCS 连接到 fuchsia.test.manager.RunBuilder 协议,以执行 并从测试结果中收集信息。

此解决方案的优势:

  • 我们只需更改 ffx 测试即可支持此功能
  • 开发者可以结合使用当前的测试管理器代码及其自定义清单 在其拓扑中使用测试管理器组件

此解决方案的问题包括:

  • 在不同环境下运行测试管理器后,将很难对其进行更改 拓扑和 OOT。这将极大地影响测试架构团队的 速度。
  • 客户端需要将测试经理所需的所有功能路由到 自己的拓扑
  • 客户端需要编写测试以确保测试管理器能正常运行 并防止任何回归

替代方案:子配件

子组件可以解决自带测试运行程序的问题, 不像建议的解决方案那么灵活。

我们提出的解决方案使我们能够灵活地将来移除 经过编码的测试领域,并完全拥有产品的所有权 所有者。

替代方案:测试会打包自己的运行程序

测试可以打包自己的运行程序,并使用它们运行测试组件

此解决方案的优势:

  • 无需进行任何更改
  • 这一切可以立即实现

此解决方案的问题包括:

  • 为每个测试运行新运行程序对性能的影响。
  • 需要将运行程序所需的功能路由到测试(中断) 这会削弱我们的保证)。
  • 需要为每个新的跑步者创建一个自定义领域(由于功能方面的原因) 路由要求)。这造成了技术债务复合性。

替代方案:测试配置

将测试参数化,使其具有功能以及这些功能的来源 然后通过管道传输到测试领域本身

"fuchsia.test.additional_capabilities": {
  "runner": "dart_runner",
  "source": "/core/dart/runner"
}

为了实现可路由功能,测试管理器可以使用 RealmQuery API,使用 Realm Builder 代理请求。对于 运行程序,测试管理器可以使用 hub 来代理运行程序协议。

此解决方案的优势:

  • 测试作为测试管理器的子项运行,因此测试管理器可以完全控制 功能

此解决方案的问题包括:

  • 测试可能取决于正式版名称,因此它们将成为 公开 API。
  • 使用 Hub 代理运行程序请求只是一个短期解决方案, 最终需要嵌套或链式运行程序。
  • 测试将能够访问任何可能属于安全性的系统功能 涉及破坏显式路由、在远处创建操作。

替代方案:测试管理器使用 RealmQuery API

在此设计中,测试管理器将有权访问 RealmQuery API,并使用该 API 查询所需信息 从测试领域启动测试。

测试作者将使用分片包含领域和测试集合 测试信息

分片:

{
  facets: {
    "fuchsia.test": {
      launch: {
        realm: "/core/foo/bar/test_realm",
        collection: "tests" // default is "tests", can be omitted.
      }
    },
  },
}

test.cml:

{
    include: [
        "syslog/client.shard.cml",
        "//some/path/oot_runner/default.shard.cml",
        "//some/path/test_realm/default.shard.cml",
    ],
    program: {
        binary: "bin/sample_test",
    },
    use: [
      {
          protocol: [
              "fuchsia.foo.bar",
              ...
          ],
      },
      ...
  ],
}

测试管理器将读取分面,并使用提供的功能查询和 在指定的测试领域启动测试。

测试拓扑

替代方案:测试管理器在拓扑的一个已知位置运行系统测试

这种设计提议在拓扑中有一个常见的已知位置 (例如 /core/tests),测试管理器可以执行所有系统测试。通过 平台开发者将创建和维护这一已知领域, 管理器将仅提供执行和收集工件的机制, 测试。

缺点

  • 可配置性较低,将来如果我们需要多个,将无法伸缩 来运行测试
  • 我们希望将来能够使用嵌套的测试管理器来运行测试 同胞这种设计反对这种做法。
  • 我们可以使用此 RFC 中的设计实现相同的功能, 将 /core/tests 指定为运行测试的领域。此 RFC 提供了更大的灵活性,我们认为这会对您有所帮助。

先验技术和参考资料

这是 Fuchsia 所独有的概念,因此之前没有此类概念。

未来工作

  • 从测试管理器拓扑中移除所有非封闭领域,并与我们的 客户将测试转移到他们自己的自定义测试领域。
  • 以“自带测试经理”为设计目标与测试领域的同级关系。这个 在会话或任何 OOT 领域下运行测试时很有用, 要求在平台中提供任何产品特定支持。