xref: /aosp_15_r20/external/cronet/base/fuchsia/fidl_event_handler_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2023 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "base/fuchsia/fidl_event_handler.h"
6 
7 #include <fidl/base.testfidl/cpp/fidl.h>
8 #include <fidl/fuchsia.logger/cpp/fidl.h>
9 #include <lib/sys/cpp/component_context.h>
10 
11 #include "base/fuchsia/fuchsia_component_connect.h"
12 #include "base/fuchsia/process_context.h"
13 #include "base/fuchsia/scoped_service_binding.h"
14 #include "base/fuchsia/test_component_context_for_process.h"
15 #include "base/fuchsia/test_interface_natural_impl.h"
16 #include "base/fuchsia/test_log_listener_safe.h"
17 #include "base/task/thread_pool.h"
18 #include "base/test/bind.h"
19 #include "base/test/scoped_logging_settings.h"
20 #include "base/test/task_environment.h"
21 #include "testing/gmock/include/gmock/gmock.h"
22 #include "testing/gtest/include/gtest/gtest.h"
23 
24 namespace {
25 
26 constexpr char kBaseUnittestsExec[] = "base_unittests__exec";
27 
28 }  // namespace
29 
30 namespace base {
31 
32 class FidlEventHandlerTest : public testing::Test {
33  public:
FidlEventHandlerTest()34   FidlEventHandlerTest() {
35     test_context_.AddService(
36         fidl::DiscoverableProtocolName<fuchsia_logger::Log>);
37     ListenFilteredByCurrentProcessId(listener_);
38     // Initialize logging in the `scoped_logging_settings_`.
39     CHECK(logging::InitLogging({.logging_dest = logging::LOG_DEFAULT}));
40   }
41   FidlEventHandlerTest(const FidlEventHandlerTest&) = delete;
42   FidlEventHandlerTest& operator=(const FidlEventHandlerTest&) = delete;
43   ~FidlEventHandlerTest() override = default;
44 
45  protected:
46   test::SingleThreadTaskEnvironment task_environment_{
47       test::SingleThreadTaskEnvironment::MainThreadType::IO};
48   SimpleTestLogListener listener_;
49 
50   // Ensure that logging is directed to the system debug log.
51   logging::ScopedLoggingSettings scoped_logging_settings_;
52   TestComponentContextForProcess test_context_;
53   TestInterfaceNaturalImpl test_service_;
54 };
55 
TEST_F(FidlEventHandlerTest,FidlErrorEventLogger)56 TEST_F(FidlEventHandlerTest, FidlErrorEventLogger) {
57   FidlErrorEventLogger<base_testfidl::TestInterface> event_handler;
58 
59   event_handler.on_fidl_error(fidl::UnbindInfo::PeerClosed(ZX_ERR_PEER_CLOSED));
60 
61   constexpr char kLogMessage[] =
62       "base.testfidl.TestInterface was disconnected with ZX_ERR_PEER_CLOSED";
63   std::optional<fuchsia_logger::LogMessage> logged_message =
64       listener_.RunUntilMessageReceived(kLogMessage);
65 
66   ASSERT_TRUE(logged_message.has_value());
67   EXPECT_EQ(logged_message->severity(),
68             static_cast<int32_t>(fuchsia_logger::LogLevelFilter::kError));
69   ASSERT_EQ(logged_message->tags().size(), 1u);
70   EXPECT_EQ(logged_message->tags()[0], kBaseUnittestsExec);
71 }
72 
TEST_F(FidlEventHandlerTest,FidlErrorEventLogger_CustomProtocolName)73 TEST_F(FidlEventHandlerTest, FidlErrorEventLogger_CustomProtocolName) {
74   FidlErrorEventLogger<base_testfidl::TestInterface> event_handler(
75       "test_protocol_name");
76 
77   event_handler.on_fidl_error(fidl::UnbindInfo::PeerClosed(ZX_ERR_PEER_CLOSED));
78 
79   constexpr char kLogMessage[] =
80       "test_protocol_name was disconnected with ZX_ERR_PEER_CLOSED";
81   std::optional<fuchsia_logger::LogMessage> logged_message =
82       listener_.RunUntilMessageReceived(kLogMessage);
83 
84   ASSERT_TRUE(logged_message.has_value());
85   EXPECT_EQ(logged_message->severity(),
86             static_cast<int32_t>(fuchsia_logger::LogLevelFilter::kError));
87   ASSERT_EQ(logged_message->tags().size(), 1u);
88   EXPECT_EQ(logged_message->tags()[0], kBaseUnittestsExec);
89 }
90 
TEST_F(FidlEventHandlerTest,FidlErrorEventLogger_LogsOnServiceClosure)91 TEST_F(FidlEventHandlerTest, FidlErrorEventLogger_LogsOnServiceClosure) {
92   FidlErrorEventLogger<base_testfidl::TestInterface> event_handler;
93   auto client_end = fuchsia_component::ConnectAt<base_testfidl::TestInterface>(
94       test_context_.published_services_natural());
95   EXPECT_TRUE(client_end.is_ok());
96   fidl::Client client(std::move(*client_end), async_get_default_dispatcher(),
97                       &event_handler);
98 
99   {
100     ScopedNaturalServiceBinding<base_testfidl::TestInterface> binding(
101         ComponentContextForProcess()->outgoing().get(), &test_service_);
102 
103     ASSERT_EQ(ZX_OK, VerifyTestInterface(client));
104   };
105 
106   constexpr char kLogMessage[] =
107       "base.testfidl.TestInterface was disconnected with ZX_ERR_PEER_CLOSED";
108   std::optional<fuchsia_logger::LogMessage> logged_message =
109       listener_.RunUntilMessageReceived(kLogMessage);
110 
111   ASSERT_TRUE(logged_message.has_value());
112   EXPECT_EQ(logged_message->severity(),
113             static_cast<int32_t>(fuchsia_logger::LogLevelFilter::kError));
114   ASSERT_EQ(logged_message->tags().size(), 1u);
115   EXPECT_EQ(logged_message->tags()[0], kBaseUnittestsExec);
116 }
117 
TEST(FidlEventHandlerDeathTest,FidlErrorEventProcessExiter)118 TEST(FidlEventHandlerDeathTest, FidlErrorEventProcessExiter) {
119   FidlErrorEventProcessExiter<base_testfidl::TestInterface> event_handler;
120 
121   EXPECT_DEATH(
122       event_handler.on_fidl_error(
123           fidl::UnbindInfo::PeerClosed(ZX_ERR_PEER_CLOSED)),
124       testing::HasSubstr("base.testfidl.TestInterface disconnected "
125                          "unexpectedly, exiting: ZX_ERR_PEER_CLOSED (-24)"));
126 }
127 
TEST(FidlEventHandlerDeathTest,FidlErrorEventProcessExiter_CustomProtocolName)128 TEST(FidlEventHandlerDeathTest,
129      FidlErrorEventProcessExiter_CustomProtocolName) {
130   FidlErrorEventProcessExiter<base_testfidl::TestInterface> event_handler(
131       "test_protocol_name");
132 
133   EXPECT_DEATH(
134       event_handler.on_fidl_error(
135           fidl::UnbindInfo::PeerClosed(ZX_ERR_PEER_CLOSED)),
136       testing::HasSubstr("test_protocol_name disconnected unexpectedly, "
137                          "exiting: ZX_ERR_PEER_CLOSED (-24)"));
138 }
139 
TEST(FidlEventHandlerDeathTest,FidlErrorEventProcessExiter_LogsOnServiceClosure)140 TEST(FidlEventHandlerDeathTest,
141      FidlErrorEventProcessExiter_LogsOnServiceClosure) {
142   test::SingleThreadTaskEnvironment task_environment_{
143       test::SingleThreadTaskEnvironment::MainThreadType::IO};
144   TestComponentContextForProcess test_context;
145   FidlErrorEventProcessExiter<base_testfidl::TestInterface> event_handler;
146   auto client_end = fuchsia_component::ConnectAt<base_testfidl::TestInterface>(
147       test_context.published_services_natural());
148   EXPECT_TRUE(client_end.is_ok());
149   fidl::Client client(std::move(*client_end), async_get_default_dispatcher(),
150                       &event_handler);
151 
152   auto bind_and_close_service = [&]() {
153     {
154       TestInterfaceNaturalImpl test_service;
155       ScopedNaturalServiceBinding<base_testfidl::TestInterface> binding(
156           ComponentContextForProcess()->outgoing().get(), &test_service);
157 
158       ASSERT_EQ(ZX_OK, VerifyTestInterface(client));
159     }
160     base::RunLoop().RunUntilIdle();
161   };
162 
163   EXPECT_DEATH(
164       bind_and_close_service(),
165       testing::HasSubstr("base.testfidl.TestInterface disconnected "
166                          "unexpectedly, exiting: ZX_ERR_PEER_CLOSED (-24)"));
167 }
168 
TEST_F(FidlEventHandlerTest,FidlErrorEventHandler)169 TEST_F(FidlEventHandlerTest, FidlErrorEventHandler) {
170   RunLoop loop;
171   FidlErrorEventHandler<base_testfidl::TestInterface> event_handler(
172       base::BindLambdaForTesting(
173           [quit_closure = loop.QuitClosure()](fidl::UnbindInfo error) {
174             ASSERT_TRUE(error.is_peer_closed());
175             quit_closure.Run();
176           }));
177 
178   event_handler.on_fidl_error(fidl::UnbindInfo::PeerClosed(ZX_ERR_PEER_CLOSED));
179 
180   loop.Run();
181 }
182 
TEST_F(FidlEventHandlerTest,FidlErrorEventHandler_FiresOnServiceClosure)183 TEST_F(FidlEventHandlerTest, FidlErrorEventHandler_FiresOnServiceClosure) {
184   RunLoop loop;
185   FidlErrorEventHandler<base_testfidl::TestInterface> event_handler(
186       base::BindLambdaForTesting(
187           [quit_closure = loop.QuitClosure()](fidl::UnbindInfo error) {
188             ASSERT_TRUE(error.is_peer_closed());
189             quit_closure.Run();
190           }));
191 
192   auto client_end = fuchsia_component::ConnectAt<base_testfidl::TestInterface>(
193       test_context_.published_services_natural());
194   EXPECT_TRUE(client_end.is_ok());
195   fidl::Client client(std::move(*client_end), async_get_default_dispatcher(),
196                       &event_handler);
197 
198   {
199     ScopedNaturalServiceBinding<base_testfidl::TestInterface> binding(
200         ComponentContextForProcess()->outgoing().get(), &test_service_);
201 
202     ASSERT_EQ(ZX_OK, VerifyTestInterface(client));
203   };
204 
205   loop.Run();
206 }
207 
208 }  // namespace base
209