tree: a63577285362818683050e90a7f3e98bd12b61db [path history] [tgz]
  1. meta/
  2. src/
  3. tests/
  4. BUILD.gn
  5. fuchsia_sharded_test_package.gni
  6. METADATA.textproto
  7. OWNERS
  8. README.md
src/lib/testing/sharding/README.md

Fuchsia component test sharding

A system that shards a fuchsia_test_component into a fuchsia_test_package containing multiple test components. Each component runs the same test binary, but proxies its fuchsia.test.Suite instance through a sharder component that filters for a subset of test cases whose names hash to the same shard.

This is intended to allow for Fuchsia tests that are at risk of bumping against suite-level test timeouts (but whose individual test cases are small enough to not time out) to be automatically sharded by test-case-name without needing manual modification of the test source files.

Usage

See //src/lib/testing/sharding/tests/example_sharded_test for a fully-worked example, and the documentation comments on //src/lib/testing/sharding/fuchsia_sharded_test_package.gni for details on all the features of fuchsia_sharded_test_package.

The test being sharded needs to have its CML file configured to use the test-sharding client shard:

{
    include: [
        // When using expectation-based testing, use
        // "//src/lib/testing/sharding/meta/client_with_expectations.shard.cml"
        // instead.
        "//src/lib/testing/sharding/meta/client.shard.cml",
        "syslog/client.shard.cml",
    ],
    program: {
        runner: "rust_test_runner",
        binary: "bin/underlying_test_to_be_sharded",
    },
}

Then use fuchsia_sharded_test_package to declare the test package in GN:

import("//build/rust/rustc_test.gni")
import("//src/lib/testing/sharding/fuchsia_sharded_test_package.gni")

rustc_test("underlying_test_to_be_sharded") {
  edition = "2021"
  sources = [ "src/lib.rs" ]
}

fuchsia_sharded_test_package("example-sharded-test") {
  test_components = [
    {
      name = "example-test"
      manifest = "meta/example-test.cml"
      deps = [ ":underlying_test_to_be_sharded" ]
      num_shards = 3

      # Captures just the "section" of the test so that cases
      # in the same section get sharded together. (optional)
      shard_part_regex = "section_(\d+)::case_.*"

      # Sharding can be used with tests that use
      # //src/lib/testing/expectation. (optional)
      expectations = "path/to/expectations_file.json5"
    },
  ]
}

Then fx test example-sharded-test will result in:

  • The example-sharded-test package being built and published.
  • The test components in that package example-test_shard_0_of_3.cm, example-test_shard_1_of_3.cm, and example-test_shard_2_of_3.cm being run.

When all is said and done, each shard's component topology looks like this:

      parent (test manager)

              ^      fuchsia.test.Suite
              |      (shard subset according to shard config.json)
              +-----------------------+
                                      |
+------------------------+            |
|                        |            |
|  test_shard_0_of_3.cm  |            |
|  +-------------------+ |            |
|  | <original binary> | |            |
|  +-------------------+ |            |
|                        |            |
++-----+-----------------+            |
 |     |                              |
 |     |fuchsia.test.Suite (original) |
 |     v                              |
 |   +-+------------+                 |
 |   |  sharder.cm  | +---------------+
 |   +--+-----------+
 |      ^
 |      | /pkg/data/testshards/shard_0/config.json
 +------+ as /testshard/config.json