summaryrefslogtreecommitdiffstats
path: root/lldb/unittests/Utility
diff options
context:
space:
mode:
authorZachary Turner <zturner@google.com>2017-03-03 20:56:28 +0000
committerZachary Turner <zturner@google.com>2017-03-03 20:56:28 +0000
commit6f9e690199edd68b20bac92983a216459bc568ed (patch)
tree7ea5fb74ec0ed3234dd3af2decf394709498e8bc /lldb/unittests/Utility
parent000d61acfdf96a72a1c5e352f87c90eafa936de6 (diff)
downloadbcm5719-llvm-6f9e690199edd68b20bac92983a216459bc568ed.tar.gz
bcm5719-llvm-6f9e690199edd68b20bac92983a216459bc568ed.zip
Move Log from Core -> Utility.
All references to Host and Core have been removed, so this class can now safely be lowered into Utility. Differential Revision: https://reviews.llvm.org/D30559 llvm-svn: 296909
Diffstat (limited to 'lldb/unittests/Utility')
-rw-r--r--lldb/unittests/Utility/CMakeLists.txt1
-rw-r--r--lldb/unittests/Utility/LogTest.cpp212
2 files changed, 213 insertions, 0 deletions
diff --git a/lldb/unittests/Utility/CMakeLists.txt b/lldb/unittests/Utility/CMakeLists.txt
index 9596abb8cfd..782f4e52ed7 100644
--- a/lldb/unittests/Utility/CMakeLists.txt
+++ b/lldb/unittests/Utility/CMakeLists.txt
@@ -1,6 +1,7 @@
add_lldb_unittest(UtilityTests
ConstStringTest.cpp
ErrorTest.cpp
+ LogTest.cpp
NameMatchesTest.cpp
StringExtractorTest.cpp
TaskPoolTest.cpp
diff --git a/lldb/unittests/Utility/LogTest.cpp b/lldb/unittests/Utility/LogTest.cpp
new file mode 100644
index 00000000000..33b5b55aa30
--- /dev/null
+++ b/lldb/unittests/Utility/LogTest.cpp
@@ -0,0 +1,212 @@
+//===-- 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 "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);
+
+struct LogChannelTest : public ::testing::Test {
+ void TearDown() override { Log::DisableAllLogChannels(nullptr); }
+
+ static void SetUpTestCase() {
+ Log::Register("chan", test_channel);
+ }
+
+ static void TearDownTestCase() {
+ Log::Unregister("chan");
+ llvm::llvm_shutdown();
+ }
+};
+
+static std::string GetLogString(uint32_t log_options, const char *format,
+ int arg) {
+ std::string stream_string;
+ std::shared_ptr<llvm::raw_string_ostream> stream_sp(
+ new llvm::raw_string_ostream(stream_string));
+ Log log_(stream_sp);
+ log_.GetOptions().Reset(log_options);
+ Log *log = &log_;
+ LLDB_LOG(log, format, arg);
+ return stream_sp->str();
+}
+
+TEST(LogTest, LLDB_LOG_nullptr) {
+ Log *log = nullptr;
+ LLDB_LOG(log, "{0}", 0); // Shouldn't crash
+}
+
+TEST(LogTest, log_options) {
+ EXPECT_EQ("Hello World 47\n", GetLogString(0, "Hello World {0}", 47));
+ EXPECT_EQ("Hello World 47\n",
+ GetLogString(LLDB_LOG_OPTION_THREADSAFE, "Hello World {0}", 47));
+
+ {
+ std::string msg =
+ GetLogString(LLDB_LOG_OPTION_PREPEND_SEQUENCE, "Hello World {0}", 47);
+ int seq_no;
+ EXPECT_EQ(1, sscanf(msg.c_str(), "%d Hello World 47", &seq_no));
+ }
+
+ EXPECT_EQ(
+ "LogTest.cpp:GetLogString Hello "
+ "World 47\n",
+ GetLogString(LLDB_LOG_OPTION_PREPEND_FILE_FUNCTION, "Hello World {0}", 47));
+
+ EXPECT_EQ(llvm::formatv("[{0,0+4}/{1,0+4}] Hello World 47\n",
+ ::getpid(),
+ llvm::get_threadid_np())
+ .str(),
+ GetLogString(LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD,
+ "Hello World {0}", 47));
+}
+
+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));
+ const char *cat1[] = {"foo"};
+ std::string message;
+ std::shared_ptr<llvm::raw_string_ostream> stream_sp(
+ new llvm::raw_string_ostream(message));
+ StreamString err;
+ EXPECT_TRUE(Log::EnableLogChannel(stream_sp, 0, "chan", cat1, err));
+ 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));
+ StreamString err;
+ EXPECT_FALSE(Log::EnableLogChannel(stream_sp, 0, "chanchan", {}, err));
+ EXPECT_EQ("Invalid log channel 'chanchan'.\n", err.GetString());
+ err.Clear();
+
+ EXPECT_TRUE(Log::EnableLogChannel(stream_sp, 0, "chan", {}, err));
+ EXPECT_EQ("", err.GetString()) << "err: " << err.GetString().str();
+ EXPECT_NE(nullptr, test_channel.GetLogIfAll(FOO));
+ EXPECT_EQ(nullptr, test_channel.GetLogIfAll(BAR));
+
+ const char *cat2[] = {"bar"};
+ EXPECT_TRUE(Log::EnableLogChannel(stream_sp, 0, "chan", cat2, err));
+ EXPECT_NE(nullptr, test_channel.GetLogIfAll(FOO | BAR));
+
+ const char *cat3[] = {"baz"};
+ EXPECT_TRUE(Log::EnableLogChannel(stream_sp, 0, "chan", cat3, err));
+ EXPECT_TRUE(err.GetString().contains("unrecognized log category 'baz'"))
+ << "err: " << err.GetString().str();
+ 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));
+ StreamString err;
+ EXPECT_TRUE(Log::EnableLogChannel(stream_sp, LLDB_LOG_OPTION_VERBOSE, "chan",
+ {}, err));
+
+ 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));
+ const char *cat12[] = {"foo", "bar"};
+ std::string message;
+ std::shared_ptr<llvm::raw_string_ostream> stream_sp(
+ new llvm::raw_string_ostream(message));
+ StreamString err;
+ EXPECT_TRUE(Log::EnableLogChannel(stream_sp, 0, "chan", cat12, err));
+ EXPECT_NE(nullptr, test_channel.GetLogIfAll(FOO | BAR));
+
+ const char *cat2[] = {"bar"};
+ EXPECT_TRUE(Log::DisableLogChannel("chan", cat2, err));
+ EXPECT_NE(nullptr, test_channel.GetLogIfAll(FOO));
+ EXPECT_EQ(nullptr, test_channel.GetLogIfAll(BAR));
+
+ const char *cat3[] = {"baz"};
+ EXPECT_TRUE(Log::DisableLogChannel("chan", cat3, err));
+ EXPECT_TRUE(err.GetString().contains("unrecognized log category 'baz'"))
+ << "err: " << err.GetString().str();
+ EXPECT_NE(nullptr, test_channel.GetLogIfAll(FOO));
+ EXPECT_EQ(nullptr, test_channel.GetLogIfAll(BAR));
+ err.Clear();
+
+ EXPECT_TRUE(Log::DisableLogChannel("chan", {}, err));
+ EXPECT_EQ(nullptr, test_channel.GetLogIfAny(FOO | BAR));
+}
+
+TEST_F(LogChannelTest, List) {
+ StreamString str;
+ EXPECT_TRUE(Log::ListChannelCategories("chan", str));
+ 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, str.GetString().str());
+ str.Clear();
+
+ EXPECT_FALSE(Log::ListChannelCategories("chanchan", str));
+ EXPECT_EQ("Invalid log channel 'chanchan'.\n", str.GetString().str());
+}
+
+TEST_F(LogChannelTest, LogThread) {
+ // Test that we are able to concurrently write to a log channel and disable
+ // it.
+ std::string message;
+ std::shared_ptr<llvm::raw_string_ostream> stream_sp(
+ new llvm::raw_string_ostream(message));
+ StreamString err;
+ EXPECT_TRUE(Log::EnableLogChannel(stream_sp, 0, "chan", {}, err));
+
+ Log *log = test_channel.GetLogIfAll(FOO);
+
+ // Start logging on one thread. Concurrently, try disabling the log channel.
+ std::thread log_thread([log] { LLDB_LOG(log, "Hello World"); });
+ EXPECT_TRUE(Log::DisableLogChannel("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_TRUE(stream_sp->str() == "" || stream_sp->str() == "Hello World\n")
+ << "str(): " << stream_sp->str();
+}
OpenPOWER on IntegriCloud