aboutsummaryrefslogtreecommitdiff
path: root/unittests/Utility
diff options
context:
space:
mode:
Diffstat (limited to 'unittests/Utility')
-rw-r--r--unittests/Utility/CMakeLists.txt17
-rw-r--r--unittests/Utility/ConstStringTest.cpp18
-rw-r--r--unittests/Utility/ErrorTest.cpp19
-rw-r--r--unittests/Utility/Inputs/TestModule.c9
-rw-r--r--unittests/Utility/Inputs/TestModule.sobin5602 -> 0 bytes
-rw-r--r--unittests/Utility/LogTest.cpp280
-rw-r--r--unittests/Utility/Mocks/CMakeLists.txt9
-rw-r--r--unittests/Utility/Mocks/MockTildeExpressionResolver.cpp80
-rw-r--r--unittests/Utility/Mocks/MockTildeExpressionResolver.h37
-rw-r--r--unittests/Utility/ModuleCacheTest.cpp169
-rw-r--r--unittests/Utility/NameMatchesTest.cpp58
-rw-r--r--unittests/Utility/TildeExpressionResolverTest.cpp36
-rw-r--r--unittests/Utility/TimeoutTest.cpp18
-rw-r--r--unittests/Utility/UriParserTest.cpp40
-rw-r--r--unittests/Utility/VASprintfTest.cpp59
15 files changed, 642 insertions, 207 deletions
diff --git a/unittests/Utility/CMakeLists.txt b/unittests/Utility/CMakeLists.txt
index 15a29825f1da..60868bcb414c 100644
--- a/unittests/Utility/CMakeLists.txt
+++ b/unittests/Utility/CMakeLists.txt
@@ -1,9 +1,20 @@
+add_subdirectory(Mocks)
+
add_lldb_unittest(UtilityTests
- ModuleCacheTest.cpp
+ ConstStringTest.cpp
+ ErrorTest.cpp
+ LogTest.cpp
+ NameMatchesTest.cpp
StringExtractorTest.cpp
TaskPoolTest.cpp
+ TildeExpressionResolverTest.cpp
TimeoutTest.cpp
UriParserTest.cpp
- )
+ VASprintfTest.cpp
-add_unittest_inputs(UtilityTests TestModule.so)
+ LINK_LIBS
+ lldbUtility
+ lldbUtilityMocks
+ LINK_COMPONENTS
+ Support
+ )
diff --git a/unittests/Utility/ConstStringTest.cpp b/unittests/Utility/ConstStringTest.cpp
new file mode 100644
index 000000000000..454f656760ca
--- /dev/null
+++ b/unittests/Utility/ConstStringTest.cpp
@@ -0,0 +1,18 @@
+//===-- ConstStringTest.cpp -------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Utility/ConstString.h"
+#include "llvm/Support/FormatVariadic.h"
+#include "gtest/gtest.h"
+
+using namespace lldb_private;
+
+TEST(ConstStringTest, format_provider) {
+ EXPECT_EQ("foo", llvm::formatv("{0}", ConstString("foo")).str());
+}
diff --git a/unittests/Utility/ErrorTest.cpp b/unittests/Utility/ErrorTest.cpp
new file mode 100644
index 000000000000..a114b26ebe54
--- /dev/null
+++ b/unittests/Utility/ErrorTest.cpp
@@ -0,0 +1,19 @@
+//===-- ErrorTest.cpp -------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Utility/Error.h"
+#include "gtest/gtest.h"
+
+using namespace lldb_private;
+
+TEST(ErrorTest, Formatv) {
+ EXPECT_EQ("", llvm::formatv("{0}", Error()).str());
+ EXPECT_EQ("Hello Error", llvm::formatv("{0}", Error("Hello Error")).str());
+ EXPECT_EQ("Hello", llvm::formatv("{0:5}", Error("Hello Error")).str());
+}
diff --git a/unittests/Utility/Inputs/TestModule.c b/unittests/Utility/Inputs/TestModule.c
deleted file mode 100644
index 6347f7264944..000000000000
--- a/unittests/Utility/Inputs/TestModule.c
+++ /dev/null
@@ -1,9 +0,0 @@
-// Compile with $CC -nostdlib -shared TestModule.c -o TestModule.so
-// The actual contents of the test module is not important here. I am using this
-// because it
-// produces an extremely tiny (but still perfectly valid) module.
-
-void boom(void) {
- char *BOOM;
- *BOOM = 47;
-}
diff --git a/unittests/Utility/Inputs/TestModule.so b/unittests/Utility/Inputs/TestModule.so
deleted file mode 100644
index 9e9bf0b6e17e..000000000000
--- a/unittests/Utility/Inputs/TestModule.so
+++ /dev/null
Binary files differ
diff --git a/unittests/Utility/LogTest.cpp b/unittests/Utility/LogTest.cpp
new file mode 100644
index 000000000000..61fb6b5e4a5b
--- /dev/null
+++ b/unittests/Utility/LogTest.cpp
@@ -0,0 +1,280 @@
+//===-- 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(); }
+
+ static void SetUpTestCase() {
+ Log::Register("chan", test_channel);
+ }
+
+ static void TearDownTestCase() {
+ Log::Unregister("chan");
+ llvm::llvm_shutdown();
+ }
+};
+
+// 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);
+}
+
+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);
+}
+
+static std::string GetLogString(uint32_t log_options, const char *format,
+ int arg) {
+ std::string message;
+ std::shared_ptr<llvm::raw_string_ostream> stream_sp(
+ new llvm::raw_string_ostream(message));
+ std::string error;
+ llvm::raw_string_ostream error_stream(error);
+ EXPECT_TRUE(
+ Log::EnableLogChannel(stream_sp, log_options, "chan", {}, error_stream));
+
+ Log *log = test_channel.GetLogIfAll(FOO);
+ EXPECT_NE(nullptr, log);
+
+ LLDB_LOG(log, format, arg);
+ EXPECT_TRUE(Log::DisableLogChannel("chan", {}, error_stream));
+
+ return stream_sp->str();
+}
+
+TEST_F(LogChannelTest, 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())
+ .str(),
+ GetLogString(LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD,
+ "Hello World {0}", 47));
+}
+
+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));
+ std::string err;
+ EXPECT_TRUE(EnableChannel(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(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_TRUE(stream_sp->str() == "" || stream_sp->str() == "Hello World\n")
+ << "str(): " << stream_sp->str();
+}
+
+TEST_F(LogChannelTest, LogVerboseThread) {
+ // Test that we are able to concurrently check the verbose flag of a log
+ // channel and enable it.
+ std::string message;
+ std::shared_ptr<llvm::raw_string_ostream> stream_sp(
+ new llvm::raw_string_ostream(message));
+ std::string err;
+ EXPECT_TRUE(EnableChannel(stream_sp, 0, "chan", {}, err));
+
+ Log *log = test_channel.GetLogIfAll(FOO);
+
+ // Start logging on one thread. Concurrently, try enabling the log channel
+ // (with different log options).
+ std::thread log_thread([log] { LLDB_LOGV(log, "Hello World"); });
+ EXPECT_TRUE(EnableChannel(stream_sp, LLDB_LOG_OPTION_VERBOSE, "chan",
+ {}, err));
+ log_thread.join();
+ EXPECT_TRUE(DisableChannel("chan", {}, err));
+
+ // 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_TRUE(stream_sp->str() == "" || stream_sp->str() == "Hello World\n")
+ << "str(): " << stream_sp->str();
+}
+
+TEST_F(LogChannelTest, LogGetLogThread) {
+ // Test that we are able to concurrently get mask of a Log object and disable
+ // it.
+ std::string message;
+ std::shared_ptr<llvm::raw_string_ostream> stream_sp(
+ new llvm::raw_string_ostream(message));
+ std::string err;
+ EXPECT_TRUE(EnableChannel(stream_sp, 0, "chan", {}, err));
+ Log *log = test_channel.GetLogIfAll(FOO);
+
+ // Try fetching the log on one thread. Concurrently, try disabling the log
+ // channel.
+ uint32_t mask;
+ std::thread log_thread([log, &mask] { mask = log->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_TRUE(mask == 0 || mask == FOO) << "mask: " << mask;
+}
diff --git a/unittests/Utility/Mocks/CMakeLists.txt b/unittests/Utility/Mocks/CMakeLists.txt
new file mode 100644
index 000000000000..57db5bf3b628
--- /dev/null
+++ b/unittests/Utility/Mocks/CMakeLists.txt
@@ -0,0 +1,9 @@
+add_lldb_library(lldbUtilityMocks
+ MockTildeExpressionResolver.cpp
+
+ LINK_LIBS
+ lldbUtility
+
+ LINK_COMPONENTS
+ Support
+ )
diff --git a/unittests/Utility/Mocks/MockTildeExpressionResolver.cpp b/unittests/Utility/Mocks/MockTildeExpressionResolver.cpp
new file mode 100644
index 000000000000..832836682b50
--- /dev/null
+++ b/unittests/Utility/Mocks/MockTildeExpressionResolver.cpp
@@ -0,0 +1,80 @@
+//===----------------- MockTildeExpressionResolver.cpp ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "MockTildeExpressionResolver.h"
+#include "llvm/Support/Path.h"
+
+using namespace lldb_private;
+using namespace llvm;
+
+MockTildeExpressionResolver::MockTildeExpressionResolver(StringRef CurrentUser,
+ StringRef HomeDir)
+ : CurrentUser(CurrentUser) {
+ UserDirectories.insert(std::make_pair(CurrentUser, HomeDir));
+}
+
+void MockTildeExpressionResolver::AddKnownUser(StringRef User,
+ StringRef HomeDir) {
+ assert(UserDirectories.find(User) == UserDirectories.end());
+ UserDirectories.insert(std::make_pair(User, HomeDir));
+}
+
+void MockTildeExpressionResolver::Clear() {
+ CurrentUser = StringRef();
+ UserDirectories.clear();
+}
+
+void MockTildeExpressionResolver::SetCurrentUser(StringRef User) {
+ assert(UserDirectories.find(User) != UserDirectories.end());
+ CurrentUser = User;
+}
+
+bool MockTildeExpressionResolver::ResolveExact(StringRef Expr,
+ SmallVectorImpl<char> &Output) {
+ Output.clear();
+
+ assert(!llvm::any_of(
+ Expr, [](char c) { return llvm::sys::path::is_separator(c); }));
+ assert(Expr.empty() || Expr[0] == '~');
+ Expr = Expr.drop_front();
+ if (Expr.empty()) {
+ auto Dir = UserDirectories[CurrentUser];
+ Output.append(Dir.begin(), Dir.end());
+ return true;
+ }
+
+ for (const auto &User : UserDirectories) {
+ if (User.getKey() != Expr)
+ continue;
+ Output.append(User.getValue().begin(), User.getValue().end());
+ return true;
+ }
+ return false;
+}
+
+bool MockTildeExpressionResolver::ResolvePartial(StringRef Expr,
+ StringSet<> &Output) {
+ Output.clear();
+
+ assert(!llvm::any_of(
+ Expr, [](char c) { return llvm::sys::path::is_separator(c); }));
+ assert(Expr.empty() || Expr[0] == '~');
+ Expr = Expr.drop_front();
+
+ SmallString<16> QualifiedName("~");
+ for (const auto &User : UserDirectories) {
+ if (!User.getKey().startswith(Expr))
+ continue;
+ QualifiedName.resize(1);
+ QualifiedName.append(User.getKey().begin(), User.getKey().end());
+ Output.insert(QualifiedName);
+ }
+
+ return !Output.empty();
+}
diff --git a/unittests/Utility/Mocks/MockTildeExpressionResolver.h b/unittests/Utility/Mocks/MockTildeExpressionResolver.h
new file mode 100644
index 000000000000..7ae5623f839a
--- /dev/null
+++ b/unittests/Utility/Mocks/MockTildeExpressionResolver.h
@@ -0,0 +1,37 @@
+//===--------------------- TildeExpressionResolver.h ------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_UNITTESTS_UTILITY_MOCKS_MOCK_TILDE_EXPRESSION_RESOLVER_H
+#define LLDB_UNITTESTS_UTILITY_MOCKS_MOCK_TILDE_EXPRESSION_RESOLVER_H
+
+#include "lldb/Utility/TildeExpressionResolver.h"
+
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringMap.h"
+
+namespace lldb_private {
+class MockTildeExpressionResolver : public TildeExpressionResolver {
+ llvm::StringRef CurrentUser;
+ llvm::StringMap<llvm::StringRef> UserDirectories;
+
+public:
+ MockTildeExpressionResolver(llvm::StringRef CurrentUser,
+ llvm::StringRef HomeDir);
+
+ void AddKnownUser(llvm::StringRef User, llvm::StringRef HomeDir);
+ void Clear();
+ void SetCurrentUser(llvm::StringRef User);
+
+ bool ResolveExact(llvm::StringRef Expr,
+ llvm::SmallVectorImpl<char> &Output) override;
+ bool ResolvePartial(llvm::StringRef Expr, llvm::StringSet<> &Output) override;
+};
+}
+
+#endif
diff --git a/unittests/Utility/ModuleCacheTest.cpp b/unittests/Utility/ModuleCacheTest.cpp
deleted file mode 100644
index 911c278c1626..000000000000
--- a/unittests/Utility/ModuleCacheTest.cpp
+++ /dev/null
@@ -1,169 +0,0 @@
-#include "gtest/gtest.h"
-
-#include "llvm/ADT/SmallString.h"
-#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/Path.h"
-
-#include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
-#include "Utility/ModuleCache.h"
-#include "lldb/Core/Module.h"
-#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Host/HostInfo.h"
-#include "lldb/Symbol/SymbolContext.h"
-
-extern const char *TestMainArgv0;
-
-using namespace lldb_private;
-using namespace lldb;
-
-namespace {
-
-class ModuleCacheTest : public testing::Test {
-public:
- static void SetUpTestCase();
-
- static void TearDownTestCase();
-
-protected:
- static FileSpec s_cache_dir;
- static llvm::SmallString<128> s_test_executable;
-
- void TryGetAndPut(const FileSpec &cache_dir, const char *hostname,
- bool expect_download);
-};
-}
-
-FileSpec ModuleCacheTest::s_cache_dir;
-llvm::SmallString<128> ModuleCacheTest::s_test_executable;
-
-static const char dummy_hostname[] = "dummy_hostname";
-static const char dummy_remote_dir[] = "bin";
-static const char module_name[] = "TestModule.so";
-static const char module_uuid[] =
- "F4E7E991-9B61-6AD4-0073-561AC3D9FA10-C043A476";
-static const uint32_t uuid_bytes = 20;
-static const size_t module_size = 5602;
-
-static FileSpec GetDummyRemotePath() {
- FileSpec fs("/", false, FileSpec::ePathSyntaxPosix);
- fs.AppendPathComponent(dummy_remote_dir);
- fs.AppendPathComponent(module_name);
- return fs;
-}
-
-static FileSpec GetUuidView(FileSpec spec) {
- spec.AppendPathComponent(".cache");
- spec.AppendPathComponent(module_uuid);
- spec.AppendPathComponent(module_name);
- return spec;
-}
-
-static FileSpec GetSysrootView(FileSpec spec, const char *hostname) {
- spec.AppendPathComponent(hostname);
- spec.AppendPathComponent(dummy_remote_dir);
- spec.AppendPathComponent(module_name);
- return spec;
-}
-
-void ModuleCacheTest::SetUpTestCase() {
- HostInfo::Initialize();
- ObjectFileELF::Initialize();
-
- FileSpec tmpdir_spec;
- HostInfo::GetLLDBPath(lldb::ePathTypeLLDBTempSystemDir, s_cache_dir);
-
- llvm::StringRef exe_folder = llvm::sys::path::parent_path(TestMainArgv0);
- s_test_executable = exe_folder;
- llvm::sys::path::append(s_test_executable, "Inputs", module_name);
-}
-
-void ModuleCacheTest::TearDownTestCase() {
- ObjectFileELF::Terminate();
- HostInfo::Terminate();
-}
-
-static void VerifyDiskState(const FileSpec &cache_dir, const char *hostname) {
- FileSpec uuid_view = GetUuidView(cache_dir);
- EXPECT_TRUE(uuid_view.Exists()) << "uuid_view is: " << uuid_view.GetCString();
- EXPECT_EQ(module_size, uuid_view.GetByteSize());
-
- FileSpec sysroot_view = GetSysrootView(cache_dir, hostname);
- EXPECT_TRUE(sysroot_view.Exists()) << "sysroot_view is: "
- << sysroot_view.GetCString();
- EXPECT_EQ(module_size, sysroot_view.GetByteSize());
-}
-
-void ModuleCacheTest::TryGetAndPut(const FileSpec &cache_dir,
- const char *hostname, bool expect_download) {
- ModuleCache mc;
- ModuleSpec module_spec;
- module_spec.GetFileSpec() = GetDummyRemotePath();
- module_spec.GetUUID().SetFromCString(module_uuid, uuid_bytes);
- module_spec.SetObjectSize(module_size);
- ModuleSP module_sp;
- bool did_create;
- bool download_called = false;
-
- Error error = mc.GetAndPut(
- cache_dir, hostname, module_spec,
- [this, &download_called](const ModuleSpec &module_spec,
- const FileSpec &tmp_download_file_spec) {
- download_called = true;
- EXPECT_STREQ(GetDummyRemotePath().GetCString(),
- module_spec.GetFileSpec().GetCString());
- std::error_code ec = llvm::sys::fs::copy_file(
- s_test_executable, tmp_download_file_spec.GetCString());
- EXPECT_FALSE(ec);
- return Error();
- },
- [](const ModuleSP &module_sp, const FileSpec &tmp_download_file_spec) {
- return Error("Not supported.");
- },
- module_sp, &did_create);
- EXPECT_EQ(expect_download, download_called);
-
- EXPECT_TRUE(error.Success()) << "Error was: " << error.AsCString();
- EXPECT_TRUE(did_create);
- ASSERT_TRUE(bool(module_sp));
-
- SymbolContextList sc_list;
- EXPECT_EQ(1u, module_sp->FindFunctionSymbols(ConstString("boom"),
- eFunctionNameTypeFull, sc_list));
- EXPECT_STREQ(GetDummyRemotePath().GetCString(),
- module_sp->GetPlatformFileSpec().GetCString());
- EXPECT_STREQ(module_uuid, module_sp->GetUUID().GetAsString().c_str());
-}
-
-TEST_F(ModuleCacheTest, GetAndPut) {
- FileSpec test_cache_dir = s_cache_dir;
- test_cache_dir.AppendPathComponent("GetAndPut");
-
- const bool expect_download = true;
- TryGetAndPut(test_cache_dir, dummy_hostname, expect_download);
- VerifyDiskState(test_cache_dir, dummy_hostname);
-}
-
-TEST_F(ModuleCacheTest, GetAndPutUuidExists) {
- FileSpec test_cache_dir = s_cache_dir;
- test_cache_dir.AppendPathComponent("GetAndPutUuidExists");
-
- FileSpec uuid_view = GetUuidView(test_cache_dir);
- std::error_code ec =
- llvm::sys::fs::create_directories(uuid_view.GetDirectory().GetCString());
- ASSERT_FALSE(ec);
- ec = llvm::sys::fs::copy_file(s_test_executable, uuid_view.GetCString());
- ASSERT_FALSE(ec);
-
- const bool expect_download = false;
- TryGetAndPut(test_cache_dir, dummy_hostname, expect_download);
- VerifyDiskState(test_cache_dir, dummy_hostname);
-}
-
-TEST_F(ModuleCacheTest, GetAndPutStrangeHostname) {
- FileSpec test_cache_dir = s_cache_dir;
- test_cache_dir.AppendPathComponent("GetAndPutStrangeHostname");
-
- const bool expect_download = true;
- TryGetAndPut(test_cache_dir, "tab\tcolon:asterisk*", expect_download);
- VerifyDiskState(test_cache_dir, "tab_colon_asterisk_");
-}
diff --git a/unittests/Utility/NameMatchesTest.cpp b/unittests/Utility/NameMatchesTest.cpp
new file mode 100644
index 000000000000..28ae16c7ddd5
--- /dev/null
+++ b/unittests/Utility/NameMatchesTest.cpp
@@ -0,0 +1,58 @@
+//===-- NameMatchesTest.cpp -------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Utility/NameMatches.h"
+#include "gtest/gtest.h"
+
+using namespace lldb_private;
+
+TEST(NameMatchesTest, Ignore) {
+ EXPECT_TRUE(NameMatches("foo", NameMatch::Ignore, "bar"));
+}
+
+TEST(NameMatchesTest, Equals) {
+ EXPECT_TRUE(NameMatches("foo", NameMatch::Equals, "foo"));
+ EXPECT_FALSE(NameMatches("foo", NameMatch::Equals, "bar"));
+}
+
+TEST(NameMatchesTest, Contains) {
+ EXPECT_TRUE(NameMatches("foobar", NameMatch::Contains, "foo"));
+ EXPECT_TRUE(NameMatches("foobar", NameMatch::Contains, "oob"));
+ EXPECT_TRUE(NameMatches("foobar", NameMatch::Contains, "bar"));
+ EXPECT_TRUE(NameMatches("foobar", NameMatch::Contains, "foobar"));
+ EXPECT_TRUE(NameMatches("", NameMatch::Contains, ""));
+ EXPECT_FALSE(NameMatches("", NameMatch::Contains, "foo"));
+ EXPECT_FALSE(NameMatches("foobar", NameMatch::Contains, "baz"));
+}
+
+TEST(NameMatchesTest, StartsWith) {
+ EXPECT_TRUE(NameMatches("foo", NameMatch::StartsWith, "f"));
+ EXPECT_TRUE(NameMatches("foo", NameMatch::StartsWith, ""));
+ EXPECT_TRUE(NameMatches("", NameMatch::StartsWith, ""));
+ EXPECT_FALSE(NameMatches("foo", NameMatch::StartsWith, "b"));
+ EXPECT_FALSE(NameMatches("", NameMatch::StartsWith, "b"));
+}
+
+TEST(NameMatchesTest, EndsWith) {
+ EXPECT_TRUE(NameMatches("foo", NameMatch::EndsWith, "o"));
+ EXPECT_TRUE(NameMatches("foo", NameMatch::EndsWith, ""));
+ EXPECT_TRUE(NameMatches("", NameMatch::EndsWith, ""));
+ EXPECT_FALSE(NameMatches("foo", NameMatch::EndsWith, "b"));
+ EXPECT_FALSE(NameMatches("", NameMatch::EndsWith, "b"));
+}
+
+TEST(NameMatchesTest, RegularExpression) {
+ EXPECT_TRUE(NameMatches("foobar", NameMatch::RegularExpression, "foo"));
+ EXPECT_TRUE(NameMatches("foobar", NameMatch::RegularExpression, "f[oa]o"));
+ EXPECT_TRUE(NameMatches("foo", NameMatch::RegularExpression, ""));
+ EXPECT_TRUE(NameMatches("", NameMatch::RegularExpression, ""));
+ EXPECT_FALSE(NameMatches("foo", NameMatch::RegularExpression, "b"));
+ EXPECT_FALSE(NameMatches("", NameMatch::RegularExpression, "b"));
+ EXPECT_FALSE(NameMatches("^a", NameMatch::RegularExpression, "^a"));
+}
diff --git a/unittests/Utility/TildeExpressionResolverTest.cpp b/unittests/Utility/TildeExpressionResolverTest.cpp
new file mode 100644
index 000000000000..fd953390ed5d
--- /dev/null
+++ b/unittests/Utility/TildeExpressionResolverTest.cpp
@@ -0,0 +1,36 @@
+#include "gtest/gtest.h"
+
+#include "Mocks/MockTildeExpressionResolver.h"
+#include "lldb/Utility/TildeExpressionResolver.h"
+
+#include "llvm/ADT/SmallString.h"
+
+using namespace llvm;
+using namespace lldb_private;
+
+TEST(TildeExpressionResolver, ResolveFullPath) {
+ MockTildeExpressionResolver Resolver("James", "/james");
+ Resolver.AddKnownUser("Kirk", "/kirk");
+ Resolver.AddKnownUser("Lars", "/lars");
+ Resolver.AddKnownUser("Jason", "/jason");
+ Resolver.AddKnownUser("Larry", "/larry");
+
+ SmallString<32> Result;
+ ASSERT_TRUE(Resolver.ResolveFullPath("~", Result));
+ EXPECT_EQ("/james", Result);
+ ASSERT_TRUE(Resolver.ResolveFullPath("~/", Result));
+ EXPECT_EQ("/james/", Result);
+
+ ASSERT_TRUE(Resolver.ResolveFullPath("~James/bar/baz", Result));
+ EXPECT_EQ("/james/bar/baz", Result);
+
+ ASSERT_TRUE(Resolver.ResolveFullPath("~Jason/", Result));
+ EXPECT_EQ("/jason/", Result);
+
+ ASSERT_TRUE(Resolver.ResolveFullPath("~Lars", Result));
+ EXPECT_EQ("/lars", Result);
+
+ ASSERT_FALSE(Resolver.ResolveFullPath("~Jaso", Result));
+ ASSERT_FALSE(Resolver.ResolveFullPath("", Result));
+ ASSERT_FALSE(Resolver.ResolveFullPath("Jason", Result));
+}
diff --git a/unittests/Utility/TimeoutTest.cpp b/unittests/Utility/TimeoutTest.cpp
index a30c616d411b..d1002fb840da 100644
--- a/unittests/Utility/TimeoutTest.cpp
+++ b/unittests/Utility/TimeoutTest.cpp
@@ -8,15 +8,23 @@
//===----------------------------------------------------------------------===//
#include "lldb/Utility/Timeout.h"
+#include "llvm/Support/FormatVariadic.h"
#include "gtest/gtest.h"
using namespace lldb_private;
using namespace std::chrono;
TEST(TimeoutTest, Construction) {
- ASSERT_FALSE(Timeout<std::micro>(llvm::None));
- ASSERT_TRUE(bool(Timeout<std::micro>(seconds(0))));
- ASSERT_EQ(seconds(0), *Timeout<std::micro>(seconds(0)));
- ASSERT_EQ(seconds(3), *Timeout<std::micro>(seconds(3)));
- ASSERT_TRUE(bool(Timeout<std::micro>(Timeout<std::milli>(seconds(0)))));
+ EXPECT_FALSE(Timeout<std::micro>(llvm::None));
+ EXPECT_TRUE(bool(Timeout<std::micro>(seconds(0))));
+ EXPECT_EQ(seconds(0), *Timeout<std::micro>(seconds(0)));
+ EXPECT_EQ(seconds(3), *Timeout<std::micro>(seconds(3)));
+ EXPECT_TRUE(bool(Timeout<std::micro>(Timeout<std::milli>(seconds(0)))));
+}
+
+TEST(TimeoutTest, Format) {
+ EXPECT_EQ("<infinite>",
+ llvm::formatv("{0}", Timeout<std::milli>(llvm::None)).str());
+ EXPECT_EQ("1000 ms",
+ llvm::formatv("{0}", Timeout<std::milli>(seconds(1))).str());
}
diff --git a/unittests/Utility/UriParserTest.cpp b/unittests/Utility/UriParserTest.cpp
index 8b08e63eb8c7..c07d59a55e01 100644
--- a/unittests/Utility/UriParserTest.cpp
+++ b/unittests/Utility/UriParserTest.cpp
@@ -1,9 +1,7 @@
-#include "Utility/UriParser.h"
+#include "lldb/Utility/UriParser.h"
#include "gtest/gtest.h"
-namespace {
-class UriParserTest : public ::testing::Test {};
-}
+using namespace lldb_private;
// result strings (scheme/hostname/port/path) passed into UriParser::Parse
// are initialized to kAsdf so we can verify that they are unmodified if the
@@ -41,12 +39,12 @@ public:
EXPECT_EQ(testCase.m_port, port); \
EXPECT_STREQ(testCase.m_path, path.str().c_str());
-TEST_F(UriParserTest, Minimal) {
+TEST(UriParserTest, Minimal) {
const UriTestCase testCase("x://y", "x", "y", -1, "/");
VALIDATE
}
-TEST_F(UriParserTest, MinimalPort) {
+TEST(UriParserTest, MinimalPort) {
const UriTestCase testCase("x://y:1", "x", "y", 1, "/");
llvm::StringRef scheme(kAsdf);
llvm::StringRef hostname(kAsdf);
@@ -61,28 +59,28 @@ TEST_F(UriParserTest, MinimalPort) {
EXPECT_STREQ(testCase.m_path, path.str().c_str());
}
-TEST_F(UriParserTest, MinimalPath) {
+TEST(UriParserTest, MinimalPath) {
const UriTestCase testCase("x://y/", "x", "y", -1, "/");
VALIDATE
}
-TEST_F(UriParserTest, MinimalPortPath) {
+TEST(UriParserTest, MinimalPortPath) {
const UriTestCase testCase("x://y:1/", "x", "y", 1, "/");
VALIDATE
}
-TEST_F(UriParserTest, LongPath) {
+TEST(UriParserTest, LongPath) {
const UriTestCase testCase("x://y/abc/def/xyz", "x", "y", -1, "/abc/def/xyz");
VALIDATE
}
-TEST_F(UriParserTest, TypicalPortPath) {
+TEST(UriParserTest, TypicalPortPath) {
const UriTestCase testCase("connect://192.168.100.132:5432/", "connect",
"192.168.100.132", 5432, "/");
VALIDATE;
}
-TEST_F(UriParserTest, BracketedHostnamePort) {
+TEST(UriParserTest, BracketedHostnamePort) {
const UriTestCase testCase("connect://[192.168.100.132]:5432/", "connect",
"192.168.100.132", 5432, "/");
llvm::StringRef scheme(kAsdf);
@@ -98,54 +96,54 @@ TEST_F(UriParserTest, BracketedHostnamePort) {
EXPECT_STREQ(testCase.m_path, path.str().c_str());
}
-TEST_F(UriParserTest, BracketedHostname) {
+TEST(UriParserTest, BracketedHostname) {
const UriTestCase testCase("connect://[192.168.100.132]", "connect",
"192.168.100.132", -1, "/");
VALIDATE
}
-TEST_F(UriParserTest, BracketedHostnameWithColon) {
+TEST(UriParserTest, BracketedHostnameWithColon) {
const UriTestCase testCase("connect://[192.168.100.132:5555]:1234", "connect",
"192.168.100.132:5555", 1234, "/");
VALIDATE
}
-TEST_F(UriParserTest, SchemeHostSeparator) {
+TEST(UriParserTest, SchemeHostSeparator) {
const UriTestCase testCase("x:/y");
VALIDATE
}
-TEST_F(UriParserTest, SchemeHostSeparator2) {
+TEST(UriParserTest, SchemeHostSeparator2) {
const UriTestCase testCase("x:y");
VALIDATE
}
-TEST_F(UriParserTest, SchemeHostSeparator3) {
+TEST(UriParserTest, SchemeHostSeparator3) {
const UriTestCase testCase("x//y");
VALIDATE
}
-TEST_F(UriParserTest, SchemeHostSeparator4) {
+TEST(UriParserTest, SchemeHostSeparator4) {
const UriTestCase testCase("x/y");
VALIDATE
}
-TEST_F(UriParserTest, BadPort) {
+TEST(UriParserTest, BadPort) {
const UriTestCase testCase("x://y:a/");
VALIDATE
}
-TEST_F(UriParserTest, BadPort2) {
+TEST(UriParserTest, BadPort2) {
const UriTestCase testCase("x://y:5432a/");
VALIDATE
}
-TEST_F(UriParserTest, Empty) {
+TEST(UriParserTest, Empty) {
const UriTestCase testCase("");
VALIDATE
}
-TEST_F(UriParserTest, PortOverflow) {
+TEST(UriParserTest, PortOverflow) {
const UriTestCase testCase("x://"
"y:"
"0123456789012345678901234567890123456789012345678"
diff --git a/unittests/Utility/VASprintfTest.cpp b/unittests/Utility/VASprintfTest.cpp
new file mode 100644
index 000000000000..0b440942eb5a
--- /dev/null
+++ b/unittests/Utility/VASprintfTest.cpp
@@ -0,0 +1,59 @@
+//===-- VASprintfTest.cpp ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Utility/VASPrintf.h"
+#include "llvm/ADT/SmallString.h"
+
+#include "gtest/gtest.h"
+
+#include <locale.h>
+
+using namespace lldb_private;
+using namespace llvm;
+
+static bool Sprintf(llvm::SmallVectorImpl<char> &Buffer, const char *Fmt, ...) {
+ va_list args;
+ va_start(args, Fmt);
+ bool Result = VASprintf(Buffer, Fmt, args);
+ va_end(args);
+ return Result;
+}
+
+TEST(VASprintfTest, NoBufferResize) {
+ std::string TestStr("small");
+
+ llvm::SmallString<32> BigBuffer;
+ ASSERT_TRUE(Sprintf(BigBuffer, "%s", TestStr.c_str()));
+ EXPECT_STREQ(TestStr.c_str(), BigBuffer.c_str());
+ EXPECT_EQ(TestStr.size(), BigBuffer.size());
+}
+
+TEST(VASprintfTest, BufferResize) {
+ std::string TestStr("bigger");
+ llvm::SmallString<4> SmallBuffer;
+ ASSERT_TRUE(Sprintf(SmallBuffer, "%s", TestStr.c_str()));
+ EXPECT_STREQ(TestStr.c_str(), SmallBuffer.c_str());
+ EXPECT_EQ(TestStr.size(), SmallBuffer.size());
+}
+
+TEST(VASprintfTest, EncodingError) {
+ // Save the current locale first.
+ std::string Current(::setlocale(LC_ALL, nullptr));
+
+ setlocale(LC_ALL, ".932");
+
+ wchar_t Invalid[2];
+ Invalid[0] = 0x100;
+ Invalid[1] = 0;
+ llvm::SmallString<32> Buffer;
+ EXPECT_FALSE(Sprintf(Buffer, "%ls", Invalid));
+ EXPECT_EQ("<Encoding error>", Buffer);
+
+ setlocale(LC_ALL, Current.c_str());
+}