| // 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; |
| }; |