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

    /// DEPRECATED. Use |ConnectToModularService()| instead.
    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;

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

    /// DEPRECATED. Use |env_services.service_dir| to pass through services from
    /// parent environment.
    3: vector<string> env_services_to_inherit;

    /// DEPRECATED. Use |env_services.services_from_components| instead.
    5: vector<InjectedService> env_services_to_inject;
};

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

/// DEPRECATED. Use |ConnectToModularService| instead.
xunion TestHarnessService {
    request<fuchsia.modular.PuppetMaster> puppet_master;
    request<fuchsia.modular.ComponentContext> component_context;
    request<fuchsia.modular.AgentContext> agent_context;
};

/// DEPRECATED. Renamed to ComponentService.
struct InjectedService {
    /// 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;
};

