// Copyright 2020 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "base/fuchsia/test_log_listener_safe.h" #include "base/callback_helpers.h" #include "base/fuchsia/fuchsia_logging.h" #include "base/run_loop.h" #include "base/strings/string_piece.h" #include "base/test/bind.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/abseil-cpp/absl/types/optional.h" namespace base { TestLogListenerSafe::TestLogListenerSafe() = default; TestLogListenerSafe::~TestLogListenerSafe() = default; void TestLogListenerSafe::set_on_log_message( base::RepeatingCallback callback) { on_log_message_ = std::move(callback); } void TestLogListenerSafe::Log(fuchsia::logger::LogMessage message, LogCallback callback) { if (on_log_message_) on_log_message_.Run(message); callback(); } void TestLogListenerSafe::LogMany( std::vector messages, LogManyCallback callback) { for (const auto& message : messages) on_log_message_.Run(message); callback(); } void TestLogListenerSafe::Done() {} void TestLogListenerSafe::NotImplemented_(const std::string& name) { ADD_FAILURE() << "NotImplemented_: " << name; } SimpleTestLogListener::SimpleTestLogListener() : binding_(&listener_) {} SimpleTestLogListener::~SimpleTestLogListener() = default; void SimpleTestLogListener::ListenToLog( fuchsia::logger::Log* log, std::unique_ptr options) { ignore_before_ = zx::clock::get_monotonic(); listener_.set_on_log_message(base::BindRepeating( &SimpleTestLogListener::PushLoggedMessage, base::Unretained(this))); log->ListenSafe(binding_.NewBinding(), std::move(options)); } absl::optional SimpleTestLogListener::RunUntilMessageReceived( base::StringPiece expected_string) { while (!logged_messages_.empty()) { fuchsia::logger::LogMessage message = logged_messages_.front(); logged_messages_.pop_front(); if (base::StringPiece(message.msg).find(expected_string) != std::string::npos) { return message; } } absl::optional logged_message; base::RunLoop loop; binding_.set_error_handler( [quit_loop = loop.QuitClosure()](zx_status_t status) { ZX_LOG(ERROR, status) << "LogListenerSafe disconnected"; quit_loop.Run(); }); on_log_message_ = base::BindLambdaForTesting( [ignore_before = ignore_before_, &logged_message, expected_string = std::string(expected_string), quit_loop = loop.QuitClosure()](const fuchsia::logger::LogMessage& message) { if (zx::time(message.time) < ignore_before) return; if (message.msg.find(expected_string) == std::string::npos) return; logged_message.emplace(message); quit_loop.Run(); }); loop.Run(); binding_.set_error_handler({}); on_log_message_ = NullCallback(); return logged_message; } void SimpleTestLogListener::PushLoggedMessage( const fuchsia::logger::LogMessage& message) { DVLOG(1) << "TestLogListener received: " << message.msg; if (zx::time(message.time) < ignore_before_) return; if (on_log_message_) { DCHECK(logged_messages_.empty()); on_log_message_.Run(message); } else { logged_messages_.push_back(std::move(message)); } } } // namespace base