Flutter Engine
The Flutter Engine
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/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
21#include "flutter/fml/log_settings.h"
22#include "flutter/fml/platform/fuchsia/log_interest_listener.h"
23#include "gtest/gtest.h"
24
25namespace fml {
26namespace testing {
27
28constexpr static char kLogSink[] = "log_sink";
29
30class LogInterestListenerFuchsia : public ::loop_fixture::RealLoop,
31 public ::testing::Test {};
32
34 ScopedSetLogSettings backup({.min_log_level = kLogInfo});
35 {
36 ::fuchsia_diagnostics::Interest interest;
37 interest.min_severity(::fuchsia_diagnostics::Severity::kTrace);
39 EXPECT_EQ(GetMinLogLevel(), -1); // VERBOSE
40 }
41 {
42 ::fuchsia_diagnostics::Interest interest;
43 interest.min_severity(::fuchsia_diagnostics::Severity::kInfo);
45 EXPECT_EQ(GetMinLogLevel(), kLogInfo);
46 }
47 {
48 ::fuchsia_diagnostics::Interest interest;
49 interest.min_severity(::fuchsia_diagnostics::Severity::kError);
51 EXPECT_EQ(GetMinLogLevel(), kLogError);
52 }
53}
54
55// Class to mock the server end of a LogSink.
56class MockLogSink : public component_testing::LocalComponentImpl,
57 public fidl::Server<fuchsia_logger::LogSink> {
58 public:
59 MockLogSink(fit::closure quitLoop, async_dispatcher_t* dispatcher)
60 : quit_loop_(std::move(quitLoop)), dispatcher_(dispatcher) {}
61
63 WaitForInterestChangeCompleter::Sync& completer) override {
64 if (first_call_) {
65 // If it has not been called before, then return a result right away.
66 fuchsia_logger::LogSinkWaitForInterestChangeResponse response = {
67 {.data = {{.min_severity = fuchsia_diagnostics::Severity::kWarn}}}};
68 completer.Reply(fit::ok(response));
69 first_call_ = false;
70 } else {
71 // On the second call, don't return a result.
72 completer_.emplace(completer.ToAsync());
73 quit_loop_();
74 }
75 }
76
77 void Connect(fuchsia_logger::LogSinkConnectRequest& request,
78 ConnectCompleter::Sync& completer) override {}
79
81 fuchsia_logger::LogSinkConnectStructuredRequest& request,
82 ConnectStructuredCompleter::Sync& completer) override {}
83
84 void OnStart() override {
85 ASSERT_EQ(outgoing()->AddProtocol<fuchsia_logger::LogSink>(
86 bindings_.CreateHandler(this, dispatcher_,
87 fidl::kIgnoreBindingClosure)),
88 ZX_OK);
89 }
90
91 private:
92 bool first_call_ = true;
93 fit::closure quit_loop_;
94 async_dispatcher_t* dispatcher_;
95 fidl::ServerBindingGroup<fuchsia_logger::LogSink> bindings_;
96 std::optional<WaitForInterestChangeCompleter::Async> completer_;
97};
98
99TEST_F(LogInterestListenerFuchsia, AsyncWaitForInterestChange) {
100 ScopedSetLogSettings backup({.min_log_level = kLogInfo});
101 auto realm_builder = component_testing::RealmBuilder::Create();
102 realm_builder.AddLocalChild(kLogSink, [&]() {
103 return std::make_unique<MockLogSink>(QuitLoopClosure(), dispatcher());
104 });
105 realm_builder.AddRoute(component_testing::Route{
106 .capabilities = {component_testing::Protocol{
107 fidl::DiscoverableProtocolName<fuchsia_logger::LogSink>}},
108 .source = component_testing::ChildRef{kLogSink},
109 .targets = {component_testing::ParentRef()}});
110
111 auto realm = realm_builder.Build(dispatcher());
112 auto cleanup = fit::defer([&]() {
113 bool complete = false;
114 realm.Teardown([&](auto result) { complete = true; });
115 RunLoopUntil([&]() { return complete; });
116 });
117 auto client_end = realm.component().Connect<fuchsia_logger::LogSink>();
118 ASSERT_TRUE(client_end.is_ok());
119 LogInterestListener listener(std::move(client_end.value()), dispatcher());
121 RunLoop();
122
123 EXPECT_EQ(GetMinLogLevel(), kLogWarning);
124}
125
126} // namespace testing
127} // namespace fml
static sk_sp< Effect > Create()
Definition: RefCntTest.cpp:117
static bool ok(int result)
static void HandleInterestChange(const fuchsia_diagnostics::Interest &interest)
void Connect(fuchsia_logger::LogSinkConnectRequest &request, ConnectCompleter::Sync &completer) override
MockLogSink(fit::closure quitLoop, async_dispatcher_t *dispatcher)
void ConnectStructured(fuchsia_logger::LogSinkConnectStructuredRequest &request, ConnectStructuredCompleter::Sync &completer) override
void WaitForInterestChange(WaitForInterestChangeCompleter::Sync &completer) override
GAsyncResult * result
TEST_F(LogInterestListenerFuchsia, SeverityChanges)
static constexpr char kLogSink[]
Definition: ascii_trie.cc:9
int GetMinLogLevel()
Definition: log_settings.cc:36
constexpr LogSeverity kLogError
Definition: log_level.h:15
constexpr LogSeverity kLogInfo
Definition: log_level.h:13
std::function< void()> closure
Definition: closure.h:14
constexpr LogSeverity kLogWarning
Definition: log_level.h:14
Definition: ref_ptr.h:256