blob: 4f5f8aa26e884a382caf740509335f10368957d8 [file] [log] [blame] [view]
# Inspect validator puppet architecture
## Overview
The Validator system sends FIDL commands to control a "puppet" program, which
invokes library functionality to modify some state that the Validator then
evaluates. For more information about the Inspect Validator, see the
[README](README.md).
The Puppet includes these parts:
* Serving a FIDL protocol.
* Unpacking the protocol and making library calls.
* Building an integration test that includes the Puppet and Validator programs.
This doc focuses on the Inspect Validator Rust Puppet located at
[//src/diagnostics/validator/inspect/lib/rust/src/main.rs](/src/diagnostics/validator/inspect/lib/rust/src/main.rs).
## FIDL design
The FIDL protocol for Inspect Puppet is defined in
[//src/diagnostics/validator/inspect/fidl/inspect_puppet.fidl](/src/diagnostics/validator/inspect/fidl/inspect_puppet.fidl).
The FIDL protocol corresponds closely to the functions in the
[Inspect library API](/docs/development/diagnostics/inspect/README.md)
which defines actions to be applied to any Inspect API implementation. The FIDL
API is written to correspond to the
[Rust API](https://fuchsia-docs.firebaseapp.com/rust/fuchsia_inspect/index.html).
(Note: Inspect APIs are allowed to differ from the Rust API; such APIs may
require puppet code architecture modifications.)
## Serving FIDL
The `main()` function performs boilerplate to serve a single FIDL client
through `run_driver_service()`, which receives either `Initialize` or `Act`
events from the FIDL stream. `Act` events are unpacked by the `Actor` object
which maintains the state necessary to control the Inspect library.
## Actor and the Inspect library
`Actor` contains an `Inspector` (the Inspect library's entry-point object),
a hashmap of `nodes`, and a hashmap of `properties`. It implements one
function, `act()`, which contains a giant `match` statement ("switch" or "case"
in other languages) to invoke each action that the library implements.
Puppets can report `Unimplemented` for actions the library doesn't support.
After the Validator invokes each action, it will test the library's effect on
the VMO. The library should handle propagating the effects of actions so that
the Validator can see them.
The hashmaps of `nodes` and `properties` store values that are returned by the
Inspect library. Since Rust is an RAII language that cleans up automatically
when reference to memory is lost, failing to store a node or property would
cause immediate deletion of that node or property. Also, storing properties
allows updating their values in response to FIDL commands.
## Testing and the build system
The Validator and Puppet combination should make a hermetic integration test.
### Dependencies and names
[Validator's BUILD.gn file](/src/diagnostics/validator/inspect/BUILD.gn#21)
defines a `validator_bin` target, which is used by the
[Rust puppet's BUILD.gn file](/src/diagnostics/validator/inspect/lib/rust/BUILD.gn#33)
as a dependency to the `test_package()` named `inspect_validator_test_rust`
which is the test that exercises the Rust puppet.
The Rust puppet itself is
[a component](/src/diagnostics/validator/inspect/lib/rust/BUILD.gn#8).
That build rule produces
`inspect_validator_rust_puppet`, which is included in the binaries of the
`fuchsia_unittest_package()`.
The `validator_bin` target from the
[Validator's Build.gn file](/src/diagnostics/validator/inspect/BUILD.gn)
is included in the `deps` of the
`fuchsia_unittest_package()`.
### CQ/CI
Putting `inspect_validator_test_rust` in the `deps` of `group("tests")` in its
[BUILD.gn](/src/diagnostics/validator/inspect/lib/rust/BUILD.gn)
makes it easy to include `inspect_validator/lib/rust:tests` in the `deps` of
`group("tests")` of [src/diagnostics/BUILD.gn](/src/diagnostics/BUILD.gn).
This will be picked up by the build system and cause the Inspect Validator Rust
Puppet test to be run in CQ and CI.
### Meta .cml files
There are the following CML files in [//src/diagnostics/validator/inspect/meta](/src/diagnostics/validator/inspect/meta):
* [puppet.shard.cml](/src/diagnostics/validator/inspect/meta/puppet.shard.cml)
Lets the puppet binary run, use the logger and Inspect, and serve the Validate protocol.
* [validator.cml](/src/diagnostics/validator/inspect/meta/validator.cml)
* `use: protocol:` specifies the services that the Validator needs to run.
* `fuchsia.diagnostics.ArchiveAccessor` lets it read the puppet's published Inspect data.
* `diagnostics.validate.InspectPuppet` lets it control the puppet.
* `children: name: "puppet"` places the puppet in the component hierarchy.
* `children: url: "#meta/puppet.cm"` allows the puppet to be found and loaded.
* `offer: protocol: "fuchsia.logger.LogSink"` is needed for the puppet's logs to be visible.
* Provides the necessary structured config for the validator for each puppet.
* [test.shard.cml](/src/diagnostics/validator/inspect/meta/test.shard.cml)
Defines the abilities necessary to run the Inspect Validator test manager, which is the parent
of the validator and the component.
These shards are used by the puppet's and validator's CML files in each puppet directory, or by
the test manager. Currently there are 4 puppets:
* [Rust](/src/diagnostics/validator/inspect/lib/rust)
* [C++](/src/diagnostics/validator/inspect/lib/cpp)
* [Go](/src/connectivity/network/netstack/inspect/validator)
The Validator conroller's CML is referred to in the `manifest` key of `fuchsia_unittest_package()`
(for Rust or C++) or `fuchsia_unittest_component()` (for Go).