diff options
Diffstat (limited to 'unittests/Utility')
| -rw-r--r-- | unittests/Utility/CMakeLists.txt | 17 | ||||
| -rw-r--r-- | unittests/Utility/ConstStringTest.cpp | 18 | ||||
| -rw-r--r-- | unittests/Utility/ErrorTest.cpp | 19 | ||||
| -rw-r--r-- | unittests/Utility/Inputs/TestModule.c | 9 | ||||
| -rw-r--r-- | unittests/Utility/Inputs/TestModule.so | bin | 5602 -> 0 bytes | |||
| -rw-r--r-- | unittests/Utility/LogTest.cpp | 280 | ||||
| -rw-r--r-- | unittests/Utility/Mocks/CMakeLists.txt | 9 | ||||
| -rw-r--r-- | unittests/Utility/Mocks/MockTildeExpressionResolver.cpp | 80 | ||||
| -rw-r--r-- | unittests/Utility/Mocks/MockTildeExpressionResolver.h | 37 | ||||
| -rw-r--r-- | unittests/Utility/ModuleCacheTest.cpp | 169 | ||||
| -rw-r--r-- | unittests/Utility/NameMatchesTest.cpp | 58 | ||||
| -rw-r--r-- | unittests/Utility/TildeExpressionResolverTest.cpp | 36 | ||||
| -rw-r--r-- | unittests/Utility/TimeoutTest.cpp | 18 | ||||
| -rw-r--r-- | unittests/Utility/UriParserTest.cpp | 40 | ||||
| -rw-r--r-- | unittests/Utility/VASprintfTest.cpp | 59 |
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 Binary files differdeleted file mode 100644 index 9e9bf0b6e17e..000000000000 --- a/unittests/Utility/Inputs/TestModule.so +++ /dev/null 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()); +} |
