blob: 016e2c1df001df2c3c1dcf3e2d10831b072e351a [file] [log] [blame]
// Copyright 2019 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.modular.testing;
using fuchsia.mem;
using fuchsia.modular;
using fuchsia.modular.session;
using fuchsia.sys;
/// The `TestHarness` service is used to run the modular runtime under a
/// hermetic environment and drive integration tests under it. Tests may use
/// this service to intercept components and assume their role. Additionally,
/// tests may use `TestHarness/ConnectToModularService()` to get capabilities
/// for controlling stories (using PuppetMaster) and connecting to agents
/// (using ComponentContext).
///
/// Closing the `TestHarness` connection will kill the `TestHarness` environment
/// including the modular runtime running under it.
///
/// On error, this connection is closed with the following epitaphs:
/// * `ZX_ERR_INVALID_ARGS`: Run() failed to execute succesfully.
/// * `ZX_ERR_BAD_STATE`: Other methods are called before Run() is called.
/// * `ZX_ERR_ALREADY_BOUND`: Run() was already called.
/// * `ZX_ERR_ALREADY_EXISTS`: The same environment service is being provided
/// twice.
[Discoverable]
protocol TestHarness {
/// Initializes an instance of the modular runtime in an enclosed
/// environment, configured with parameters provided in `spec`. Closing the
/// `TestHarness` connection will kill the enclosed environment.
///
/// This protocol connection is closed if Run() fails, with the following
/// epitaphs:
/// * `ZX_ERR_INVALID_ARGS`: `spec` is mal-formed.
/// * `ZX_ERR_ALREADY_EXISTS`: The same environment service is being provided
/// twice in `spec.env_services`
/// * `ZX_ERR_ALREADY_BOUND`: Run() was already called.
Run(TestHarnessSpec spec);
/// This event is sent when a component specified in
/// `TestHarnessSpec.components_to_intercept` is created.
/// `startup_info.launch_info.url` contains the component URL.
///
/// Closing `intercepted_component` will signal to the component manager
/// that this component has exited unexpectedly. Prefer to use
/// InterceptedComponent/Exit to provide exit code and reason.
-> OnNewComponent(fuchsia.sys.StartupInfo startup_info,
InterceptedComponent intercepted_component);
/// Tests may use this method to connect to services provided by the modular
/// runtime. These services share the same component namespace for any
/// resources they create (e.g., entities, message queues, and module
/// names).
///
/// This protocol connection is closed with the following epitaphs:
/// * `ZX_ERR_BAD_STATE`: if `ConnectToModularService()` is called before
/// `Run()`.
/// * `ZX_ERR_INVALID_ARGS`: if `service` is not set to a value.
ConnectToModularService(ModularService service);
/// Connects to environment services injected into the TestHarness
/// environment.
ConnectToEnvironmentService(string service_name, handle<channel> request);
/// Parses a JSON modular configuration string into BasemgrConfig and
/// SessionmgrConfig. This method may be called before `Run()` is called.
ParseConfig(string config)
-> (fuchsia.modular.session.BasemgrConfig basemgr_config,
fuchsia.modular.session.SessionmgrConfig sessionmgr_config);
};
/// Describes which service to connect to using `ConnectToModularService()`.
union ModularService {
1: request<fuchsia.modular.PuppetMaster> puppet_master;
2: request<fuchsia.modular.ComponentContext> component_context;
3: request<fuchsia.modular.AgentContext> agent_context;
};
/// InterceptedComponent represents an intercepted component's lifecycle.
/// Closing this connection causes the component to be killed, and is
/// equivalent in behaviour to the `ComponentController` being closed.
protocol InterceptedComponent {
/// Signals that component has exit'd with the specified exit code. The
/// values here are bubbled up to the
/// `fuchsia.sys.ComponentController.OnTerminated` event. The `OnKill` event
/// is sent, and this InterceptedComponent handle is closed.
Exit(int64 exit_code, fuchsia.sys.TerminationReason reason);
/// The event is sent when the component is killed by the associated
/// `fuchsia.sys.ComponentController`, or when `Exit()` is called.
-> OnKill();
};
/// Defines the setup of an environment running an instance of the modular
/// framework used for testing purposes. This table is supplied to
/// `TestHarness.Run()`. A malformed `TestHarnessSpec` will cause `TestHarness`
/// connection to close with an epitaph of `ZX_ERR_INVALID_ARGS`.
///
/// By default, the following services are made available to the hermetic
/// environment:
/// * fuchsia.identity.account.AccountManager
/// * fuchsia.devicesettings.DeviceSettingsManager
///
/// Additional services may be supplied using using
/// `TestHarnessSpec.env_services_to_inherit` and
/// `TestHarnessSpec.injected_services`. Additional services override the
/// default services listed above.
table TestHarnessSpec {
/// Configuration for basemgr. See `fuchsia.modular.session.BasemgrConfig`
/// for a description of the defaults.
///
/// The test harness will amend `basemgr_config` before passing it off to
/// the modular runtime in the following way:
/// * If `basemgr_config.base_shell.app_config.url` is not set, the test
/// harness will use a base shell which automatically logs into the
/// session.
/// * If `basemgr_config.session_shell_map[0].config.app_config.url` is not
/// set, the test harness will use a shell which automatically starts new
/// stories.
/// * If `basemgr_config.story_shell.app_config.url` is not set, the test
/// harness use a minimally functioning story shell which displays all
/// mods in a story.
///
/// To intercept and mock the shells, users may provide fake URLs for the
/// shells and specify that the fake URL be intercepted using
/// `components_to_intercept`.
1: fuchsia.modular.session.BasemgrConfig basemgr_config;
/// Configuration for sessionmgr. See
/// `fuchsia.modular.session.SessionmgrConfig` for a description of the
/// defaults.
2: fuchsia.modular.session.SessionmgrConfig sessionmgr_config;
/// List of component URLs (and additional .cmx contents) to intercept.
4: vector<InterceptSpec> components_to_intercept;
/// Options to configure the test harness environment. Use this to inject
/// services into the environment.
///
/// Optional.
6: EnvironmentServicesSpec env_services;
/// Suffix to the environment name.
/// The default environment name is 'mth_{random number from 0 to 99999}'.
/// When provided, the environment_suffix additionally appends a '_' and
/// the string to the end of the environment name. The overall name gets
/// truncated at 32 characters.
///
/// Optional.
7: string environment_suffix;
/// DEPRECATED. Use `env_services.service_dir` to pass through services from
/// parent environment.
3: vector<string> env_services_to_inherit;
5: reserved;
};
/// Options for configuring the test harness environment with services.
///
/// If the same service is provided in more than one place, `TestHarness`
/// connection is closed with a `ZX_ERR_ALREADY_EXISTS` epitaph.
table EnvironmentServicesSpec {
/// A directory of services to be provided to the test harness environment.
///
/// Optional.
1: handle<channel> service_dir;
/// A list of services provided by components to inject into the test
/// harness environment. Multiple services may be provided by the same
/// component, but only one instance of the component is launched to serve
/// its services. Components are started when one of their services is
/// requested, and are kept alive for the duration of the test harness
/// environment's life.
///
/// Optional.
2: vector<ComponentService> services_from_components;
};
/// Describes a service to be provided by a component instance.
struct ComponentService {
/// Name of the service.
string name;
/// URL of the component which will provide the service.
/// The service is retrieved from this component's /out/svc namespace.
fuchsia.sys.component_url url;
};
/// Describes a component to intercept. Malformed parameters result in closing
/// `TestHarness` with a `ZX_ERR_INVALID_ARGS` epitaph.
table InterceptSpec {
/// Required. Must be a valid component URL (e.g., fuchsia-pkg://..), or is
/// considered malformed.
1: fuchsia.sys.component_url component_url;
/// The .cmx contents of this component's manifest. A minimal manifest is
/// constructed by default. If set, the contents of `extra_cmx_contents`
/// override the default constructed manifest, which only has the required
/// "program.binary" field defined.
///
/// `extra_cmx_contents` must be a valid .cmx JSON. Example:
///
/// {
/// "sandbox": {
/// "services": [
/// "fuchsia.sys.Launcher",
/// ]
/// }
/// }
2: fuchsia.mem.Buffer extra_cmx_contents;
};