blob: 959d468d0f56adf1cbefb7670074971cf9a63b74 [file] [log] [blame] [view]
# Fuchsia tests.json file format
Fuchsia's build system exports structured information about all
tests included in a build in a `tests.json` file in the build output
directory (e.g. `$FUCHSIA_DIR/out/default/tests.json`).
Fuchsia's continuous integration infrastructure uses `tests.json`
to determine which tests to run, and `fx test` uses it to determine
which tests may be run locally. `tests.json` and its schema are
implementation details of the platform build and test and are not
part of the SDK.
This document describes the file's contents and how the file is generated.
## Generating tests.json
The `tests.json` file is generated immediately after gn-gen in
[regenerator.py](/build/build_tests_json.py).
The fields for `tests.json` entries are collected using the [GN
metadata
mechanism](https://gn.googlesource.com/gn/+/main/docs/reference.md#var_metadata).
`tests.json` entries are registered from GN files by using the
[`test_spec` GN template](/build/testing/test_spec.gni).
`tests.json` is automatically generated by `fx set`. The `tests.json`
format is limited by what can readily be generated from GN using
GN's relatively limited metadata mechanism. To get around these
limitations, the Fuchsia build also produces file called `test-list.json`,
which is generated by post-processing `tests.json` as described below.
## tests.json consumers
Various tools and scripts ingest the `tests.json` file since it is
the canonical list of available tests for a given Fuchsia build.
This section surveys the most notable consumers of the format.
### test_list_tool
The [test_list_tool](/tools/test_list_tool/) processes `tests.json`.
Using the canonical list of tests, it uses the contained package
manifest information to load the build packages and annotate each
test with information about how it should be executed and tags for
additional categorization. For example, it can determine if a test
component runs hermetically, and tags the test with `"hermetic":
true`.
The test_list_tool outputs this information to a `test-list.json`
file adjacent to `tests.json`, and it is run as one of the last
build steps after all packages are built. It uses the same unique
`name` key as `tests.json` so that entries can be matched.
### fx search-tests
The `fx search-tests` script provides fuzzy matching on test names
to help developers find which tests are available to run. It uses
the values in `tests.json` as keys for fuzzy matching, in addition
to searching for non-included tests through the source tree.
### fx test
The `fx test` command is the developer-facing entrypoint to test
execution in the Fuchsia source tree. It uses `tests.json` to
determine the canonical set of tests, and then finds associated
data in `test-list.json` and `test_components.json` to determine
how a test should be executed.
### botanist / testsharder
In Infra, [testsharder](/tools/integration/testsharder/) depends on
`tests.json` to shard test entries based on environment dimensions.
The output of that process is another file containing fields
derived from `tests.json` which is then passed to [botanist](/tools/botanist/)
on the bots where tests run.
## tests.json structure
`tests.json` is a JSON file consisting of a single array. Each
element of the array corresponds to a single Test Target entry in
the build.
Test Target entries have two top-level fields, `environments` and
`test` corresponding to Test Environments and Test Info respectively.
### Fields
#### environments field
The `environments` field is an array of Test Environment entries.
Each Test Environment entry specifies a single environment the test
may run in, and this field is used by testsharder to shard tests between
device configurations.
Each Test Environment entry has a single field `dimensions` with
any number of arbitrary dimensions. Typically, however, there are
two sets of fields that are most common:
- `device_type` - Specifies the required device type for the test.
For example:
```json
"environments": [
{
"dimensions": {
"device_type": "QEMU"
}
}
]
```
This denotes a test that can run on the QEMU device configuration.
**Note:** This does not mean that the test runs on *any* QEMU
device, rather it means that the test runs on a QEMU instance
based on the configuration used by `botanist`.
- `cpu` and `os` - Specifies the required CPU architecture and
operating system for a host test. For example:
```json
"environments": [
{
"dimensions": {
"cpu": "x64",
"os": "Linux"
}
}
]
```
This specifies a test that can run on an x64 Linux system.
- `tags` - Specifies other properties for sharding. For example:
```json
"environments": [
{
"tags": [ "e2e-isolated" ]
}
]
```
This specifies a test with tag "e2e-isolated".
Tests with an environment tag will not be run in continuous
integration builds unless the build configuration specifically
opts in to running tests with that tag, in which case *only* tests
with that tag will run.
#### test field
The `test` field provides information about how to categorize, run,
and configure the test. Test executors like `fx test` and `botanist`
use this data to determine the correct binary and command line to
execute the test. It also contains information that is useful for
other tooling integrations, for instance, to rebuild test targets
between test invocations.
There are generally two types of test: Host and Device. Host tests
refer to a binary path on the host system that is run to execute
the test. Device tests refer to a component URL that is run on the
target system using Test Manager.
Some host tests require a Fuchsia device and some do not. An
*end-to-end test* (E2E) has an `os` that is not "fuchsia," but still
has a `device_type` specified in its `environments`.
The `test` object contains the following fields, split by type of test:
**All tests**
- `name` - Name for the test. This value is unique within `tests.json`.
Typically contains the test component URL for device tests and the
path to the test binary relative to the output directory for host
tests.
- `cpu` - The CPU architecture this test runs on. Redundant with
the `environments` entry for host tests, but the only source of
this information for device tests.
- `os` - The OS this test runs on. Redundant with the `environments`
entry for host tests, but the only source of this information for
device tests. This field is used by `botanist` to determine if a
test should be run as a subprocess on the host machine or run over
SSH to a target device.
- `label` - The GN label that produced this test entry. Used to
know which targets to rebuild when executing tests from `fx test`,
but only for host tests for which this label actually outputs the
real test binary. Other types of tests use different label fields
such as `package_label`.
**Host tests only**
- `path` - The path to the test binary, relative to the output
directory. Present only for host tests.
- `runtime_deps` - The path (relative to the output directory) to
a JSON file containing a list of file paths (relative to the output
directory) to files that should be put in a place known to a host
test for use at runtime. The format of the file is a JSON array
of file path strings.
**Device tests only**
- `has_generated_manifest` - True if this is a test component whose
manifest was generated by a GN rule, omitted if the test is a host
test, false otherwise. Used for test categorization and tracking
of tests using custom manifests.
- `build_rule` - Generated by the build for further test categorization.
For example, it is meaningful to know if a test was was created by
the `fuchsia_unittest_package` or the `fuchsia_test_package` rule.
- `log_settings` - A dict that may contain these fields:
- `max_severity` - This field overrides the default maximum log
severity for tests. By default tests that emit an ERROR log will
fail, but this field instructs test executors to run in a mode
where a different level of logs causes failure.
- `min_severity` - Used to instruct the test components to emit
logs at this level rather than the default. By default tests
choose their own minimum log severity.
- `package_label` - The GN label that produced the package this
test is contained in. Only present for device tests. Used by `fx
test` to rebuild the packages containing tests before they are run.
- `component_label` - The GN label that produces the test component
for this test. Used for fuzzy matching test names when no matching
tests are found in `fx search-tests` (in addition to all other label
fields). Only present for device tests.
- `package_manifests` - List of paths (relative to output directory)
for each package manifest involved in constructing the test package.
Used to determine which packages to republish after building tests
in `fx test`. Only present for device tests.
- `package_url` - The test component URL corresponding to this test.
This is the URL that Test Manager is requested to execute for device
tests.
- `parallel` - Override for default test runner parallelism (as an
integer). Typically used to instruct test executors to tell `ffx
test` not to run test cases in parallel for tests that have crosstalk.
Setting this value to `1` disables parallel test case execution,
while a number `> 1` forces parallel test case execution if supported
by the individual test runner.
### Examples
**Host Test**
```json5
[
{
"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)",
"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"
}
}
]
```
**Device Test**
```json5
[
{
"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)",
"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"
}
}
]
```