1 // Copyright 2020 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 #ifndef BASE_FUCHSIA_TEST_LOG_LISTENER_SAFE_H_ 6 #define BASE_FUCHSIA_TEST_LOG_LISTENER_SAFE_H_ 7 8 #include <fidl/fuchsia.logger/cpp/fidl.h> 9 #include <lib/async/default.h> 10 #include <lib/fidl/cpp/binding.h> 11 #include <lib/zx/time.h> 12 13 #include <memory> 14 #include <optional> 15 #include <string> 16 #include <string_view> 17 #include <vector> 18 19 #include "base/containers/circular_deque.h" 20 #include "base/functional/callback.h" 21 22 namespace base { 23 24 // LogListenerSafe implementation that invokes a caller-supplied callback for 25 // each received message. 26 // Note that messages will be delivered in order of receipt from the system 27 // logger, starting with any recent messages that the logging service had 28 // cached, i.e. including messages that may pre-date this log-listener being 29 // created. 30 class TestLogListenerSafe final 31 : public fidl::Server<fuchsia_logger::LogListenerSafe> { 32 public: 33 using OnLogMessageCallback = 34 base::RepeatingCallback<void(const fuchsia_logger::LogMessage&)>; 35 36 TestLogListenerSafe(); 37 ~TestLogListenerSafe() override; 38 39 TestLogListenerSafe(const TestLogListenerSafe&) = delete; 40 TestLogListenerSafe& operator=(const TestLogListenerSafe&) = delete; 41 42 // Sets a callback to be invoked with every message received via Log(). 43 void set_on_log_message(OnLogMessageCallback callback); 44 45 private: 46 // LogListenerSafe implementation. 47 void Log(LogRequest& request, LogCompleter::Sync& completer) override; 48 void LogMany(LogManyRequest& request, 49 LogManyCompleter::Sync& completer) override; 50 void Done(DoneCompleter::Sync& completer) override; 51 52 OnLogMessageCallback on_log_message_; 53 }; 54 55 // Helper that manages a TestLogListenerSafe to simplify running the message 56 // loop until specific messages are received. 57 // Messages received prior to ListenToLog() being called will be silently 58 // ignored. 59 class SimpleTestLogListener { 60 public: 61 SimpleTestLogListener(); 62 ~SimpleTestLogListener(); 63 64 SimpleTestLogListener(const SimpleTestLogListener&) = delete; 65 SimpleTestLogListener& operator=(const SimpleTestLogListener&) = delete; 66 67 // Attaches this instance to receive data matching `options`, from `log`. 68 void ListenToLog(const fidl::Client<fuchsia_logger::Log>& log, 69 std::unique_ptr<fuchsia_logger::LogFilterOptions> options); 70 71 // Runs the message loop until a log message containing `expected_string` is 72 // received, and returns it. Returns `std::nullopt` if `binding_` disconnects 73 // without the `expected_string` having been logged. 74 std::optional<fuchsia_logger::LogMessage> RunUntilMessageReceived( 75 std::string_view expected_string); 76 77 private: 78 // Pushes `message` to the `logged_messages_` queue, or to `on_log_message_`. 79 void PushLoggedMessage(const fuchsia_logger::LogMessage& message); 80 81 // Used to ignore messages with timestamps prior to this listener's creation. 82 zx::time ignore_before_; 83 84 TestLogListenerSafe listener_; 85 std::optional<fidl::ServerBinding<fuchsia_logger::LogListenerSafe>> binding_; 86 87 base::circular_deque<fuchsia_logger::LogMessage> logged_messages_; 88 TestLogListenerSafe::OnLogMessageCallback on_log_message_; 89 }; 90 91 // Configures `listener` to listen for messages from the current process. 92 void ListenFilteredByCurrentProcessId(SimpleTestLogListener& listener); 93 94 } // namespace base 95 96 #endif // BASE_FUCHSIA_TEST_LOG_LISTENER_SAFE_H_ 97