To migrate your test components, follow these steps:
Find the GN build rules for the tests that exercise your component. Typically this is a fuchsia_test_package()
or fuchsia_unittest_package()
.
The preferred practice for tests declared with a fuchsia_unittest_package()
build rule is to use the generated manifest provided by the Fuchsia build system.
To allow the GN target to generate your manifest, remove the manifest
attribute from the fuchsia_unittest_package()
:
fuchsia_unittest_package("my_component_tests") { {{ '<strike>' }}manifest = "meta/my_component_test.cmx"{{ '</strike>' }} deps = [ ":my_component_test" ] }
Your test package is now able to execute using Components v2 and the Test Runner Framework.
Consider the following example test component manifest:
// my_component_test.cmx { "include": [ "syslog/client.shard.cmx" ], "program": { "binary": "bin/my_component_test" } }
To migrate this test to the Test Runner Framework, do the following:
Create a CML file that points to the test binary that includes the appropriate test runner:
Note: See the available test runners provided by the framework.
// my_component_test.cml { include: [ // Select the appropriate test runner shard here: // rust, gtest, go, etc. "//src/sys/test_runners/rust/default.shard.cml", // Enable system logging "syslog/client.shard.cml", ], program: { binary: "bin/my_component_test", } }
Locate the GN build rule for your test component referenced by the fuchsia_test_package()
:
fuchsia_component("my_component_test") { testonly = true manifest = "meta/my_component_test.cmx" deps = [ ":bin_test" ] } fuchsia_test_package("my_component_tests") { deps = [ ":my_component_test" ] }
Update your test component's build rule to reference the new CML file:
fuchsia_component("my_component_test") { testonly = true {{ '<strong>' }}manifest = "meta/my_component_test.cml"{{ '</strong>' }} deps = [ ":bin_test" ] } fuchsia_test_package("my_component_tests") { deps = [ ":my_component_test" ] }
A test may include or depend on components that are separate from the test component. Here are some things to look for:
fuchsia.test facets
, such as injected-services
or system-services
?Note: The Test Runner Framework executes tests within a realm that enforces hermetic component resolution, which means that test components must resolve dependencies from within their own package. For more details, see hermetic component resolution.
The migration procedure varies depending on the testing framework features in your v1 component:
system-services
test facets.injected-services
test facets.Note: For more details on the services and capabilities provided to components by the Test Runner Framework, see the test manager documentation.
For tests that use system-services
test facets, consider if they can be converted to injected services instead. Injecting services is the preferred method because it promotes hermetic test behavior.
For certain non-hermetic tests, the Test Runner Framework provides the test realm with the following services:
Service | Description |
---|---|
fuchsia.scheduler.ProfileProvider | Profile provider for scheduler |
fuchsia.sysmem.Allocator | Allocates system memory buffers |
fuchsia.tracing.provider.Registry | Register to trace provider |
fuchsia.vulkan.loader.Loader | Vulkan library provider |
fuchsia.sys.Loader | CFv1 loader service to help with |
: : migration. : | |
fuchsia.sys.Environment | CFv1 environment service to help with |
: : migration. : |
Consider the following example test component that uses a single system service, fuchsia.sysmem.Allocator
:
// my_component_test.cmx { "facets": { "fuchsia.test": { "system-services": [ "fuchsia.sysmem.Allocator" ] } }, "program": { "binary": "bin/my_component_test" }, "sandbox": { "services": [ "fuchsia.sysmem.Allocator" ] } }
To migrate this test to the Test Runner Framework, declare each available system service with the other required services in your test component manifest. Since this test uses the fuchsia.sysmem.Allocator
system capability, it also needs to be marked as hermetic: "false"
as shown below.
// my_component_test.cml { include: [ // Select the appropriate test runner shard here: // rust, gtest, go, etc. "//src/sys/test_runners/rust/default.shard.cml", ], program: { binary: "bin/my_component_test", }, {{ '<strong>' }}facets: { "fuchsia.test": { type: "system" }, }, use: [ { protocol: [ "fuchsia.sysmem.Allocator" ], }, ],{{ '</strong>' }} }
For tests that use other fuchsia.test facets, such as injected-services
, your test component manifest must declare each dependent component and route the provided capabilities to the test component.
In the following example, suppose there's a single injected service, fuchsia.pkg.FontResolver
:
// my_component_test.cmx { "facets": { "fuchsia.test": { "injected-services": { "fuchsia.pkg.FontResolver": "fuchsia-pkg://fuchsia.com/font_provider_test#meta/mock_font_resolver.cmx" } } }, "program": { "binary": "bin/my_component_test" }, "sandbox": { "services": [ "fuchsia.pkg.FontResolver" ] } }
To migrate this test to the Test Runner Framework, do the following:
Create a CML file for the test component that points to the test binary and includes the appropriate test runner:
Note: See test runners that are provided by the framework.
// my_component_test.cml (test component) { include: [ // Select the appropriate test runner shard here: // rust, gtest, go, etc. "//src/sys/test_runners/rust/default.shard.cml", ], program: { // Binary containing tests binary: "bin/font_provider_test", }, use: [ ... ], }
You need CML files for each component that provides a capability needed in the test. If there is an existing CML file for the component providing the injected service, you may be able to reuse it. Otherwise if the mock component is being ported to v2, create a new CML file. If the mock component has not been ported to v2 yet, wrap the component using cmx_runner
.
{CML component}
// mock_font_resolver.cml (capability provider) { program: { runner: "elf", binary: "bin/mock_font_resolver", }, use: [ // mock_font_resolver's dependencies. { protocol: [ "fuchsia.proto.SomeProtocol" ], }, ], capabilities: [ { protocol: [ "fuchsia.pkg.FontResolver" ], }, ], expose: [ { protocol: "fuchsia.pkg.FontResolver", from: "self", }, ], }
{Wrapped CMX component}
// mock_font_resolver.cml (capability provider) { include: [ // Use `cmx_runner` to wrap the component. "//src/sys/test_manager/cmx_runner/default.shard.cml", "syslog/client.shard.cml", ], program: { // wrap v1 component legacy_url: "fuchsia-pkg://fuchsia.com/font_provider_test#meta/mock_font_resolver.cmx", }, use: [ // if `mock_font_resolver.cmx` depends on some other protocol. { protocol: [ "fuchsia.proto.SomeProtocol" ], }, // Note: Wrapped legacy component can only use protocol capabilities. ], // expose capability provided by mock component. capabilities: [ { protocol: [ "fuchsia.pkg.FontResolver" ], }, ], expose: [ { protocol: "fuchsia.pkg.FontResolver", from: "self", }, ], }
Note: The CML files for the capability providers can be distributed in the same package that contained the v1 test. Follow the same instructions in Migrate the component manifest that you used to package your component.
Add the capability provider(s) as children of the test component, and route the capabilities from each provider.
// my_component_test.cml (test component) { ... // Add capability providers children: [ { name: "font_resolver", url: "#meta/mock_font_resolver.cm", }, ], // Route capabilities to the test use: [ { protocol: [ "fuchsia.pkg.FontResolver" ], from: "#font_resolver", }, ], offer: [ { // offer dependencies to mock font provider. protocol: [ "fuchsia.proto.SomeProtocol" ], from: "#some_other_child", }, ], }
Package the test component and capability provider(s) together into a single hermetic fuchsia_test_package()
:
{CML component}
# Test component fuchsia_component("my_component_test") { testonly = true manifest = "meta/my_component_test.cml" deps = [ ":bin_test" ] } fuchsia_component("mock_font_resolver") { testonly = true manifest = "meta/mock_font_resolver.cml" deps = [ ":mock_font_resolver_bin" ] } # Hermetic test package fuchsia_test_package("my_component_tests") { test_components = [ ":my_component_test" ] deps = [ ":mock_font_resolver" ] }
{Wrapped CMX component}
# Test component fuchsia_component("my_component_test") { testonly = true manifest = "meta/my_component_test.cml" deps = [ ":bin_test" ] } fuchsia_component("mock_font_resolver") { testonly = true manifest = "meta/mock_font_resolver.cml" deps = [ {{ '<var label="legacy_component">"//path/to/legacy(v1)_component"</var>' }} ] } # Hermetic test package fuchsia_test_package("my_component_tests") { test_components = [ ":my_component_test" ] deps = [ ":mock_font_resolver" ] }
For more details on providing external capabilities to tests, see Integration testing topologies.
Explore the following sections for additional migration guidance on specific features your test components may support:
Build and run your test and verify that it passes:
fx build && fx test my_component_tests
If your test doesn‘t run correctly or doesn’t start at all, try following the advice in Troubleshooting components.