| // Copyright 2021 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| library fuchsia.component.test; |
| |
| using fuchsia.component; |
| using fuchsia.component.decl; |
| using fuchsia.component.runner; |
| using fuchsia.component.types; |
| using fuchsia.io; |
| using fuchsia.io2; |
| |
| type RealmBuilderError = strict enum : uint32 { |
| /// An attempt was made to interact with a component declaration for a |
| /// component which is located behind a child declaration, and is thus not |
| /// directly available to RealmBuilder. |
| NODE_BEHIND_CHILD_DECL = 0; |
| |
| /// An attempt was made to retrieve a child of a component which does not |
| /// exist. |
| NO_SUCH_CHILD = 1; |
| |
| /// The root component cannot have a URL-based source. |
| ROOT_CANNOT_BE_SET_TO_URL = 2; |
| |
| /// The root component cannot be marked as eager. |
| ROOT_CANNOT_BE_EAGER = 3; |
| |
| /// RealmBuilder failed to parse the FIDL from one of the arguments. |
| BAD_FIDL = 4; |
| |
| /// A required field was missing in the input. |
| MISSING_FIELD = 5; |
| |
| /// The set of targets for a route is not allowed to be empty. |
| ROUTE_TARGETS_EMPTY = 6; |
| |
| /// The source for the route does not exist. |
| MISSING_ROUTE_SOURCE = 7; |
| |
| /// A target for the route does not exist. |
| MISSING_ROUTE_TARGET = 8; |
| |
| /// A target for the route is equal to the source, and it is impossible to |
| /// route a component's capability to itself. |
| ROUTE_SOURCE_AND_TARGET_MATCH = 9; |
| |
| /// A component manifest has failed validation. |
| VALIDATION_ERROR = 10; |
| |
| /// The requested route is impossible because the capability type cannot be |
| /// exposed. |
| UNABLE_TO_EXPOSE = 11; |
| |
| /// The source of the route is invalid because currently "above root" is the |
| /// only supported source for storage capabilities. |
| STORAGE_SOURCE_INVALID = 12; |
| |
| /// There is no component in this realm with the given moniker. |
| MONIKER_NOT_FOUND = 13; |
| |
| /// The package directory has already been set for this connection. |
| PKG_DIR_ALREADY_SET = 14; |
| |
| /// Unable to load component from package, the package dir is not set. |
| PKG_DIR_NOT_SET = 15; |
| |
| /// Failed to load component from package due to IO error. |
| PKG_DIR_IO_ERROR = 16; |
| |
| /// Failed to load the component decl. |
| FAILED_TO_LOAD_COMPONENT_DECL = 17; |
| |
| /// An invalid capability was requested from the "debug" route endpoint. |
| /// |
| /// Only protocols may be requested from the "debug" route endpoint in |
| /// RealmBuilder. |
| INVALID_CAPABILITY_FROM_DEBUG = 18; |
| }; |
| |
| const MAX_MOCK_ID_LENGTH uint32 = 1000; |
| const MAX_LEN_ROUTE_ENDPOINTS uint32 = 100; |
| |
| /// The handles a mock component uses to consume capabilities from and provide |
| /// capabilities to the framework. |
| type MockComponentStartInfo = resource table { |
| 1: ns vector<fuchsia.component.runner.ComponentNamespaceEntry>:fuchsia.component.runner.MAX_NAMESPACE_COUNT; |
| 2: outgoing_dir server_end:fuchsia.io.Directory; |
| }; |
| |
| /// A component to be added to the realm, which is either a component |
| /// declaration that RealmBuilder should provide or an external URL that should |
| /// be referenced in a child decl. |
| type Component = flexible union { |
| 1: decl fuchsia.component.decl.Component; |
| 2: url string:fuchsia.component.types.MAX_URL_LENGTH; |
| 3: legacy_url string:fuchsia.component.types.MAX_URL_LENGTH; |
| }; |
| |
| /// A capability route, denoting where a capability comes from and where it goes |
| /// to. |
| type CapabilityRoute = table { |
| /// The capability to route |
| 1: capability Capability; |
| |
| /// Where the capability comes from |
| 2: source RouteEndpoint; |
| |
| /// Where the capability goes to |
| 3: targets vector<RouteEndpoint>:MAX_LEN_ROUTE_ENDPOINTS; |
| |
| /// If true any components loaded in from the package will be modified as |
| /// needed to make the route valid. If false the package-local components |
| /// will not be modified. |
| 4: force_route bool; |
| }; |
| |
| /// A capability to be routed |
| type Capability = flexible union { |
| 1: protocol ProtocolCapability; |
| 2: directory DirectoryCapability; |
| 3: storage StorageCapability; |
| }; |
| |
| /// A protocol capability |
| type ProtocolCapability = table { |
| 1: name string:fuchsia.component.MAX_NAME_LENGTH; |
| }; |
| |
| /// A directory capability |
| type DirectoryCapability = table { |
| 1: name string:fuchsia.component.MAX_NAME_LENGTH; |
| 2: path string:fuchsia.component.MAX_PATH_LENGTH; |
| 3: rights fuchsia.io2.Rights; |
| }; |
| |
| /// A storage capability |
| type StorageCapability = table { |
| 1: name string:fuchsia.component.MAX_NAME_LENGTH; |
| 2: path string:fuchsia.component.MAX_PATH_LENGTH; |
| }; |
| |
| /// The endpoint of a capability route, describing either the provider or |
| /// consumer of a capability. |
| type RouteEndpoint = flexible union { |
| 1: component string:fuchsia.component.MAX_PATH_LENGTH; |
| 2: above_root AboveRoot; |
| 3: debug Debug; |
| }; |
| |
| /// The capability route's endpoint exists above the constructed realm, and is |
| /// offered to the realm's collection or will be accessed by the parent using |
| /// `fuchsia.component#Realm`. |
| type AboveRoot = struct {}; |
| |
| /// The capability route's endpoint exists in the environment and is offered as |
| /// "debug". |
| type Debug = struct {}; |
| |
| /// This stateful protocol can be used to construct a new component realm at |
| /// runtime. This new realm is built iteratively by calling the methods on this |
| /// protocol to add new components and capability routes between them. Due to |
| /// the stateful nature of this protocol, one realm may be constructed per |
| /// connection. |
| /// |
| /// Once the realm details are successfully processed, `Commit` should be called |
| /// to produce a URL which can be used to create the component. |
| @discoverable |
| protocol RealmBuilder { |
| /// Initializes this connection to the framework intermediary. This function |
| /// should be called at the stat of every new RealmBuilder |
| /// connection, with the `pkg_dir_handle` argument providing a connection |
| /// to the test's package with rx* permissions. Components that are added |
| /// with a relative URL are loaded from this directory handle. If this call |
| /// is not made, any call to SetComponent with a relative URL will return an |
| /// error. |
| Init(resource struct { |
| pkg_dir_handle client_end:fuchsia.io.Directory; |
| }) -> (struct {}) error RealmBuilderError; |
| |
| /// Sets the component to the provided component source. If the source is |
| /// a `Component::decl` then a new node is added to the internal tree |
| /// structure maintained for this connection. If the source is a |
| /// `Component::url` then a new ChildDecl is added to the parent of the |
| /// moniker. If any parents for the component do not exist then they are |
| /// added. If a different component already exists under this moniker, |
| /// then it is replaced. |
| SetComponent(struct { |
| moniker string:fuchsia.component.MAX_MONIKER_LENGTH; |
| component Component; |
| }) -> (struct {}) error RealmBuilderError; |
| |
| /// Sets the component to be a mock component. A new Component decl is |
| /// generated for the component, and assigned a new mock id. This id is |
| /// returned by this function, and when the mock component should start |
| /// running a new OnMockRunRequest is issued with this same id. |
| SetMockComponent(struct { |
| moniker string:fuchsia.component.MAX_MONIKER_LENGTH; |
| }) -> (struct { |
| mock_id string:MAX_MOCK_ID_LENGTH; |
| }) error RealmBuilderError; |
| |
| /// Returns the current value of a component decl in the realm being |
| /// constructed. Note that this cannot retrieve decls through external |
| /// URLs, so for example if `SetComponent` is called with `Component::url` |
| /// and then `GetComponentDecl` is called with the same moniker, an error |
| /// will be returned. |
| GetComponentDecl(struct { |
| moniker string:fuchsia.component.MAX_MONIKER_LENGTH; |
| }) -> (struct { |
| component_decl fuchsia.component.decl.Component; |
| }) error RealmBuilderError; |
| |
| /// Adds a capability route to the realm being constructed, adding any |
| /// necessary offers, exposes, uses, and capability declarations to any |
| /// component involved in the route. Note that components added with |
| /// `Component::url` can not be modified, and they are presumed to already |
| /// have the declarations needed for the route to be valid. If an error is |
| /// returned some of the components in the route may have been updated while |
| /// others were not. |
| RouteCapability(struct { |
| route CapabilityRoute; |
| }) -> (struct {}) error RealmBuilderError; |
| |
| /// Marks the component and any ancestors of it as eager, ensuring that the |
| /// component is started immediately once the realm is bound to. |
| MarkAsEager(struct { |
| moniker string:fuchsia.component.MAX_MONIKER_LENGTH; |
| }) -> (struct {}) error RealmBuilderError; |
| |
| /// Returns true if the component exists in this realm. |
| Contains(struct { |
| moniker string:fuchsia.component.MAX_MONIKER_LENGTH; |
| }) -> (struct { |
| exists bool; |
| }); |
| |
| /// Assembles the realm being constructed and returns the URL for the root |
| /// component in the realm, which may then be used to create a new component |
| /// in any collection where fuchsia-test-component is properly set up. |
| Commit() -> (struct { |
| root_component_url string:fuchsia.component.types.MAX_URL_LENGTH; |
| }) error RealmBuilderError; |
| |
| /// The component framework is requesting that a mock component start |
| /// running |
| -> OnMockRunRequest(resource struct { |
| mock_id string:MAX_MOCK_ID_LENGTH; |
| start_info MockComponentStartInfo; |
| }); |
| |
| /// The component framework is requesting that a mock component stop |
| /// running |
| -> OnMockStopRequest(struct { |
| mock_id string:MAX_MOCK_ID_LENGTH; |
| }); |
| }; |