diff options
Diffstat (limited to 'unittests/Utility/LogTest.cpp')
-rw-r--r-- | unittests/Utility/LogTest.cpp | 314 |
1 files changed, 0 insertions, 314 deletions
diff --git a/unittests/Utility/LogTest.cpp b/unittests/Utility/LogTest.cpp deleted file mode 100644 index e4e5002a7f8b..000000000000 --- a/unittests/Utility/LogTest.cpp +++ /dev/null @@ -1,314 +0,0 @@ -//===-- LogTest.cpp ---------------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "gmock/gmock.h" -#include "gtest/gtest.h" - -#include "lldb/Utility/Log.h" -#include "lldb/Utility/StreamString.h" -#include "llvm/Support/ManagedStatic.h" -#include "llvm/Support/Threading.h" -#include <thread> - -using namespace lldb; -using namespace lldb_private; - -enum { FOO = 1, BAR = 2 }; -static constexpr Log::Category test_categories[] = { - {{"foo"}, {"log foo"}, FOO}, {{"bar"}, {"log bar"}, BAR}, -}; -static constexpr uint32_t default_flags = FOO; - -static Log::Channel test_channel(test_categories, default_flags); - -// Wrap enable, disable and list functions to make them easier to test. -static bool EnableChannel(std::shared_ptr<llvm::raw_ostream> stream_sp, - uint32_t log_options, llvm::StringRef channel, - llvm::ArrayRef<const char *> categories, - std::string &error) { - error.clear(); - llvm::raw_string_ostream error_stream(error); - return Log::EnableLogChannel(stream_sp, log_options, channel, categories, - error_stream); -} - -static bool DisableChannel(llvm::StringRef channel, - llvm::ArrayRef<const char *> categories, - std::string &error) { - error.clear(); - llvm::raw_string_ostream error_stream(error); - return Log::DisableLogChannel(channel, categories, error_stream); -} - -static bool ListCategories(llvm::StringRef channel, std::string &result) { - result.clear(); - llvm::raw_string_ostream result_stream(result); - return Log::ListChannelCategories(channel, result_stream); -} - -namespace { -// A test fixture which provides tests with a pre-registered channel. -struct LogChannelTest : public ::testing::Test { - void TearDown() override { Log::DisableAllLogChannels(); } - - static void SetUpTestCase() { - Log::Register("chan", test_channel); - } - - static void TearDownTestCase() { - Log::Unregister("chan"); - llvm::llvm_shutdown(); - } -}; - -// A test fixture which provides tests with a pre-registered and pre-enabled -// channel. Additionally, the messages written to that channel are captured and -// made available via getMessage(). -class LogChannelEnabledTest : public LogChannelTest { - llvm::SmallString<0> m_messages; - std::shared_ptr<llvm::raw_svector_ostream> m_stream_sp = - std::make_shared<llvm::raw_svector_ostream>(m_messages); - Log *m_log; - size_t m_consumed_bytes = 0; - -protected: - std::shared_ptr<llvm::raw_ostream> getStream() { return m_stream_sp; } - Log *getLog() { return m_log; } - llvm::StringRef takeOutput(); - llvm::StringRef logAndTakeOutput(llvm::StringRef Message); - -public: - void SetUp() override; -}; -} // end anonymous namespace - -void LogChannelEnabledTest::SetUp() { - LogChannelTest::SetUp(); - - std::string error; - ASSERT_TRUE(EnableChannel(m_stream_sp, 0, "chan", {}, error)); - - m_log = test_channel.GetLogIfAll(FOO); - ASSERT_NE(nullptr, m_log); -} - -llvm::StringRef LogChannelEnabledTest::takeOutput() { - llvm::StringRef result = m_stream_sp->str().drop_front(m_consumed_bytes); - m_consumed_bytes+= result.size(); - return result; -} - -llvm::StringRef LogChannelEnabledTest::logAndTakeOutput(llvm::StringRef Message) { - LLDB_LOG(m_log, "{0}", Message); - return takeOutput(); -} - -TEST(LogTest, LLDB_LOG_nullptr) { - Log *log = nullptr; - LLDB_LOG(log, "{0}", 0); // Shouldn't crash -} - -TEST(LogTest, Register) { - llvm::llvm_shutdown_obj obj; - Log::Register("chan", test_channel); - Log::Unregister("chan"); - Log::Register("chan", test_channel); - Log::Unregister("chan"); -} - -TEST(LogTest, Unregister) { - llvm::llvm_shutdown_obj obj; - Log::Register("chan", test_channel); - EXPECT_EQ(nullptr, test_channel.GetLogIfAny(FOO)); - std::string message; - std::shared_ptr<llvm::raw_string_ostream> stream_sp( - new llvm::raw_string_ostream(message)); - EXPECT_TRUE(Log::EnableLogChannel(stream_sp, 0, "chan", {"foo"}, llvm::nulls())); - EXPECT_NE(nullptr, test_channel.GetLogIfAny(FOO)); - Log::Unregister("chan"); - EXPECT_EQ(nullptr, test_channel.GetLogIfAny(FOO)); -} - -TEST_F(LogChannelTest, Enable) { - EXPECT_EQ(nullptr, test_channel.GetLogIfAll(FOO)); - std::string message; - std::shared_ptr<llvm::raw_string_ostream> stream_sp( - new llvm::raw_string_ostream(message)); - std::string error; - ASSERT_FALSE(EnableChannel(stream_sp, 0, "chanchan", {}, error)); - EXPECT_EQ("Invalid log channel 'chanchan'.\n", error); - - EXPECT_TRUE(EnableChannel(stream_sp, 0, "chan", {}, error)); - EXPECT_NE(nullptr, test_channel.GetLogIfAll(FOO)); - EXPECT_EQ(nullptr, test_channel.GetLogIfAll(BAR)); - - EXPECT_TRUE(EnableChannel(stream_sp, 0, "chan", {"bar"}, error)); - EXPECT_NE(nullptr, test_channel.GetLogIfAll(FOO | BAR)); - - EXPECT_TRUE(EnableChannel(stream_sp, 0, "chan", {"baz"}, error)); - EXPECT_NE(std::string::npos, error.find("unrecognized log category 'baz'")) - << "error: " << error; - EXPECT_NE(nullptr, test_channel.GetLogIfAll(FOO | BAR)); -} - -TEST_F(LogChannelTest, EnableOptions) { - EXPECT_EQ(nullptr, test_channel.GetLogIfAll(FOO)); - std::string message; - std::shared_ptr<llvm::raw_string_ostream> stream_sp( - new llvm::raw_string_ostream(message)); - std::string error; - EXPECT_TRUE( - EnableChannel(stream_sp, LLDB_LOG_OPTION_VERBOSE, "chan", {}, error)); - - Log *log = test_channel.GetLogIfAll(FOO); - ASSERT_NE(nullptr, log); - EXPECT_TRUE(log->GetVerbose()); -} - -TEST_F(LogChannelTest, Disable) { - EXPECT_EQ(nullptr, test_channel.GetLogIfAll(FOO)); - std::string message; - std::shared_ptr<llvm::raw_string_ostream> stream_sp( - new llvm::raw_string_ostream(message)); - std::string error; - EXPECT_TRUE(EnableChannel(stream_sp, 0, "chan", {"foo", "bar"}, error)); - EXPECT_NE(nullptr, test_channel.GetLogIfAll(FOO | BAR)); - - EXPECT_TRUE(DisableChannel("chan", {"bar"}, error)); - EXPECT_NE(nullptr, test_channel.GetLogIfAll(FOO)); - EXPECT_EQ(nullptr, test_channel.GetLogIfAll(BAR)); - - EXPECT_TRUE(DisableChannel("chan", {"baz"}, error)); - EXPECT_NE(std::string::npos, error.find("unrecognized log category 'baz'")) - << "error: " << error; - EXPECT_NE(nullptr, test_channel.GetLogIfAll(FOO)); - EXPECT_EQ(nullptr, test_channel.GetLogIfAll(BAR)); - - EXPECT_TRUE(DisableChannel("chan", {}, error)); - EXPECT_EQ(nullptr, test_channel.GetLogIfAny(FOO | BAR)); -} - -TEST_F(LogChannelTest, List) { - std::string list; - EXPECT_TRUE(ListCategories("chan", list)); - std::string expected = - R"(Logging categories for 'chan': - all - all available logging categories - default - default set of logging categories - foo - log foo - bar - log bar -)"; - EXPECT_EQ(expected, list); - - EXPECT_FALSE(ListCategories("chanchan", list)); - EXPECT_EQ("Invalid log channel 'chanchan'.\n", list); -} - -TEST_F(LogChannelEnabledTest, log_options) { - std::string Err; - EXPECT_EQ("Hello World\n", logAndTakeOutput("Hello World")); - EXPECT_TRUE(EnableChannel(getStream(), LLDB_LOG_OPTION_THREADSAFE, "chan", {}, - Err)); - EXPECT_EQ("Hello World\n", logAndTakeOutput("Hello World")); - - { - EXPECT_TRUE(EnableChannel(getStream(), LLDB_LOG_OPTION_PREPEND_SEQUENCE, - "chan", {}, Err)); - llvm::StringRef Msg = logAndTakeOutput("Hello World"); - int seq_no; - EXPECT_EQ(1, sscanf(Msg.str().c_str(), "%d Hello World", &seq_no)); - } - - { - EXPECT_TRUE(EnableChannel(getStream(), LLDB_LOG_OPTION_PREPEND_FILE_FUNCTION, - "chan", {}, Err)); - llvm::StringRef Msg = logAndTakeOutput("Hello World"); - char File[12]; - char Function[17]; - - sscanf(Msg.str().c_str(), "%[^:]:%s Hello World", File, Function); - EXPECT_STRCASEEQ("LogTest.cpp", File); - EXPECT_STREQ("logAndTakeOutput", Function); - } - - EXPECT_TRUE(EnableChannel( - getStream(), LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD, "chan", {}, Err)); - EXPECT_EQ(llvm::formatv("[{0,0+4}/{1,0+4}] Hello World\n", ::getpid(), - llvm::get_threadid()) - .str(), - logAndTakeOutput("Hello World")); -} - -TEST_F(LogChannelEnabledTest, LLDB_LOG_ERROR) { - LLDB_LOG_ERROR(getLog(), llvm::Error::success(), "Foo failed: {0}"); - ASSERT_EQ("", takeOutput()); - - LLDB_LOG_ERROR(getLog(), - llvm::make_error<llvm::StringError>( - "My Error", llvm::inconvertibleErrorCode()), - "Foo failed: {0}"); - ASSERT_EQ("Foo failed: My Error\n", takeOutput()); - - // Doesn't log, but doesn't assert either - LLDB_LOG_ERROR(nullptr, - llvm::make_error<llvm::StringError>( - "My Error", llvm::inconvertibleErrorCode()), - "Foo failed: {0}"); -} - -TEST_F(LogChannelEnabledTest, LogThread) { - // Test that we are able to concurrently write to a log channel and disable - // it. - std::string err; - - // Start logging on one thread. Concurrently, try disabling the log channel. - std::thread log_thread([this] { LLDB_LOG(getLog(), "Hello World"); }); - EXPECT_TRUE(DisableChannel("chan", {}, err)); - log_thread.join(); - - // The log thread either managed to write to the log in time, or it didn't. In - // either case, we should not trip any undefined behavior (run the test under - // TSAN to verify this). - EXPECT_THAT(takeOutput(), testing::AnyOf("", "Hello World\n")); -} - -TEST_F(LogChannelEnabledTest, LogVerboseThread) { - // Test that we are able to concurrently check the verbose flag of a log - // channel and enable it. - std::string err; - - // Start logging on one thread. Concurrently, try enabling the log channel - // (with different log options). - std::thread log_thread([this] { LLDB_LOGV(getLog(), "Hello World"); }); - EXPECT_TRUE( - EnableChannel(getStream(), LLDB_LOG_OPTION_VERBOSE, "chan", {}, err)); - log_thread.join(); - - // The log thread either managed to write to the log, or it didn't. In either - // case, we should not trip any undefined behavior (run the test under TSAN to - // verify this). - EXPECT_THAT(takeOutput(), testing::AnyOf("", "Hello World\n")); -} - -TEST_F(LogChannelEnabledTest, LogGetLogThread) { - // Test that we are able to concurrently get mask of a Log object and disable - // it. - std::string err; - - // Try fetching the log mask on one thread. Concurrently, try disabling the - // log channel. - uint32_t mask; - std::thread log_thread([this, &mask] { mask = getLog()->GetMask().Get(); }); - EXPECT_TRUE(DisableChannel("chan", {}, err)); - log_thread.join(); - - // The mask should be either zero of "FOO". In either case, we should not trip - // any undefined behavior (run the test under TSAN to verify this). - EXPECT_THAT(mask, testing::AnyOf(0, FOO)); -} |