blob: cab6ff96ee94aa486fe76e6e950796fc150fc542 [file] [log] [blame]
// Copyright 2018 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 <fcntl.h>
#include <lib/zx/socket.h>
#include <lib/syslog/global.h>
#include <lib/syslog/wire_format.h>
#include "gtest/gtest.h"
#include "lib/syslog/cpp/logger.h"
__BEGIN_CDECLS
// This does not come from header file as this function should only be used in
// tests and is not for general use.
void fx_log_reset_global(void);
__END_CDECLS
namespace {
class Cleanup {
public:
Cleanup() { fx_log_reset_global(); }
~Cleanup() { fx_log_reset_global(); }
};
bool ends_with(const char* str, const char* suffix) {
if (strlen(str) < strlen(suffix)) {
return false;
}
size_t l = strlen(suffix);
str += strlen(str) - l;
return strcmp(str, suffix) == 0;
}
inline zx_status_t init_helper(zx_handle_t handle, const char** tags,
size_t ntags) {
fx_logger_config_t config = {.min_severity = FX_LOG_INFO,
.console_fd = -1,
.log_service_channel = handle,
.tags = tags,
.num_tags = ntags};
return fx_log_init_with_config(&config);
}
void output_compare_helper(zx::socket local, fx_log_severity_t severity,
const char* msg, const char** tags, int num_tags) {
fx_log_packet_t packet;
ASSERT_EQ(ZX_OK, local.read(0, &packet, sizeof(packet), nullptr));
EXPECT_EQ(severity, packet.metadata.severity);
int pos = 0;
for (int i = 0; i < num_tags; i++) {
const char* tag = tags[i];
auto tag_len = static_cast<int8_t>(strlen(tag));
ASSERT_EQ(tag_len, packet.data[pos]);
pos++;
ASSERT_STREQ(tag, packet.data + pos);
pos += tag_len;
}
ASSERT_EQ(0, packet.data[pos]);
pos++;
EXPECT_TRUE(ends_with(packet.data + pos, msg)) << (packet.data + pos);
}
TEST(LogInit, Init) {
Cleanup cleanup;
ASSERT_EQ(ZX_OK, syslog::InitLogger());
fx_log_reset_global();
ASSERT_EQ(ZX_OK, syslog::InitLogger({"tag1", "tag2"}));
}
TEST(Logger, LogSimple) {
Cleanup cleanup;
zx::socket local, remote;
EXPECT_EQ(ZX_OK, zx::socket::create(ZX_SOCKET_DATAGRAM, &local, &remote));
ASSERT_EQ(ZX_OK, init_helper(remote.release(), nullptr, 0));
const char* msg = "test message";
FX_LOGS(INFO) << msg;
output_compare_helper(std::move(local), FX_LOG_INFO, msg, nullptr, 0);
}
TEST(Logger, WithSeverityMacro) {
Cleanup cleanup;
zx::socket local, remote;
EXPECT_EQ(ZX_OK, zx::socket::create(ZX_SOCKET_DATAGRAM, &local, &remote));
ASSERT_EQ(ZX_OK, init_helper(remote.release(), nullptr, 0));
const char* msg = "test message";
FX_LOGS_WITH_SEVERITY(FX_LOG_INFO) << msg;
output_compare_helper(std::move(local), FX_LOG_INFO, msg, nullptr, 0);
}
static zx_status_t GetAvailableBytes(const zx::socket& socket,
size_t* out_available) {
zx_info_socket_t info = {};
zx_status_t status = socket.get_info(ZX_INFO_SOCKET, &info, sizeof(info),
nullptr, nullptr);
if (status != ZX_OK) {
return status;
}
*out_available = info.rx_buf_available;
return ZX_OK;
}
TEST(Logger, LogSeverity) {
Cleanup cleanup;
zx::socket local, remote;
EXPECT_EQ(ZX_OK, zx::socket::create(ZX_SOCKET_DATAGRAM, &local, &remote));
ASSERT_EQ(ZX_OK, init_helper(remote.release(), nullptr, 0));
FX_VLOGS(1) << "just some msg";
size_t outstanding_bytes = 10u; // init to non zero value.
ASSERT_EQ(ZX_OK, GetAvailableBytes(local, &outstanding_bytes));
EXPECT_EQ(0u, outstanding_bytes);
FX_LOGS(WARNING) << "just some msg";
output_compare_helper(std::move(local), FX_LOG_WARNING, "just some msg",
nullptr, 0);
}
TEST(Logger, LogWithTag) {
Cleanup cleanup;
zx::socket local, remote;
EXPECT_EQ(ZX_OK, zx::socket::create(ZX_SOCKET_DATAGRAM, &local, &remote));
ASSERT_EQ(ZX_OK, init_helper(remote.release(), nullptr, 0));
FX_LOGST(INFO, "tag") << "just some string";
const char* tags[] = {"tag"};
output_compare_helper(std::move(local), FX_LOG_INFO, "just some string", tags,
1);
}
TEST(Logger, CheckFunction) {
Cleanup cleanup;
zx::socket local, remote;
EXPECT_EQ(ZX_OK, zx::socket::create(ZX_SOCKET_DATAGRAM, &local, &remote));
ASSERT_EQ(ZX_OK, init_helper(remote.release(), nullptr, 0));
FX_CHECK(1 > 0) << "error msg";
size_t outstanding_bytes = 10u; // init to non zero value.
ASSERT_EQ(ZX_OK, GetAvailableBytes(local, &outstanding_bytes));
EXPECT_EQ(0u, outstanding_bytes);
}
TEST(Logger, VLog) {
Cleanup cleanup;
zx::socket local, remote;
EXPECT_EQ(ZX_OK, zx::socket::create(ZX_SOCKET_DATAGRAM, &local, &remote));
ASSERT_EQ(ZX_OK, init_helper(remote.release(), nullptr, 0));
const char* msg = "test message";
FX_VLOGS(1) << msg;
size_t outstanding_bytes = 10u; // init to non zero value.
ASSERT_EQ(ZX_OK, GetAvailableBytes(local, &outstanding_bytes));
EXPECT_EQ(0u, outstanding_bytes);
FX_LOG_SET_VERBOSITY(1);
FX_VLOGS(2) << msg;
outstanding_bytes = 10u; // init to non zero value.
ASSERT_EQ(ZX_OK, GetAvailableBytes(local, &outstanding_bytes));
EXPECT_EQ(0u, outstanding_bytes);
FX_VLOGS(1) << msg;
output_compare_helper(std::move(local), -1, msg, nullptr, 0);
}
TEST(Logger, VLogWithTag) {
Cleanup cleanup;
zx::socket local, remote;
EXPECT_EQ(ZX_OK, zx::socket::create(ZX_SOCKET_DATAGRAM, &local, &remote));
ASSERT_EQ(ZX_OK, init_helper(remote.release(), nullptr, 0));
const char* msg = "test message";
const char* tags[] = {"tag"};
FX_VLOGST(1, tags[0]) << msg;
size_t outstanding_bytes = 10u; // init to non zero value.
ASSERT_EQ(ZX_OK, GetAvailableBytes(local, &outstanding_bytes));
EXPECT_EQ(0u, outstanding_bytes);
FX_LOG_SET_VERBOSITY(1);
FX_VLOGST(2, tags[0]) << msg;
outstanding_bytes = 10u; // init to non zero value.
ASSERT_EQ(ZX_OK, GetAvailableBytes(local, &outstanding_bytes));
EXPECT_EQ(0u, outstanding_bytes);
FX_VLOGST(1, tags[0]) << msg;
output_compare_helper(std::move(local), -1, msg, tags, 1);
}
} // namespace