blob: 1690fd512aac08c35c3fcc31a468ffa7b496b07e [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.
#ifndef LIB_MODULAR_TESTING_CPP_FAKE_COMPONENT_H_
#define LIB_MODULAR_TESTING_CPP_FAKE_COMPONENT_H_
#include <lib/fidl/cpp/binding_set.h>
#include <lib/modular/testing/cpp/test_harness_builder.h>
#include <lib/sys/cpp/component_context.h>
namespace modular_testing {
// FakeComponent is a utility class for intercepting modular components. This class is
// designed to be used alongside the modular_testing::TestHarnessBuilder::Intercept*() methods.
// Clients may instantiate this class directly, or sub-class and override OnCreate() and
// OnDestroy().
//
// See |modular_testing::FakeAgent| for intercepting a modular Agent.
//
// USAGE:
// ======
// * Pass BuildInterceptOptions() to TestHarnessBuilder::InterceptComponent() to route the
// component's launch to this instance.
// * Use is_running() to determine if the component is running.
// * Use component_context() to connect to incoming services, and add public services.
//
// EXAMPLE:
// ========
// ..
// modular_testing::TestHarnessBuilder builder;
// modular_testing::FakeComponent fake_component(
// {.url = modular_testing::TestHarnessBuilder::GenerateFakeUrl()});
// builder.InterceptComponent(fake_component.BuildInterceptOptions());
// builder.BuildAndRun(test_harness());
// ..
class FakeComponent : fuchsia::modular::Lifecycle {
public:
struct Args {
// Required.
//
// The URL of this component.
std::string url;
// Optional.
std::vector<std::string> sandbox_services;
};
FakeComponent() = delete;
explicit FakeComponent(Args args);
FakeComponent(const FakeComponent&) = delete;
FakeComponent(FakeComponent&&) = delete;
void operator=(const FakeComponent&) = delete;
void operator=(FakeComponent&&) = delete;
~FakeComponent() override;
// Constructs an InterceptOptions struct using the FakeComponent::Args supplied to this instance.
//
// The constructed launch handler takes care of triggering OnCreate() on launch, OnDestroy() on
// destruction.
//
// |dispatcher| is used for serving the component's outgoing directory and dispatching
// |OnDestroy()|. A value of |nullptr| will use the current thread's dispatcher.
modular_testing::TestHarnessBuilder::InterceptOptions BuildInterceptOptions(
async_dispatcher_t* dispatcher = nullptr);
// Returns the URL assigned to this component; see |Args::url|.
std::string url() const;
// Returns true if the component was launched by the component manager and
// has not yet been destroyed.
bool is_running() const;
// Returns the ComponentContext for the running component.
//
// Requires: is_running()
sys::ComponentContext* component_context();
const sys::ComponentContext* component_context() const;
// Instructs the component manager that this component is exiting. See
// documentation for fuchsia.sys.TerminationReason for more details.
//
// Requires: is_running()
void Exit(int64_t exit_code,
fuchsia::sys::TerminationReason reason = fuchsia::sys::TerminationReason::EXITED);
protected:
// Called when the component is created.
//
// The directory handles for "/svc" in |startup_info.flat_namespace| and
// for |startup_info.launch_info.directory_request| will be invalid:
// they are both consumed in the construction of |component_context_|.
//
// Clients may override this to be notified of create as well as to consume
// remaining |startup_info.flat_namespace| entries.
//
// |callback| must be called to finish component creation, and specifically,
// to start serving the component's outgoing directory. All modifications
// to the outgoing directory (e.g. adding services) should be performed
// before |callback| is invoked.
virtual void OnCreateAsync(fuchsia::sys::StartupInfo startup_info,
fit::function<void()> callback) {
OnCreate(std::move(startup_info));
callback();
}
// Called when the component is created by OnCreateAsync.
virtual void OnCreate(fuchsia::sys::StartupInfo startup_info) {}
// Called when |intercepted_componet_ptr_|'s OnKill event is dispatched.
//
// Clients may override this to be notifed of component destruction.
virtual void OnDestroy() {}
// Called when this component receives a fuchsia.modular.Lifecycle/Terminate(). This object will
// |Exit()| when Terminate() is received.
//
// |fuchsia::modular::Lifecycle|
void Terminate() override;
private:
Args args_;
fuchsia::modular::testing::InterceptedComponentPtr intercepted_component_ptr_;
std::unique_ptr<sys::ComponentContext> component_context_;
fidl::BindingSet<fuchsia::modular::Lifecycle> lifecycle_bindings_;
};
} // namespace modular_testing
#endif // LIB_MODULAR_TESTING_CPP_FAKE_COMPONENT_H_