Google is committed to advancing racial equity for Black communities. See how.

Complex topologies and integration testing

Integration testing scenarios involve two or more components operating in the same realm and exchanging capabilities. While the majority of tests are unit tests that span only a single component, integration testing scenarios call for defining realm topologies and capability routes.

The "driver" pattern for v2 component tests

We demonstrate the driver pattern for writing an integration test with a custom component topology.

Build definition

We define the BUILD.gn file as shown below:

rustc_test("bin") {
  name = "hello_world_integration_test"
  edition = "2018"
  source_root = "src/hello_world_integration_test.rs"

  deps = [
    "//sdk/fidl/fuchsia.io:fuchsia.io-rustc",
    "//sdk/fidl/fuchsia.sys2:fuchsia.sys2-rustc",
    "//src/lib/diagnostics/reader/rust",
    "//src/lib/fidl/rust/fidl",
    "//src/lib/fuchsia",
    "//src/lib/fuchsia-component",
    "//third_party/rust_crates:anyhow",
    "//third_party/rust_crates:futures",
  ]

  sources = [ "src/hello_world_integration_test.rs" ]
}

fuchsia_component("hello-world-integration-test-driver") {
  testonly = true
  manifest = "meta/hello-world-integration-test-driver.cml"
  deps = [ ":bin" ]
}

fuchsia_component("hello-world-integration-test-component") {
  component_name = "hello-world-integration-test"
  testonly = true
  manifest = "meta/hello-world-integration-test.cml"
}

fuchsia_test_package("hello-world-integration-test") {
  test_components = [ ":hello-world-integration-test-component" ]
  deps = [
    ":hello-world-integration-test-driver",
    "//examples/components/basic:hello-world",
    "//src/diagnostics/archivist:archivist-for-embedding",
  ]
}

Component topology

The topology for the test realm in this example looks as follows:


Test driver topology

In this example the test package hello-world-integration-test contains four components:

  • hello-world-integration-test-component - Main entry point
  • hello-world - Component under test
  • hello-world-integration-test-driver - Test driver
  • archivist-for-embedding - Helper component that provides services to other components.

hello-world-integration-test-component has two children:

  • hello-world-integration-test-driver
  • archivist-for-embedding

This is a simple component realm that launches hello-world-integration-test-driver and offers it the helper services.

Finally, note that all components under test are included in the test's own package. This promotes hermeticity and has many benefits. For instance it's possible to push an updated version of the same package to the device and run the test again without worrying whether the different components are all of the same version or have fallen out of sync.

Test Runner Framework integration

Note that the driver component exposes fuchsia.test.Suite from its child to the test root. The root of a test realm must always expose this protocol in order to integrate with the Test Runner Framework.

The root realm is defined as follows:

{
    children: [
        {
            name: "driver",
            url: "fuchsia-pkg://fuchsia.com/hello-world-integration-test#meta/hello-world-integration-test-driver.cm",
        },
    ],
    offer: [
        {
            protocol: [
                "fuchsia.diagnostics.ArchiveAccessor",
                "fuchsia.logger.LogSink",
            ],
            from: "parent",
            to: "#driver",
        },
    ],
    expose: [
        {
            protocol: "fuchsia.test.Suite",
            from: "#driver",
        },
    ],
}

hello-world-integration-test-driver contains the test logic and expectations. The driver launches the hello-world component and asserts that it is writing the expected strings to the log.

Note that this is a Rust test, and therefore includes rust/default.shard.cml as required to integrate with the Test Runner Framework.

{
    include: [
        "//sdk/lib/diagnostics/syslog/client.shard.cml",
        "//src/sys/test_runners/rust/default.shard.cml",
    ],
    program: {
        binary: "bin/hello_world_integration_test",
    },
    children: [
        {
            name: "hello_world",
            url: "fuchsia-pkg://fuchsia.com/hello-world-integration-test#meta/hello-world.cm",
        },
    ],
    use: [
        {
            protocol: "fuchsia.sys2.Realm",
            from: "framework",
        },
        { protocol: "fuchsia.diagnostics.ArchiveAccessor" },
    ],
    offer: [
        {
            protocol: "fuchsia.logger.LogSink",
            from: "parent",
            to: "#hello_world",
        },
    ],
}

Further study

The code for this example can be found under //examples/components/basic/integration_tests.