blob: 404904c856967077c95cf4d93c767184d879b845 [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.
#include <fuchsia/modular/cpp/fidl.h>
#include <lib/gtest/real_loop_fixture.h>
#include <lib/modular/cpp/agent.h>
#include <lib/sys/cpp/testing/component_context_provider.h>
#include <test/modular/agent/cpp/fidl.h>
class AgentTest : public gtest::RealLoopFixture, public test::modular::agent::Pinger {
protected:
int ping_count() { return ping_count_; }
private:
// |test::modular::agent::Pinger|
void Ping() override { ping_count_++; }
int ping_count_ = 0;
};
// Test that a Lifecycle/Terminate signal will cause Agent and Lifecycle interfaces to close out and
// a termination callback to be called.
TEST_F(AgentTest, LifecycleTerminate) {
sys::testing::ComponentContextProvider ctx_provider;
bool terminated = false;
modular::Agent agent(ctx_provider.context()->outgoing(), [&terminated] { terminated = true; });
auto lifecycle_ptr = ctx_provider.ConnectToPublicService<fuchsia::modular::Lifecycle>();
auto agent_ptr = ctx_provider.ConnectToPublicService<fuchsia::modular::Agent>();
lifecycle_ptr->Terminate();
// Check that |on_terminate| was invoked, agent & lifecycle interfaces are closed.
RunLoopUntil([&] { return terminated && !lifecycle_ptr && !agent_ptr; });
}
// Test that modular::Agent::AddService<>() adds services which can be acquired using
// |Agent.Connect|.
TEST_F(AgentTest, AddService) {
sys::testing::ComponentContextProvider ctx_provider;
// Setup the agent and expose the pinger service.
modular::Agent agent(ctx_provider.context()->outgoing(), [] {});
fidl::BindingSet<test::modular::agent::Pinger> pinger_bindings;
agent.AddService<test::modular::agent::Pinger>(pinger_bindings.GetHandler(this));
// Connect to the Pinger agent service.
auto agent_ptr = ctx_provider.ConnectToPublicService<fuchsia::modular::Agent>();
fuchsia::sys::ServiceProviderPtr sp;
agent_ptr->Connect("", sp.NewRequest());
test::modular::agent::PingerPtr pinger;
sp->ConnectToService(test::modular::agent::Pinger::Name_, pinger.NewRequest().TakeChannel());
pinger->Ping();
// Check that Pinger/Ping() was received; this should verify that Pinger was registered
RunLoopUntil([this]() { return ping_count() > 0; });
}
TEST_F(AgentTest, ReentrentDestroy) {
sys::testing::ComponentContextProvider ctx_provider;
std::unique_ptr<modular::Agent> agent;
auto val = std::make_unique<int>(42);
agent =
std::make_unique<modular::Agent>(ctx_provider.context()->outgoing(),
/* on_terminate */ [&agent, val = std::move(val)]() mutable {
agent.reset();
// this should abort/crash if |on_terminate| wasn't
// reentrant after |agent| is destroyed:
*val.get() += 1;
});
auto lifecycle_ptr = ctx_provider.ConnectToPublicService<fuchsia::modular::Lifecycle>();
lifecycle_ptr->Terminate();
RunLoopUntil([&] { return !lifecycle_ptr; });
}