blob: 9b3465f1ced506ae24feafc516c70feb30b5034b [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.
/// # Deprecation
///
/// The Modular framework, which serves and uses these protocols, has been
/// removed from the Fuchsia platform in https://fxrev.dev/871560.
///
/// The fuchsia.session.* and fuchsia.element.* APIs are a replacement
/// for Modular's session and module functionality, respectively.
@available(added=7, removed=13)
library fuchsia.modular.testing;
using fuchsia.mem;
using fuchsia.modular;
using fuchsia.modular.session;
using fuchsia.element;
using fuchsia.sys;
using zx;
/// 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
closed 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.
strict Run(resource struct {
spec TestHarnessSpec;
});
/// 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.
strict -> OnNewComponent(resource struct {
startup_info fuchsia.sys.StartupInfo;
intercepted_component client_end:InterceptedComponent;
});
/// 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.
strict ConnectToModularService(resource struct {
service ModularService;
});
/// Connects to environment services injected into the TestHarness
/// environment.
strict ConnectToEnvironmentService(resource struct {
service_name string;
request zx.Handle:CHANNEL;
});
/// Parses a JSON modular configuration string into BasemgrConfig and
/// SessionmgrConfig. This method may be called before `Run()` is called.
strict ParseConfig(struct {
config string;
}) -> (struct {
basemgr_config fuchsia.modular.session.BasemgrConfig;
sessionmgr_config fuchsia.modular.session.SessionmgrConfig;
});
};
/// Describes which service to connect to using `ConnectToModularService()`.
type ModularService = strict resource union {
1: puppet_master server_end:fuchsia.modular.PuppetMaster;
2: component_context server_end:fuchsia.modular.ComponentContext;
4: element_manager server_end:fuchsia.element.Manager;
};
/// 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.
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.
strict Exit(struct {
exit_code int64;
reason fuchsia.sys.TerminationReason;
});
/// The event is sent when the component is killed by the associated
/// `fuchsia.sys.ComponentController`, or when `Exit()` is called.
strict -> 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`.
///
/// Additional services may be supplied using using
/// `TestHarnessSpec.env_services_to_inherit` and
/// `TestHarnessSpec.injected_services`. Additional services override the
/// default services listed above.
type TestHarnessSpec = resource table {
/// 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: basemgr_config fuchsia.modular.session.BasemgrConfig;
/// Configuration for sessionmgr. See
/// `fuchsia.modular.session.SessionmgrConfig` for a description of the
/// defaults.
2: sessionmgr_config fuchsia.modular.session.SessionmgrConfig;
/// List of component URLs (and additional .cmx contents) to intercept.
4: components_to_intercept vector<InterceptSpec>;
/// Options to configure the test harness environment. Use this to inject
/// services into the environment.
///
/// Optional.
6: env_services EnvironmentServicesSpec;
/// 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: environment_suffix string;
/// DEPRECATED. Use `env_services.service_dir` to pass through services from
/// parent environment.
3: env_services_to_inherit vector<string>;
};
/// 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.
type EnvironmentServicesSpec = resource table {
/// A directory of services to be provided to the test harness environment.
///
/// Optional.
1: service_dir zx.Handle:CHANNEL;
/// 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: services_from_components vector<ComponentService>;
};
/// Describes a service to be provided by a component instance.
type ComponentService = struct {
/// Name of the service.
name string;
/// URL of the component which will provide the service.
/// The service is retrieved from this component's /out/svc namespace.
url fuchsia.sys.component_url;
};
/// Describes a component to intercept. Malformed parameters result in closing
/// `TestHarness` with a `ZX_ERR_INVALID_ARGS` epitaph.
type InterceptSpec = resource table {
/// Required. Must be a valid component URL (e.g., fuchsia-pkg://..), or is
/// considered malformed.
1: component_url fuchsia.sys.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: extra_cmx_contents fuchsia.mem.Buffer;
};