// 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.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]
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()`.
resource union ModularService {
    1: request<fuchsia.modular.PuppetMaster> puppet_master;
    2: request<fuchsia.modular.ComponentContext> component_context;
    3: reserved;
    4: request<fuchsia.element.Manager> 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.
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.
resource 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.
resource 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.
resource 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;
};
