blob: 8dd487ef106e873a12e95145b4d8f95f98c07cf9 [file] [log] [blame]
// Copyright 2017 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/app_driver/cpp/module_driver.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async/cpp/task.h>
#include <lib/async/default.h>
#include <lib/component/cpp/connect.h>
#include <lib/message_queue/cpp/message_sender_client.h>
#include <test/peridot/tests/trigger/cpp/fidl.h>
#include "peridot/public/lib/integration_testing/cpp/reporting.h"
#include "peridot/public/lib/integration_testing/cpp/testing.h"
#include "peridot/tests/trigger/defs.h"
using ::modular::testing::Await;
using ::modular::testing::Signal;
using ::modular::testing::TestPoint;
using ::test::peridot::tests::trigger::TriggerTestServicePtr;
namespace {
// Cf. README.md for what this test does and how.
class TestModule {
public:
TestPoint initialized_{"Root module initialized"};
TestModule(modular::ModuleHost* const module_host,
fidl::InterfaceRequest<
fuchsia::ui::app::ViewProvider> /*view_provider_request*/) {
modular::testing::Init(module_host->startup_context(), __FILE__);
initialized_.Pass();
// Exercise fuchsia::modular::ComponentContext.ConnectToAgent()
module_host->module_context()->GetComponentContext(
component_context_.NewRequest());
fuchsia::sys::ServiceProviderPtr agent_services;
component_context_->ConnectToAgent(kTestAgent, agent_services.NewRequest(),
agent_controller_.NewRequest());
component::ConnectToService(agent_services.get(),
agent_service_.NewRequest());
// The message queue that is used to verify deletion triggers from explicit
// deletes.
component_context_->ObtainMessageQueue("explicit_test",
explicit_msg_queue_.NewRequest());
// The message queue that is used to verify deletion triggers from deletes
// when the module's namespace is torn down. The test session shell will
// verify that the agent is notified of this queues deletion.
component_context_->ObtainMessageQueue("implicit_test",
implicit_msg_queue_.NewRequest());
implicit_msg_queue_->GetToken([this](fidl::StringPtr token) {
modular::testing::GetStore()->Put("trigger_test_module_queue_token",
token, [] {});
agent_service_->ObserveMessageQueueDeletion(token);
explicit_msg_queue_->GetToken([this](fidl::StringPtr token) {
explicit_queue_token_ = token;
agent_service_->ObserveMessageQueueDeletion(std::move(token));
TestMessageQueueMessageTrigger();
});
});
}
TestPoint received_trigger_token_{"Received trigger token"};
TestPoint agent_connected_{"fuchsia::modular::Agent accepted connection"};
TestPoint agent_stopped_{"fuchsia::modular::Agent stopped"};
TestPoint task_triggered_{"fuchsia::modular::Agent task triggered"};
void TestMessageQueueMessageTrigger() {
Await("trigger_test_agent_connected", [this] {
agent_connected_.Pass();
agent_service_->GetMessageQueueToken([this](fidl::StringPtr token) {
received_trigger_token_.Pass();
// Stop the agent.
agent_controller_.Unbind();
Await("trigger_test_agent_stopped", [this, token] {
agent_stopped_.Pass();
// Send a message to the stopped agent which should
// trigger it.
component_context_->GetMessageSender(token,
message_sender_.NewRequest());
message_sender_.Send("Time to wake up...");
Await("message_queue_message", [this] {
task_triggered_.Pass();
Await("trigger_test_agent_stopped",
[this] { TestMessageQueueDeletionTrigger(); });
});
});
});
});
}
TestPoint queue_deleted_{"Message queue deletion task triggered."};
void TestMessageQueueDeletionTrigger() {
fuchsia::sys::ServiceProviderPtr agent_services;
component_context_->ConnectToAgent(kTestAgent, agent_services.NewRequest(),
agent_controller_.NewRequest());
component::ConnectToService(agent_services.get(),
agent_service_.NewRequest());
// First wait for the agent to connect, and then kill it.
Await("trigger_test_agent_connected", [this] {
Await("trigger_test_agent_token_received", [this] {
agent_controller_.Unbind();
Await("trigger_test_agent_stopped", [this] {
// When the agent has stopped, delete the message queue and verify
// that the agent is woken up and notified.
component_context_->DeleteMessageQueue("explicit_test");
Await(explicit_queue_token_, [this] {
queue_deleted_.Pass();
Signal("trigger_test_module_done");
});
});
});
});
}
TestPoint stopped_{"Root module stopped"};
// Called by ModuleDriver.
void Terminate(fit::function<void()> done) {
stopped_.Pass();
modular::testing::Done(std::move(done));
}
private:
fuchsia::modular::AgentControllerPtr agent_controller_;
TriggerTestServicePtr agent_service_;
fuchsia::modular::ComponentContextPtr component_context_;
// The queue used for observing explicit queue deletion.
fuchsia::modular::MessageQueuePtr explicit_msg_queue_;
std::string explicit_queue_token_;
// The queue used for observing queue deletion when module's namespace is torn
// down.
fuchsia::modular::MessageQueuePtr implicit_msg_queue_;
modular::MessageSenderClient message_sender_;
FXL_DISALLOW_COPY_AND_ASSIGN(TestModule);
};
} // namespace
int main(int /*argc*/, const char** /*argv*/) {
async::Loop loop(&kAsyncLoopConfigAttachToThread);
auto context = component::StartupContext::CreateFromStartupInfo();
modular::ModuleDriver<TestModule> driver(context.get(),
[&loop] { loop.Quit(); });
loop.Run();
return 0;
}