| // 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(); |
| }); |
| }); |
| } |
| |
| TestModule(modular::ModuleHost* const module_host, |
| fidl::InterfaceRequest< |
| fuchsia::ui::viewsv1::ViewProvider> /*view_provider_request*/) |
| : TestModule( |
| module_host, |
| fidl::InterfaceRequest<fuchsia::ui::app::ViewProvider>(nullptr)) {} |
| |
| 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(const std::function<void()>& done) { |
| stopped_.Pass(); |
| modular::testing::Done(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; |
| } |