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