275 lines
7.4 KiB
C++
275 lines
7.4 KiB
C++
// 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 "platform/api/logging.h"
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "absl/strings/match.h"
|
|
#include "absl/strings/str_cat.h"
|
|
#include "absl/strings/string_view.h"
|
|
#include "gtest/gtest.h"
|
|
#include "platform/impl/logging.h"
|
|
#include "platform/impl/logging_test.h"
|
|
#include "util/osp_logging.h"
|
|
|
|
namespace openscreen {
|
|
|
|
class LoggingTest : public ::testing::Test {
|
|
public:
|
|
LoggingTest() {}
|
|
|
|
void SetUp() {
|
|
previous_log_level = GetLogLevel();
|
|
SetLogLevel(LogLevel::kInfo);
|
|
SetLogBufferForTest(&log_messages);
|
|
testing::FLAGS_gtest_death_test_style = "threadsafe";
|
|
}
|
|
|
|
void TearDown() {
|
|
SetLogLevel(previous_log_level);
|
|
SetLogBufferForTest(nullptr);
|
|
}
|
|
|
|
protected:
|
|
void ExpectLog(LogLevel level, absl::string_view message) {
|
|
const char* level_string = "";
|
|
switch (level) {
|
|
case LogLevel::kVerbose:
|
|
level_string = "VERBOSE";
|
|
break;
|
|
case LogLevel::kInfo:
|
|
level_string = "INFO";
|
|
break;
|
|
case LogLevel::kWarning:
|
|
level_string = "WARNING";
|
|
break;
|
|
case LogLevel::kError:
|
|
level_string = "ERROR";
|
|
break;
|
|
case LogLevel::kFatal:
|
|
level_string = "FATAL";
|
|
break;
|
|
}
|
|
expected_messages.push_back({level_string, std::string(message)});
|
|
}
|
|
|
|
void VerifyNoLogs() { EXPECT_TRUE(log_messages.empty()); }
|
|
|
|
void VerifyLogs() {
|
|
ASSERT_EQ(expected_messages.size(), log_messages.size());
|
|
auto expected_it = expected_messages.begin();
|
|
auto actual_it = log_messages.begin();
|
|
// NOTE: This is somewhat brittle; it relies on details of how
|
|
// logging_posix.cc formats log messages.
|
|
while (expected_it != expected_messages.end()) {
|
|
EXPECT_TRUE(
|
|
absl::StartsWith(*actual_it, absl::StrCat("[", expected_it->level)));
|
|
EXPECT_TRUE(absl::EndsWith(
|
|
*actual_it, absl::StrCat("] ", expected_it->message, "\n")));
|
|
actual_it++;
|
|
expected_it++;
|
|
}
|
|
expected_messages.clear();
|
|
log_messages.clear();
|
|
}
|
|
|
|
private:
|
|
struct LogMessage {
|
|
std::string level;
|
|
std::string message;
|
|
};
|
|
std::vector<std::string> log_messages;
|
|
std::vector<LogMessage> expected_messages;
|
|
LogLevel previous_log_level = LogLevel::kWarning;
|
|
};
|
|
|
|
TEST_F(LoggingTest, UnconditionalLogging) {
|
|
SetLogLevel(LogLevel::kVerbose);
|
|
ExpectLog(LogLevel::kVerbose, "Verbose");
|
|
ExpectLog(LogLevel::kInfo, "Info");
|
|
ExpectLog(LogLevel::kWarning, "Warning");
|
|
ExpectLog(LogLevel::kError, "Error");
|
|
|
|
OSP_VLOG << "Verbose";
|
|
OSP_LOG_INFO << "Info";
|
|
OSP_LOG_WARN << "Warning";
|
|
OSP_LOG_ERROR << "Error";
|
|
|
|
VerifyLogs();
|
|
|
|
SetLogLevel(LogLevel::kWarning);
|
|
ExpectLog(LogLevel::kWarning, "Warning");
|
|
ExpectLog(LogLevel::kError, "Error");
|
|
|
|
OSP_VLOG << "Verbose";
|
|
OSP_LOG_INFO << "Info";
|
|
OSP_LOG_WARN << "Warning";
|
|
OSP_LOG_ERROR << "Error";
|
|
|
|
VerifyLogs();
|
|
}
|
|
|
|
TEST_F(LoggingTest, ConditionalLogging) {
|
|
SetLogLevel(LogLevel::kVerbose);
|
|
|
|
ExpectLog(LogLevel::kVerbose, "Verbose");
|
|
ExpectLog(LogLevel::kInfo, "Info");
|
|
ExpectLog(LogLevel::kWarning, "Warning");
|
|
ExpectLog(LogLevel::kError, "Error");
|
|
|
|
OSP_VLOG_IF(true) << "Verbose";
|
|
OSP_LOG_IF(INFO, true) << "Info";
|
|
OSP_LOG_IF(WARN, true) << "Warning";
|
|
OSP_LOG_IF(ERROR, true) << "Error";
|
|
VerifyLogs();
|
|
|
|
OSP_VLOG_IF(false) << "Verbose";
|
|
OSP_LOG_IF(INFO, false) << "Info";
|
|
OSP_LOG_IF(WARN, false) << "Warning";
|
|
OSP_LOG_IF(ERROR, false) << "Error";
|
|
VerifyNoLogs();
|
|
}
|
|
|
|
TEST_F(LoggingTest, DebugUnconditionalLogging) {
|
|
SetLogLevel(LogLevel::kVerbose);
|
|
OSP_DVLOG << "Verbose";
|
|
OSP_DLOG_INFO << "Info";
|
|
OSP_DLOG_WARN << "Warning";
|
|
OSP_DLOG_ERROR << "Error";
|
|
|
|
#if OSP_DCHECK_IS_ON()
|
|
ExpectLog(LogLevel::kVerbose, "Verbose");
|
|
ExpectLog(LogLevel::kInfo, "Info");
|
|
ExpectLog(LogLevel::kWarning, "Warning");
|
|
ExpectLog(LogLevel::kError, "Error");
|
|
VerifyLogs();
|
|
#else
|
|
VerifyNoLogs();
|
|
#endif // OSP_DCHECK_IS_ON()
|
|
|
|
SetLogLevel(LogLevel::kWarning);
|
|
|
|
OSP_DVLOG << "Verbose";
|
|
OSP_DLOG_INFO << "Info";
|
|
OSP_DLOG_WARN << "Warning";
|
|
OSP_DLOG_ERROR << "Error";
|
|
|
|
#if OSP_DCHECK_IS_ON()
|
|
ExpectLog(LogLevel::kWarning, "Warning");
|
|
ExpectLog(LogLevel::kError, "Error");
|
|
VerifyLogs();
|
|
#else
|
|
VerifyNoLogs();
|
|
#endif // OSP_DCHECK_IS_ON()
|
|
}
|
|
|
|
TEST_F(LoggingTest, DebugConditionalLogging) {
|
|
SetLogLevel(LogLevel::kVerbose);
|
|
|
|
OSP_DVLOG_IF(true) << "Verbose";
|
|
OSP_DLOG_IF(INFO, true) << "Info";
|
|
OSP_DLOG_IF(WARN, true) << "Warning";
|
|
OSP_DLOG_IF(ERROR, true) << "Error";
|
|
|
|
#if OSP_DCHECK_IS_ON()
|
|
ExpectLog(LogLevel::kVerbose, "Verbose");
|
|
ExpectLog(LogLevel::kInfo, "Info");
|
|
ExpectLog(LogLevel::kWarning, "Warning");
|
|
ExpectLog(LogLevel::kError, "Error");
|
|
VerifyLogs();
|
|
#else
|
|
VerifyNoLogs();
|
|
#endif // OSP_DCHECK_IS_ON()
|
|
|
|
OSP_DVLOG_IF(false) << "Verbose";
|
|
OSP_DLOG_IF(INFO, false) << "Info";
|
|
OSP_DLOG_IF(WARN, false) << "Warning";
|
|
OSP_DLOG_IF(ERROR, false) << "Error";
|
|
VerifyNoLogs();
|
|
}
|
|
|
|
TEST_F(LoggingTest, CheckAndLogFatal) {
|
|
ASSERT_DEATH(OSP_CHECK(false), ".*OSP_CHECK\\(false\\) failed: ");
|
|
|
|
ASSERT_DEATH(OSP_CHECK_EQ(1, 2),
|
|
".*OSP_CHECK\\(\\(1\\) == \\(2\\)\\) failed: 1 vs\\. 2: ");
|
|
|
|
ASSERT_DEATH(OSP_CHECK_NE(1, 1),
|
|
".*OSP_CHECK\\(\\(1\\) != \\(1\\)\\) failed: 1 vs\\. 1: ");
|
|
|
|
ASSERT_DEATH(OSP_CHECK_LT(2, 1),
|
|
".*OSP_CHECK\\(\\(2\\) < \\(1\\)\\) failed: 2 vs\\. 1: ");
|
|
|
|
ASSERT_DEATH(OSP_CHECK_LE(2, 1),
|
|
".*OSP_CHECK\\(\\(2\\) <= \\(1\\)\\) failed: 2 vs\\. 1: ");
|
|
|
|
ASSERT_DEATH(OSP_CHECK_GT(1, 2),
|
|
".*OSP_CHECK\\(\\(1\\) > \\(2\\)\\) failed: 1 vs\\. 2: ");
|
|
|
|
ASSERT_DEATH(OSP_CHECK_GE(1, 2),
|
|
".*OSP_CHECK\\(\\(1\\) >= \\(2\\)\\) failed: 1 vs\\. 2: ");
|
|
|
|
ASSERT_DEATH((OSP_LOG_FATAL << "Fatal"), ".*Fatal");
|
|
|
|
VerifyLogs();
|
|
}
|
|
|
|
TEST_F(LoggingTest, DCheckAndDLogFatal) {
|
|
#if OSP_DCHECK_IS_ON()
|
|
ASSERT_DEATH(OSP_DCHECK(false), ".*OSP_CHECK\\(false\\) failed: ");
|
|
|
|
ASSERT_DEATH(OSP_DCHECK_EQ(1, 2),
|
|
".*OSP_CHECK\\(\\(1\\) == \\(2\\)\\) failed: 1 vs\\. 2: ");
|
|
|
|
ASSERT_DEATH(OSP_DCHECK_NE(1, 1),
|
|
".*OSP_CHECK\\(\\(1\\) != \\(1\\)\\) failed: 1 vs\\. 1: ");
|
|
|
|
ASSERT_DEATH(OSP_DCHECK_LT(2, 1),
|
|
".*OSP_CHECK\\(\\(2\\) < \\(1\\)\\) failed: 2 vs\\. 1: ");
|
|
|
|
ASSERT_DEATH(OSP_DCHECK_LE(2, 1),
|
|
".*OSP_CHECK\\(\\(2\\) <= \\(1\\)\\) failed: 2 vs\\. 1: ");
|
|
|
|
ASSERT_DEATH(OSP_DCHECK_GT(1, 2),
|
|
".*OSP_CHECK\\(\\(1\\) > \\(2\\)\\) failed: 1 vs\\. 2: ");
|
|
|
|
ASSERT_DEATH(OSP_DCHECK_GE(1, 2),
|
|
".*OSP_CHECK\\(\\(1\\) >= \\(2\\)\\) failed: 1 vs\\. 2: ");
|
|
|
|
ASSERT_DEATH((OSP_DLOG_FATAL << "Fatal"), ".*Fatal");
|
|
|
|
VerifyLogs();
|
|
#else
|
|
VerifyNoLogs();
|
|
#endif // OSP_DCHECK_IS_ON()
|
|
}
|
|
|
|
TEST_F(LoggingTest, OspUnimplemented) {
|
|
// Default is to log once per process if the level >= kWarning.
|
|
SetLogLevel(LogLevel::kWarning);
|
|
ExpectLog(LogLevel::kWarning, "TestBody: UNIMPLEMENTED() hit.");
|
|
for (int i = 0; i < 2; i++) {
|
|
OSP_UNIMPLEMENTED();
|
|
}
|
|
VerifyLogs();
|
|
|
|
// Setting the level to kVerbose logs every time.
|
|
SetLogLevel(LogLevel::kVerbose);
|
|
std::string message("TestBody: UNIMPLEMENTED() hit.");
|
|
ExpectLog(LogLevel::kVerbose, message);
|
|
ExpectLog(LogLevel::kVerbose, message);
|
|
for (int i = 0; i < 2; i++) {
|
|
OSP_UNIMPLEMENTED();
|
|
}
|
|
VerifyLogs();
|
|
}
|
|
|
|
TEST_F(LoggingTest, OspNotReached) {
|
|
ASSERT_DEATH(OSP_NOTREACHED(), ".*TestBody: NOTREACHED\\(\\) hit.");
|
|
}
|
|
|
|
} // namespace openscreen
|