blob: f40326cbba4675165dc8b17d51f9233976850ee1 [file] [log] [blame] [view]
# Test Component
## Create a test component
### BUILD.gn
```gn
import("//src/sys/build/components.gni")
executable("my_test") {
sources = [ "my_test.cc" ]
testonly = true
deps = [
"//src/lib/fxl/test:gtest_main",
"//third_party/googletest:gtest",
]
}
fuchsia_component("my-test-component") {
testonly = true
manifest = "meta/my_test.cmx"
deps = [ ":my_test" ]
}
fuchsia_test_package("my-test-package") {
test_components = [ ":my-test-component" ]
}
group("tests") {
deps = [ ":my-integration-test" ]
testonly = true
}
```
`test_package` will expect that there is a corresponding cmx file in the `meta`
folder. So for above example there should be a `my_test.cmx` file in `meta/`.
See also: [test packages][test-packages]
### meta/my\_test.cmx
```json
{
"program": {
"binary": "bin/my_test"
},
"sandbox": {
"services": [...]
}
}
```
## Running the tests
To run a Fuchsia test out of your build, execute:
<pre class="prettyprint">
<code class="devsite-terminal">fx test <var>TEST_NAME</var></code>
</pre>
For more information on running Fuchsia tests, see
[Running tests as components][executing-tests].
## Isolated Storage
- By default, the test component is launched in a new hermetic environment.
- The generated environment name is of form test\_env\_XXXXX, where XXXXX is a
randomly generated number.
- Each test component receives a new isolated storage directory.
- The directory is deleted after the text exits, regardless of the test's
outcome.
### Keep storage for debugging
If you need to keep test storage for the debugging after the test ends, use
[run-test-component][run-test-component] in the Fuchsia shell and pass
`--realm-label` flag.
The `--realm-label` flag defines the label for environment that your test runs
in. When the test ends, the storage won't be deleted automatically - it'll be
accessible at a path under /data. Assuming you:
- gave your test component (in package `mypackage` with component manifest
`myurl.cmx`) access to the "isolated-persistent-storage" feature
- passed --realm-label=foo to run-test-component
- wrote to the file `/data/bar` from the test binary
- can connect to the device via `fx shell`
You should see the written file under the path
`/data/r/sys/r/<REALM>/fuchsia.com:<PACKAGE>:0#meta:<CMX>/<FILE>`, e.g.
`/data/r/sys/r/foo/fuchsia.com:mypackage:0#meta:myurl.cmx/bar`
Assuming you can connect to the device via ssh, you can get the data off the
device with the in-tree utility `fx scp`.
When you're done exploring the contents of the directory, you may want to
delete it to free up space or prevent it from interfering with the results of
future tests.
## Ambient Services
All test components are started in a new hermetic environment. By default, this
environment only contains a few basic services (ambient):
```text
"fuchsia.sys.Environment"
"fuchsia.sys.Launcher"
"fuchsia.process.Launcher"
"fuchsia.process.Resolver"
```
Tests can use these services by mentioning them in their `sandbox > services`.
## Logger Service
Tests and the components launched in a hermetic environment will have access to system's `fuchsia.logger.LogSink` service if it is included in their sandbox. For tests to inject Logger, the tests must use `injected-services` (see below). Then, the injected Logger service takes precedence.
## Restricting log severity
Tests may be configured to fail when the component's test environment produces
high severity [logs][syslogs]. This is useful for when such logs, for instance
when such logs are unexpected, as they indicate an error.
A test might expect to log at ERROR severity. For example, the test might be
covering a failure condition & recovery steps. Other tests might expect not to
log anything more severe than INFO. The common case and default behavior is for
errors above WARN level to be considered failures, but there are configuration
files for overrides here:
- **fuchsia**: [//garnet/bin/run_test_component/max_severity_fuchsia.json][max-severity-fuchsia]
- **petals**: //tests/config/max_severity_\<petal\>.json
For example, *experiences*: [//tests/config/max_severity_experiences.json][max-severity-experiences]
For instance, to allow a test to produce **ERROR** logs, add the following:
```json
{
"tests": [
{
"url": "fuchsia-pkg://fuchsia.com/my-package#meta/my-test.cmx",
"max_severity": "ERROR"
},
...
]
}
```
To cause the same test to fail on any log message more severe than **INFO**:
```json
{
"tests": [
{
"url": "fuchsia-pkg://fuchsia.com/my-package#meta/my-test.cmx",
"max_severity": "INFO"
},
...
]
}
```
Valid values for `max_severity`: `TRACE`, `DEBUG`, `INFO`, `WARN`, `ERROR`, `FATAL`.
Changes to configuration take effect *only after an update*, for instance with `fx
update` or `fx ota`, or by rebuilding and restarting `fx qemu`.
## Run external services
If your test needs to use (i.e. its sandbox includes) any services other than the ambient and logger services above, you must perform either, both or none:
- Inject the services by starting other components that provide those services in the hermetic test environment
- Request non-hermetic system services be included in the test environment, when a service cannot be faked or mocked, see [Other system services](#Other-system-services).
To inject additional services, you can add a `injected-services` clause to the manifest file's facets:
```json
"facets": {
"fuchsia.test": {
"injected-services": {
"service_name1": "component_url1",
"service_name2": "component_url2"
}
}
}
```
`fx test` will start `component_url1` and `component_url2` and the
test will have access to `service_name1` and `service_name2`. Note that this makes the injected services available in the test environment, but the test component still needs to "use" them by including the service in its `sandbox > services`.
### Other system services
There are some services that cannot be faked or mocked. You can connect to real
system versions of these services by mentioning these services in
`system-services`. Services that cannot be faked are listed
[here](/garnet/bin/run_test_component/test_metadata.cc).
Test can only list allowlisted system services under `"system-services"` as
demonstrated above.
[executing-tests]: /docs/development/testing/running_tests_as_components.md
[run-test-component]: /docs/development/testing/running_tests_as_components.md#running_tests_legacy
[max-severity-fuchsia]: /garnet/bin/run_test_component/max_severity_fuchsia.json
[max-severity-experiences]: https://fuchsia.googlesource.com/experiences/+/refs/heads/master/tests/config/max_severity_experiences.json
[syslogs]: /docs/development/logs/concepts.md
[test-packages]: /docs/development/components/build.md#test-packages