blob: 5f115b833e22cb5d16783526d107a074f8a1a881 [file] [log] [blame]
// Copyright 2019 The Fuchsia 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 "managed_logger.h"
#include <lib/gtest/real_loop_fixture.h>
#include "log_listener.h"
#include "log_listener_test_helpers.h"
#include "src/lib/fxl/strings/join_strings.h"
#include "src/lib/testing/predicates/status.h"
namespace netemul {
namespace testing {
constexpr const char* kLoggerName = "my_logger";
class ManagedLoggerTest : public gtest::RealLoopFixture {
public:
using LogLevel = fuchsia::logger::LogLevelFilter;
ManagedLoggerTest() : gtest::RealLoopFixture(), listener_(new TestListener()) {}
protected:
void Startup(std::string name, bool is_err) {
logger_ = std::make_unique<ManagedLogger>(std::move(name), is_err, listener_);
sock_.reset(logger_->CreateHandle().release());
logger_->Start([](ManagedLogger* logger) { FAIL() << "Managed logger shouldn't close"; });
}
void Write(const std::string& msg) {
size_t actual = 0;
EXPECT_OK(sock_.write(0, msg.c_str(), msg.length(), &actual));
EXPECT_EQ(actual, msg.length());
}
std::vector<fuchsia::logger::LogMessage>& messages() { return listener_->messages(); }
void WaitForMessageCount(size_t len) {
RunLoopUntil([this, len]() { return messages().size() >= len; });
}
void CheckMessage(const fuchsia::logger::LogMessage& msg, LogLevel severity,
const std::string& str, const std::vector<std::string>& tags) {
EXPECT_EQ(msg.dropped_logs, 0u);
EXPECT_EQ(msg.pid, 0u);
EXPECT_EQ(msg.tid, 0u);
EXPECT_NE(msg.time, 0u);
EXPECT_EQ(msg.severity, static_cast<int32_t>(severity));
EXPECT_EQ(msg.msg, str);
EXPECT_EQ(msg.tags.size(), tags.size());
for (const auto& t : tags) {
EXPECT_NE(std::find(msg.tags.begin(), msg.tags.end(), t), msg.tags.end())
<< "Tag " << t << " in message, but got tags " << fxl::JoinStrings(msg.tags, ",");
}
}
private:
zx::socket sock_;
std::shared_ptr<TestListener> listener_;
std::unique_ptr<ManagedLogger> logger_;
};
TEST_F(ManagedLoggerTest, BreaksNewLines) {
Startup(kLoggerName, false);
Write("Hello\nWorld\nExtra");
WaitForMessageCount(2);
// no more than two messages should have been logged:
EXPECT_EQ(messages().size(), 2u);
CheckMessage(messages()[0], LogLevel::INFO, "Hello", {kLoggerName});
CheckMessage(messages()[1], LogLevel::INFO, "World", {kLoggerName});
// when we append the rest of the line it'll get logged:
Write(" Data\n");
WaitForMessageCount(3);
CheckMessage(messages()[2], LogLevel::INFO, "Extra Data", {kLoggerName});
}
TEST_F(ManagedLoggerTest, LogLevelError) {
Startup(kLoggerName, true);
Write("Hello\n");
WaitForMessageCount(1);
CheckMessage(messages()[0], LogLevel::ERROR, "Hello", {kLoggerName});
}
TEST_F(ManagedLoggerTest, LargeMessageGetsBroken) {
Startup(kLoggerName, false);
std::string msg = "a";
std::stringstream big_message;
for (int i = 0; i < ManagedLogger::BufferSize - 1; i++) {
msg[0] = 'a' + (i % 26);
Write(msg);
big_message << msg;
if (i % 10 == 0) {
// Make the listener consume the message bit by bit
RunLoopUntilIdle();
}
}
Write("More\n");
WaitForMessageCount(2);
CheckMessage(messages()[0], LogLevel::INFO, big_message.str(), {kLoggerName});
CheckMessage(messages()[1], LogLevel::INFO, "More", {kLoggerName});
}
} // namespace testing
} // namespace netemul