blob: 0597eba5381ccf119cbd986763fd98fce1e6edc5 [file] [log] [blame]
// 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;
});
};