• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2021 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/scoped_fx_logger.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/fidl/cpp/binding.h>
11 #include <lib/sys/cpp/component_context.h>
12 
13 #include "base/fuchsia/fuchsia_component_connect.h"
14 #include "base/fuchsia/fuchsia_logging.h"
15 #include "base/fuchsia/test_component_context_for_process.h"
16 #include "base/fuchsia/test_log_listener_safe.h"
17 #include "base/logging.h"
18 #include "base/test/scoped_logging_settings.h"
19 #include "base/test/task_environment.h"
20 #include "testing/gmock/include/gmock/gmock.h"
21 #include "testing/gtest/include/gtest/gtest.h"
22 
23 namespace base {
24 
25 namespace {
26 
27 class MockLogSource {
28  public:
29   MOCK_METHOD0(Log, const char*());
30 };
31 
32 }  // namespace
33 
34 // Verifies that calling the log macro goes to the Fuchsia system logs, by
35 // default.
TEST(FuchsiaLoggingTest,SystemLogging)36 TEST(FuchsiaLoggingTest, SystemLogging) {
37   constexpr char kLogMessage[] = "This is FuchsiaLoggingTest.SystemLogging!";
38 
39   test::SingleThreadTaskEnvironment task_environment_{
40       test::SingleThreadTaskEnvironment::MainThreadType::IO};
41   SimpleTestLogListener listener;
42   ListenFilteredByCurrentProcessId(listener);
43 
44   // Ensure that logging is directed to the system debug log.
45   logging::ScopedLoggingSettings scoped_logging_settings;
46   CHECK(logging::InitLogging({.logging_dest = logging::LOG_DEFAULT}));
47 
48   // Emit the test log message, and spin the loop until it is reported to the
49   // test listener.
50   LOG(ERROR) << kLogMessage;
51 
52   absl::optional<fuchsia_logger::LogMessage> logged_message =
53       listener.RunUntilMessageReceived(kLogMessage);
54 
55   ASSERT_TRUE(logged_message.has_value());
56   EXPECT_EQ(logged_message->severity(),
57             static_cast<int32_t>(fuchsia_logger::LogLevelFilter::kError));
58   ASSERT_EQ(logged_message->tags().size(), 1u);
59 
60   EXPECT_EQ(logged_message->tags()[0], "base_unittests__exec");
61 }
62 
63 // Verifies that configuring a system logger with multiple tags works.
TEST(FuchsiaLoggingTest,SystemLoggingMultipleTags)64 TEST(FuchsiaLoggingTest, SystemLoggingMultipleTags) {
65   constexpr char kLogMessage[] =
66       "This is FuchsiaLoggingTest.SystemLoggingMultipleTags!";
67   const std::vector<StringPiece> kTags = {"tag1", "tag2"};
68 
69   test::SingleThreadTaskEnvironment task_environment_{
70       test::SingleThreadTaskEnvironment::MainThreadType::IO};
71   SimpleTestLogListener listener;
72   ListenFilteredByCurrentProcessId(listener);
73 
74   // Connect the test LogListenerSafe to the Log.
75   auto log_sink_client_end =
76       fuchsia_component::Connect<fuchsia_logger::LogSink>();
77   EXPECT_TRUE(log_sink_client_end.is_ok())
78       << FidlConnectionErrorMessage(log_sink_client_end);
79 
80   // Create a logger with multiple tags and emit a message to it.
81   ScopedFxLogger logger = ScopedFxLogger::CreateFromLogSink(
82       std::move(log_sink_client_end.value()), kTags);
83   logger.LogMessage("", 0, kLogMessage, FUCHSIA_LOG_ERROR);
84 
85   absl::optional<fuchsia_logger::LogMessage> logged_message =
86       listener.RunUntilMessageReceived(kLogMessage);
87 
88   ASSERT_TRUE(logged_message.has_value());
89   auto tags = std::vector<StringPiece>(logged_message->tags().begin(),
90                                        logged_message->tags().end());
91   EXPECT_EQ(tags, kTags);
92 }
93 
94 // Verifies the Fuchsia-specific ZX_*() logging macros.
TEST(FuchsiaLoggingTest,FuchsiaLogging)95 TEST(FuchsiaLoggingTest, FuchsiaLogging) {
96   MockLogSource mock_log_source;
97   EXPECT_CALL(mock_log_source, Log())
98       .Times(DCHECK_IS_ON() ? 2 : 1)
99       .WillRepeatedly(testing::Return("log message"));
100 
101   logging::ScopedLoggingSettings scoped_logging_settings;
102   logging::SetMinLogLevel(logging::LOGGING_INFO);
103 
104   EXPECT_TRUE(LOG_IS_ON(INFO));
105   EXPECT_EQ(DCHECK_IS_ON(), DLOG_IS_ON(INFO));
106 
107   ZX_LOG(INFO, ZX_ERR_INTERNAL) << mock_log_source.Log();
108   ZX_DLOG(INFO, ZX_ERR_INTERNAL) << mock_log_source.Log();
109 
110   ZX_CHECK(true, ZX_ERR_INTERNAL);
111   ZX_DCHECK(true, ZX_ERR_INTERNAL);
112 }
113 
TEST(FuchsiaLoggingTest,ConnectionErrorMessage)114 TEST(FuchsiaLoggingTest, ConnectionErrorMessage) {
115   zx::result<fidl::ClientEnd<base_testfidl::TestInterface>> result =
116       zx::error_result{ZX_ERR_PEER_CLOSED};
117 
118   EXPECT_EQ(
119       "Failed to connect to base.testfidl.TestInterface: "
120       "ZX_ERR_PEER_CLOSED",
121       base::FidlConnectionErrorMessage(result));
122 }
123 
TEST(FuchsiaLoggingTest,FidlMethodErrorMessage_TwoWay)124 TEST(FuchsiaLoggingTest, FidlMethodErrorMessage_TwoWay) {
125   fidl::Result<base_testfidl::TestInterface::Add> result =
126       fit::error(fidl::Status::Unbound());
127 
128   EXPECT_EQ(
129       "Error calling Add: FIDL operation failed due to user initiated unbind, "
130       "status: ZX_ERR_CANCELED (-23), detail: unbound endpoint",
131       base::FidlMethodResultErrorMessage(result, "Add"));
132 }
133 
TEST(FuchsiaLoggingTest,FidlMethodErrorMessage_OneWay)134 TEST(FuchsiaLoggingTest, FidlMethodErrorMessage_OneWay) {
135   fit::result<fidl::OneWayError> result = fit::error(fidl::Status::Unbound());
136 
137   EXPECT_EQ(
138       "Error calling Add: FIDL operation failed due to user initiated unbind, "
139       "status: ZX_ERR_CANCELED (-23), detail: unbound endpoint",
140       base::FidlMethodResultErrorMessage(result, "Add"));
141 }
142 
TEST(FuchsiaLoggingTest,FidlBindingClosureWarningLogger)143 TEST(FuchsiaLoggingTest, FidlBindingClosureWarningLogger) {
144   test::SingleThreadTaskEnvironment task_environment{
145       test::SingleThreadTaskEnvironment::MainThreadType::IO};
146   SimpleTestLogListener listener;
147 
148   // Ensure that logging is directed to the system debug log.
149   logging::ScopedLoggingSettings scoped_logging_settings;
150   TestComponentContextForProcess test_context;
151   test_context.AddService(fidl::DiscoverableProtocolName<fuchsia_logger::Log>);
152   ListenFilteredByCurrentProcessId(listener);
153 
154   // Initialize logging in the `scoped_logging_settings_`.
155   CHECK(logging::InitLogging({.logging_dest = logging::LOG_DEFAULT}));
156 
157   base::FidlBindingClosureWarningLogger<base_testfidl::TestInterface>()(
158       fidl::UnbindInfo::PeerClosed(ZX_ERR_PEER_CLOSED));
159 
160   absl::optional<fuchsia_logger::LogMessage> logged_message =
161       listener.RunUntilMessageReceived(
162           "base.testfidl.TestInterface unbound: ZX_ERR_PEER_CLOSED (-24)");
163 
164   ASSERT_TRUE(logged_message.has_value());
165   EXPECT_EQ(logged_message->severity(),
166             static_cast<int32_t>(fuchsia_logger::LogLevelFilter::kWarn));
167 }
168 
169 }  // namespace base
170