blob: e52b84b1a2526ac6744be8dfd7e21f643db99b34 [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.
[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_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);
/// DEPRECATED. Use |ConnectToModularService()| instead, they are the same.
GetService(TestHarnessService service);
};
/// Describes which service to connect to using |ConnectToModularService()|.
xunion ModularService {
request<fuchsia.modular.PuppetMaster> puppet_master;
request<fuchsia.modular.ComponentContext> component_context;
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.auth.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;
/// The test harness starts the modular runtime in a hermetic environment
/// which does not allow accessing services outside of the environment,
/// unless the service names are specified in this list.
///
/// For example, adding "fuchsia.net.SocketProvider" here allows the
/// hermetic environment to inherit the test process' environment's instance
/// of the socket provider. This lets the test code, and the code under
/// test, to share the same SocketProvider.
3: vector<string> env_services_to_inherit;
/// A list of services and their providers to inject into this environment,
/// along with components which provide them. 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.
5: vector<InjectedService> env_services_to_inject;
/// List of component URLs (and additional .cmx contents) to intercept.
4: vector<InterceptSpec> components_to_intercept;
};
/// Describes a single injected service.
struct InjectedService {
/// Name of the service.
string name;
/// URL of the component which will provide the service (denoted by |name|).
/// The service is retrieved from the 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;
};
/// DEPRECATED. Use |ConnectToModularService| instead.
xunion TestHarnessService {
request<fuchsia.modular.PuppetMaster> puppet_master;
request<fuchsia.modular.ComponentContext> component_context;
request<fuchsia.modular.AgentContext> agent_context;
};