|  | // 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; | 
|  | 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] | 
|  | 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, zx.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: reserved; | 
|  | }; | 
|  |  | 
|  | /// 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.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: zx.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; | 
|  | }; |