Flutter Engine
 
Loading...
Searching...
No Matches
log_interest_listener_unittests.cc
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
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 <fidl/fuchsia.diagnostics.types/cpp/fidl.h>
6#include <fidl/fuchsia.logger/cpp/fidl.h>
7#include <lib/async-loop/cpp/loop.h>
8#include <lib/async-loop/default.h>
9#include <lib/async-loop/testing/cpp/real_loop.h>
10#include <lib/async/dispatcher.h>
11#include <lib/component/incoming/cpp/protocol.h>
12#include <lib/fidl/cpp/client.h>
13#include <lib/fidl/cpp/wire/channel.h>
14#include <lib/fidl/cpp/wire/connect_service.h>
15#include <lib/fit/defer.h>
16#include <lib/fit/result.h>
17#include <lib/sys/component/cpp/testing/realm_builder.h>
18#include <lib/sys/component/cpp/testing/realm_builder_types.h>
19#include <zircon/errors.h>
20
23#include "gtest/gtest.h"
24
25namespace fml {
26namespace testing {
27
28constexpr static char kLogSink[] = "log_sink";
29
30using fuchsia_diagnostics_types::Interest;
31using fuchsia_diagnostics_types::Severity;
32
33class LogInterestListenerFuchsia : public ::loop_fixture::RealLoop,
34 public ::testing::Test {};
35
37 ScopedSetLogSettings backup({.min_log_level = kLogInfo});
38
39 const struct {
40 Severity severity;
41 int expected_log_level;
42 const char* name;
43 } kTestCases[] = {
44 {Severity::kTrace, -1, "VERBOSE"},
45 {Severity::kInfo, kLogInfo, "INFO"},
46 {Severity::kWarn, kLogWarning, "WARNING"},
47 {Severity::kError, kLogError, "ERROR"},
48 {Severity::kFatal, kLogFatal, "FATAL"},
49 };
50
51 for (const auto& test_case : kTestCases) {
52 SCOPED_TRACE(test_case.name);
53 Interest interest;
54 interest.min_severity(test_case.severity);
56 EXPECT_EQ(GetMinLogLevel(), test_case.expected_log_level);
57 }
58}
59
60// Class to mock the server end of a LogSink.
61class MockLogSink : public component_testing::LocalComponentImpl,
62 public fidl::Server<fuchsia_logger::LogSink> {
63 public:
64 MockLogSink(fit::closure quitLoop, async_dispatcher_t* dispatcher)
65 : quit_loop_(std::move(quitLoop)), dispatcher_(dispatcher) {}
66
68 WaitForInterestChangeCompleter::Sync& completer) override {
69 if (first_call_) {
70 // If it has not been called before, then return a result right away.
71 fuchsia_logger::LogSinkWaitForInterestChangeResponse response = {
72 {.data = {{.min_severity = Severity::kWarn}}}};
73 completer.Reply(fit::ok(response));
74 first_call_ = false;
75 } else {
76 // On the second call, don't return a result.
77 completer_.emplace(completer.ToAsync());
78 quit_loop_();
79 }
80 }
81
83 fuchsia_logger::LogSinkConnectStructuredRequest& request,
84 ConnectStructuredCompleter::Sync& completer) override {}
85
86 void OnStart() override {
87 ASSERT_EQ(outgoing()->AddProtocol<fuchsia_logger::LogSink>(
88 bindings_.CreateHandler(this, dispatcher_,
89 fidl::kIgnoreBindingClosure)),
90 ZX_OK);
91 }
92
94 fidl::UnknownMethodMetadata<fuchsia_logger::LogSink> metadata,
95 fidl::UnknownMethodCompleter::Sync& completer) override {}
96
97 private:
98 bool first_call_ = true;
99 fit::closure quit_loop_;
100 async_dispatcher_t* dispatcher_;
101 fidl::ServerBindingGroup<fuchsia_logger::LogSink> bindings_;
102 std::optional<WaitForInterestChangeCompleter::Async> completer_;
103};
104
105TEST_F(LogInterestListenerFuchsia, AsyncWaitForInterestChange) {
106 ScopedSetLogSettings backup({.min_log_level = kLogInfo});
107 auto realm_builder = component_testing::RealmBuilder::Create();
108 realm_builder.AddLocalChild(kLogSink, [&]() {
109 return std::make_unique<MockLogSink>(QuitLoopClosure(), dispatcher());
110 });
111 realm_builder.AddRoute(component_testing::Route{
112 .capabilities = {component_testing::Protocol{
113 fidl::DiscoverableProtocolName<fuchsia_logger::LogSink>}},
114 .source = component_testing::ChildRef{kLogSink},
115 .targets = {component_testing::ParentRef()}});
116
117 auto realm = realm_builder.Build(dispatcher());
118 auto cleanup = fit::defer([&]() {
119 bool complete = false;
120 realm.Teardown([&](auto result) { complete = true; });
121 RunLoopUntil([&]() { return complete; });
122 });
123 auto client_end = realm.component().Connect<fuchsia_logger::LogSink>();
124 ASSERT_TRUE(client_end.is_ok());
125 LogInterestListener listener(std::move(client_end.value()), dispatcher());
127 RunLoop();
128
129 EXPECT_EQ(GetMinLogLevel(), kLogWarning);
130}
131
132} // namespace testing
133} // namespace fml
static void HandleInterestChange(const fuchsia_diagnostics_types::Interest &interest)
MockLogSink(fit::closure quitLoop, async_dispatcher_t *dispatcher)
void handle_unknown_method(fidl::UnknownMethodMetadata< fuchsia_logger::LogSink > metadata, fidl::UnknownMethodCompleter::Sync &completer) override
void ConnectStructured(fuchsia_logger::LogSinkConnectStructuredRequest &request, ConnectStructuredCompleter::Sync &completer) override
void WaitForInterestChange(WaitForInterestChangeCompleter::Sync &completer) override
const char * name
Definition fuchsia.cc:49
TEST_F(LogInterestListenerFuchsia, SeverityChanges)
static constexpr char kLogSink[]
constexpr LogSeverity kLogFatal
Definition log_level.h:19
int GetMinLogLevel()
constexpr LogSeverity kLogError
Definition log_level.h:15
constexpr LogSeverity kLogInfo
Definition log_level.h:13
constexpr LogSeverity kLogWarning
Definition log_level.h:14
Definition ref_ptr.h:261