aboutsummaryrefslogtreecommitdiff
path: root/unittests
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-04-16 16:04:10 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-04-16 16:04:10 +0000
commit74a628f776edb588bff8f8f5cc16eac947c9d631 (patch)
treedc32e010ac4902621e5a279bfeb48628f7f0e166 /unittests
parentafed7be32164a598f8172282c249af7266c48b46 (diff)
downloadsrc-74a628f776edb588bff8f8f5cc16eac947c9d631.tar.gz
src-74a628f776edb588bff8f8f5cc16eac947c9d631.zip
Vendor import of lldb trunk r300422:vendor/lldb/lldb-trunk-r300422
Notes
Notes: svn path=/vendor/lldb/dist/; revision=317027 svn path=/vendor/lldb/lldb-trunk-r300422/; revision=317028; tag=vendor/lldb/lldb-trunk-r300422
Diffstat (limited to 'unittests')
-rw-r--r--unittests/Breakpoint/BreakpointIDTest.cpp2
-rw-r--r--unittests/Breakpoint/CMakeLists.txt6
-rw-r--r--unittests/CMakeLists.txt22
-rw-r--r--unittests/Core/BroadcasterTest.cpp1
-rw-r--r--unittests/Core/CMakeLists.txt9
-rw-r--r--unittests/Core/DataExtractorTest.cpp9
-rw-r--r--unittests/Core/ScalarTest.cpp15
-rw-r--r--unittests/Core/StateTest.cpp21
-rw-r--r--unittests/Core/StreamCallbackTest.cpp28
-rw-r--r--unittests/Core/StructuredDataTest.cpp2
-rw-r--r--unittests/Core/TimerTest.cpp8
-rw-r--r--unittests/Editline/CMakeLists.txt5
-rw-r--r--unittests/Editline/EditlineTest.cpp6
-rw-r--r--unittests/Expression/CMakeLists.txt4
-rw-r--r--unittests/Expression/GoParserTest.cpp9
-rw-r--r--unittests/Host/CMakeLists.txt16
-rw-r--r--unittests/Host/FileSpecTest.cpp28
-rw-r--r--unittests/Host/SocketTest.cpp18
-rw-r--r--unittests/Host/linux/HostTest.cpp48
-rw-r--r--unittests/Host/linux/SupportTest.cpp26
-rw-r--r--unittests/Interpreter/CMakeLists.txt5
-rw-r--r--unittests/Interpreter/TestArgs.cpp8
-rw-r--r--unittests/Interpreter/TestCompletion.cpp307
-rw-r--r--unittests/Language/CPlusPlus/CMakeLists.txt3
-rw-r--r--unittests/Language/CPlusPlus/CPlusPlusLanguageTest.cpp138
-rw-r--r--unittests/ObjectFile/CMakeLists.txt1
-rw-r--r--unittests/ObjectFile/ELF/CMakeLists.txt7
-rw-r--r--unittests/ObjectFile/ELF/TestELFHeader.cpp62
-rw-r--r--unittests/Platform/CMakeLists.txt5
-rw-r--r--unittests/Process/gdb-remote/CMakeLists.txt9
-rw-r--r--unittests/Process/gdb-remote/GDBRemoteClientBaseTest.cpp9
-rw-r--r--unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp73
-rw-r--r--unittests/Process/gdb-remote/GDBRemoteTestUtils.cpp7
-rw-r--r--unittests/Process/minidump/CMakeLists.txt9
-rw-r--r--unittests/Process/minidump/MinidumpParserTest.cpp19
-rw-r--r--unittests/ScriptInterpreter/Python/CMakeLists.txt9
-rw-r--r--unittests/Signals/CMakeLists.txt6
-rw-r--r--unittests/Signals/UnixSignalsTest.cpp140
-rw-r--r--unittests/Symbol/CMakeLists.txt4
-rw-r--r--unittests/SymbolFile/DWARF/CMakeLists.txt11
-rw-r--r--unittests/SymbolFile/DWARF/SymbolFileDWARFTests.cpp2
-rw-r--r--unittests/SymbolFile/PDB/CMakeLists.txt11
-rw-r--r--unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp14
-rw-r--r--unittests/Target/CMakeLists.txt15
-rw-r--r--unittests/Target/Inputs/TestModule.c (renamed from unittests/Utility/Inputs/TestModule.c)0
-rw-r--r--unittests/Target/Inputs/TestModule.so (renamed from unittests/Utility/Inputs/TestModule.so)bin5602 -> 5602 bytes
-rw-r--r--unittests/Target/MemoryRegionInfoTest.cpp20
-rw-r--r--unittests/Target/ModuleCacheTest.cpp (renamed from unittests/Utility/ModuleCacheTest.cpp)2
-rw-r--r--unittests/UnwindAssembly/InstEmulation/CMakeLists.txt14
-rw-r--r--unittests/UnwindAssembly/x86/CMakeLists.txt7
-rw-r--r--unittests/Utility/CMakeLists.txt17
-rw-r--r--unittests/Utility/ConstStringTest.cpp18
-rw-r--r--unittests/Utility/ErrorTest.cpp (renamed from unittests/Core/ErrorTest.cpp)2
-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/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
-rw-r--r--unittests/debugserver/CMakeLists.txt19
-rw-r--r--unittests/debugserver/RNBSocketTest.cpp133
-rw-r--r--unittests/debugserver/debugserver_LogCallback.cpp20
-rw-r--r--unittests/gtest_common.h9
66 files changed, 1882 insertions, 153 deletions
diff --git a/unittests/Breakpoint/BreakpointIDTest.cpp b/unittests/Breakpoint/BreakpointIDTest.cpp
index a449d40a335a..a84fa5439527 100644
--- a/unittests/Breakpoint/BreakpointIDTest.cpp
+++ b/unittests/Breakpoint/BreakpointIDTest.cpp
@@ -10,7 +10,7 @@
#include "gtest/gtest.h"
#include "lldb/Breakpoint/BreakpointID.h"
-#include "lldb/Core/Error.h"
+#include "lldb/Utility/Error.h"
#include "llvm/ADT/StringRef.h"
diff --git a/unittests/Breakpoint/CMakeLists.txt b/unittests/Breakpoint/CMakeLists.txt
index ca1c282aaa66..e3715e55f0d7 100644
--- a/unittests/Breakpoint/CMakeLists.txt
+++ b/unittests/Breakpoint/CMakeLists.txt
@@ -1,3 +1,9 @@
add_lldb_unittest(LLDBBreakpointTests
BreakpointIDTest.cpp
+
+ LINK_LIBS
+ lldbBreakpoint
+ lldbCore
+ LINK_COMPONENTS
+ Support
)
diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt
index a865dbe244f8..f4c735e78e34 100644
--- a/unittests/CMakeLists.txt
+++ b/unittests/CMakeLists.txt
@@ -2,6 +2,7 @@ add_custom_target(LLDBUnitTests)
set_target_properties(LLDBUnitTests PROPERTIES FOLDER "LLDB tests")
include_directories(${LLDB_SOURCE_ROOT})
+include_directories(${LLDB_PROJECT_ROOT})
set(LLDB_GTEST_COMMON_INCLUDE ${CMAKE_CURRENT_SOURCE_DIR}/gtest_common.h)
if (MSVC)
@@ -21,9 +22,17 @@ if (LLDB_BUILT_STANDALONE)
endif()
function(add_lldb_unittest test_name)
+ cmake_parse_arguments(ARG
+ ""
+ ""
+ "LINK_LIBS;LINK_COMPONENTS"
+ ${ARGN})
+
+ list(APPEND LLVM_LINK_COMPONENTS ${ARG_LINK_COMPONENTS})
+
add_unittest(LLDBUnitTests
${test_name}
- ${ARGN}
+ ${ARG_UNPARSED_ARGUMENTS}
)
add_custom_command(
@@ -31,9 +40,7 @@ function(add_lldb_unittest test_name)
POST_BUILD
COMMAND "${CMAKE_COMMAND}" -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/Inputs)
- lldb_link_common_libs(${test_name} EXE)
- target_link_libraries(${test_name} ${CLANG_USED_LIBS} ${LLDB_SYSTEM_LIBS})
- llvm_config(${test_name} ${LLVM_LINK_COMPONENTS})
+ target_link_libraries(${test_name} ${ARG_LINK_LIBS} ${CLANG_USED_LIBS} ${LLDB_SYSTEM_LIBS})
endfunction()
function(add_unittest_inputs test_name inputs)
@@ -53,10 +60,17 @@ add_subdirectory(Expression)
add_subdirectory(Host)
add_subdirectory(Interpreter)
add_subdirectory(Language)
+add_subdirectory(ObjectFile)
add_subdirectory(Platform)
add_subdirectory(Process)
add_subdirectory(ScriptInterpreter)
+add_subdirectory(Signals)
add_subdirectory(Symbol)
add_subdirectory(SymbolFile)
+add_subdirectory(Target)
add_subdirectory(UnwindAssembly)
add_subdirectory(Utility)
+
+if(LLDB_CAN_USE_DEBUGSERVER)
+ add_subdirectory(debugserver)
+endif() \ No newline at end of file
diff --git a/unittests/Core/BroadcasterTest.cpp b/unittests/Core/BroadcasterTest.cpp
index e3795822f9ac..1613d0806009 100644
--- a/unittests/Core/BroadcasterTest.cpp
+++ b/unittests/Core/BroadcasterTest.cpp
@@ -10,6 +10,7 @@
#include "gtest/gtest.h"
#include "lldb/Core/Broadcaster.h"
+#include "lldb/Core/Event.h"
#include "lldb/Core/Listener.h"
#include "lldb/Host/Predicate.h"
diff --git a/unittests/Core/CMakeLists.txt b/unittests/Core/CMakeLists.txt
index 980bc5b9f9ae..73dd0d83fee3 100644
--- a/unittests/Core/CMakeLists.txt
+++ b/unittests/Core/CMakeLists.txt
@@ -2,9 +2,16 @@ add_lldb_unittest(LLDBCoreTests
ArchSpecTest.cpp
BroadcasterTest.cpp
DataExtractorTest.cpp
- ErrorTest.cpp
ListenerTest.cpp
ScalarTest.cpp
+ StateTest.cpp
+ StreamCallbackTest.cpp
StructuredDataTest.cpp
TimerTest.cpp
+
+ LINK_LIBS
+ lldbCore
+ lldbHost
+ LINK_COMPONENTS
+ Support
)
diff --git a/unittests/Core/DataExtractorTest.cpp b/unittests/Core/DataExtractorTest.cpp
index d474e21dc0c3..213d5a7b43fd 100644
--- a/unittests/Core/DataExtractorTest.cpp
+++ b/unittests/Core/DataExtractorTest.cpp
@@ -7,16 +7,9 @@
//
//===----------------------------------------------------------------------===//
-#if defined(_MSC_VER) && (_HAS_EXCEPTIONS == 0)
-// Workaround for MSVC standard library bug, which fails to include <thread>
-// when
-// exceptions are disabled.
-#include <eh.h>
-#endif
-
#include "gtest/gtest.h"
-#include "lldb/Core/DataExtractor.h"
+#include "lldb/Utility/DataExtractor.h"
using namespace lldb_private;
diff --git a/unittests/Core/ScalarTest.cpp b/unittests/Core/ScalarTest.cpp
index b79854f97ae3..3c4995c49086 100644
--- a/unittests/Core/ScalarTest.cpp
+++ b/unittests/Core/ScalarTest.cpp
@@ -7,20 +7,13 @@
//
//===----------------------------------------------------------------------===//
-#if defined(_MSC_VER) && (_HAS_EXCEPTIONS == 0)
-// Workaround for MSVC standard library bug, which fails to include <thread>
-// when
-// exceptions are disabled.
-#include <eh.h>
-#endif
-
#include "gtest/gtest.h"
-#include "lldb/Core/DataExtractor.h"
-#include "lldb/Core/Error.h"
#include "lldb/Core/Scalar.h"
-#include "lldb/Core/StreamString.h"
-#include "lldb/Host/Endian.h"
+#include "lldb/Utility/DataExtractor.h"
+#include "lldb/Utility/Endian.h"
+#include "lldb/Utility/Error.h"
+#include "lldb/Utility/StreamString.h"
using namespace lldb_private;
diff --git a/unittests/Core/StateTest.cpp b/unittests/Core/StateTest.cpp
new file mode 100644
index 000000000000..76cdaac82055
--- /dev/null
+++ b/unittests/Core/StateTest.cpp
@@ -0,0 +1,21 @@
+//===-- StateTest.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/Core/State.h"
+#include "llvm/Support/FormatVariadic.h"
+#include "gtest/gtest.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+TEST(StateTest, Formatv) {
+ EXPECT_EQ("exited", llvm::formatv("{0}", eStateExited).str());
+ EXPECT_EQ("stopped", llvm::formatv("{0}", eStateStopped).str());
+ EXPECT_EQ("unknown", llvm::formatv("{0}", StateType(-1)).str());
+}
diff --git a/unittests/Core/StreamCallbackTest.cpp b/unittests/Core/StreamCallbackTest.cpp
new file mode 100644
index 000000000000..d3ccd0211a4e
--- /dev/null
+++ b/unittests/Core/StreamCallbackTest.cpp
@@ -0,0 +1,28 @@
+//===-- StreamCallbackTest.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/StreamCallback.h"
+#include "gtest/gtest.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+static char test_baton;
+static size_t callback_count = 0;
+static void TestCallback(const char *data, void *baton) {
+ EXPECT_STREQ("Foobar", data);
+ EXPECT_EQ(&test_baton, baton);
+ ++callback_count;
+}
+
+TEST(StreamCallbackTest, Callback) {
+ StreamCallback stream(TestCallback, &test_baton);
+ stream << "Foobar";
+ EXPECT_EQ(1u, callback_count);
+}
diff --git a/unittests/Core/StructuredDataTest.cpp b/unittests/Core/StructuredDataTest.cpp
index 8e10d571fbfa..cac330304179 100644
--- a/unittests/Core/StructuredDataTest.cpp
+++ b/unittests/Core/StructuredDataTest.cpp
@@ -10,7 +10,7 @@
#include "gtest/gtest.h"
#include "lldb/Core/StructuredData.h"
-#include "lldb/Core/StreamString.h"
+#include "lldb/Utility/StreamString.h"
#include "llvm/Support/MachO.h"
diff --git a/unittests/Core/TimerTest.cpp b/unittests/Core/TimerTest.cpp
index d37d281f61af..7e7eeef0a361 100644
--- a/unittests/Core/TimerTest.cpp
+++ b/unittests/Core/TimerTest.cpp
@@ -7,16 +7,10 @@
//
//===----------------------------------------------------------------------===//
-#if defined(_MSC_VER) && (_HAS_EXCEPTIONS == 0)
-// Workaround for MSVC standard library bug, which fails to include <thread>
-// when exceptions are disabled.
-#include <eh.h>
-#endif
-
#include "lldb/Core/Timer.h"
#include "gtest/gtest.h"
-#include "lldb/Core/StreamString.h"
+#include "lldb/Utility/StreamString.h"
#include <thread>
using namespace lldb_private;
diff --git a/unittests/Editline/CMakeLists.txt b/unittests/Editline/CMakeLists.txt
index eaa21c490d98..4f656f6cc350 100644
--- a/unittests/Editline/CMakeLists.txt
+++ b/unittests/Editline/CMakeLists.txt
@@ -1,3 +1,8 @@
add_lldb_unittest(EditlineTests
EditlineTest.cpp
+
+ LINK_LIBS
+ lldbCore
+ lldbHost
+ lldbUtility
)
diff --git a/unittests/Editline/EditlineTest.cpp b/unittests/Editline/EditlineTest.cpp
index 55dae525ddc3..f4976a348198 100644
--- a/unittests/Editline/EditlineTest.cpp
+++ b/unittests/Editline/EditlineTest.cpp
@@ -19,11 +19,11 @@
#include "gtest/gtest.h"
-#include "lldb/Core/Error.h"
-#include "lldb/Core/StringList.h"
#include "lldb/Host/Editline.h"
#include "lldb/Host/Pipe.h"
-#include "lldb/Utility/PseudoTerminal.h"
+#include "lldb/Host/PseudoTerminal.h"
+#include "lldb/Utility/Error.h"
+#include "lldb/Utility/StringList.h"
namespace {
const size_t TIMEOUT_MILLIS = 5000;
diff --git a/unittests/Expression/CMakeLists.txt b/unittests/Expression/CMakeLists.txt
index 04bad141170b..c0a701da4f3d 100644
--- a/unittests/Expression/CMakeLists.txt
+++ b/unittests/Expression/CMakeLists.txt
@@ -1,3 +1,7 @@
add_lldb_unittest(ExpressionTests
GoParserTest.cpp
+
+ LINK_LIBS
+ lldbCore
+ lldbPluginExpressionParserGo
)
diff --git a/unittests/Expression/GoParserTest.cpp b/unittests/Expression/GoParserTest.cpp
index de489e43ef22..710dc5e4e86f 100644
--- a/unittests/Expression/GoParserTest.cpp
+++ b/unittests/Expression/GoParserTest.cpp
@@ -8,19 +8,12 @@
//
//===----------------------------------------------------------------------===//
-#if defined(_MSC_VER) && (_HAS_EXCEPTIONS == 0)
-// Workaround for MSVC standard library bug, which fails to include <thread>
-// when
-// exceptions are disabled.
-#include <eh.h>
-#endif
-
#include <sstream>
#include "gtest/gtest.h"
#include "Plugins/ExpressionParser/Go/GoParser.h"
-#include "lldb/Core/Error.h"
+#include "lldb/Utility/Error.h"
using namespace lldb_private;
diff --git a/unittests/Host/CMakeLists.txt b/unittests/Host/CMakeLists.txt
index 4c20f820e3c8..3396f45da4f3 100644
--- a/unittests/Host/CMakeLists.txt
+++ b/unittests/Host/CMakeLists.txt
@@ -1,7 +1,21 @@
-add_lldb_unittest(HostTests
+set (FILES
FileSpecTest.cpp
FileSystemTest.cpp
SocketAddressTest.cpp
SocketTest.cpp
SymbolsTest.cpp
+)
+
+if (CMAKE_SYSTEM_NAME MATCHES "Linux|Android")
+ list(APPEND FILES
+ linux/HostTest.cpp
+ linux/SupportTest.cpp
+ )
+endif()
+
+add_lldb_unittest(HostTests
+ ${FILES}
+ LINK_LIBS
+ lldbCore
+ lldbHost
)
diff --git a/unittests/Host/FileSpecTest.cpp b/unittests/Host/FileSpecTest.cpp
index 55a66b3b37eb..cb6877e7b622 100644
--- a/unittests/Host/FileSpecTest.cpp
+++ b/unittests/Host/FileSpecTest.cpp
@@ -9,7 +9,7 @@
#include "gtest/gtest.h"
-#include "lldb/Host/FileSpec.h"
+#include "lldb/Utility/FileSpec.h"
using namespace lldb_private;
@@ -109,6 +109,28 @@ TEST(FileSpecTest, CopyByAppendingPathComponent) {
EXPECT_STREQ("bar", fs.GetFilename().GetCString());
}
+TEST(FileSpecTest, PrependPathComponent) {
+ FileSpec fs_posix("foo", false, FileSpec::ePathSyntaxPosix);
+ fs_posix.PrependPathComponent("/bar");
+ EXPECT_STREQ("/bar/foo", fs_posix.GetCString());
+
+ FileSpec fs_posix_2("foo/bar", false, FileSpec::ePathSyntaxPosix);
+ fs_posix_2.PrependPathComponent("/baz");
+ EXPECT_STREQ("/baz/foo/bar", fs_posix_2.GetCString());
+
+ FileSpec fs_windows("baz", false, FileSpec::ePathSyntaxWindows);
+ fs_windows.PrependPathComponent("F:\\bar");
+ EXPECT_STREQ("F:\\bar\\baz", fs_windows.GetCString());
+
+ FileSpec fs_posix_root("bar", false, FileSpec::ePathSyntaxPosix);
+ fs_posix_root.PrependPathComponent("/");
+ EXPECT_STREQ("/bar", fs_posix_root.GetCString());
+
+ FileSpec fs_windows_root("bar", false, FileSpec::ePathSyntaxWindows);
+ fs_windows_root.PrependPathComponent("F:\\");
+ EXPECT_STREQ("F:\\bar", fs_windows_root.GetCString());
+}
+
static void Compare(const FileSpec &one, const FileSpec &two, bool full_match,
bool remove_backup_dots, bool result) {
EXPECT_EQ(result, FileSpec::Equal(one, two, full_match, remove_backup_dots))
@@ -142,6 +164,7 @@ TEST(FileSpecTest, EqualDotsWindows) {
{R"(C:/bar/baz)", R"(C:\foo\..\bar\baz)"},
{R"(C:\bar)", R"(C:\foo\..\bar)"},
{R"(C:\foo\bar)", R"(C:\foo\.\bar)"},
+ {R"(C:\foo\bar)", R"(C:\foo\bar\.)"},
};
for(const auto &test: tests) {
@@ -165,6 +188,7 @@ TEST(FileSpecTest, EqualDotsPosix) {
{R"(/bar/baz)", R"(/foo/../bar/baz)"},
{R"(/bar)", R"(/foo/../bar)"},
{R"(/foo/bar)", R"(/foo/./bar)"},
+ {R"(/foo/bar)", R"(/foo/bar/.)"},
};
for(const auto &test: tests) {
@@ -283,4 +307,4 @@ TEST(FileSpecTest, FormatFileSpec) {
EXPECT_EQ("foo", llvm::formatv("{0}", F).str());
EXPECT_EQ("foo", llvm::formatv("{0:F}", F).str());
EXPECT_EQ("(empty)", llvm::formatv("{0:D}", F).str());
-} \ No newline at end of file
+}
diff --git a/unittests/Host/SocketTest.cpp b/unittests/Host/SocketTest.cpp
index 569a4404131e..7abb010a9089 100644
--- a/unittests/Host/SocketTest.cpp
+++ b/unittests/Host/SocketTest.cpp
@@ -7,13 +7,6 @@
//
//===----------------------------------------------------------------------===//
-#if defined(_MSC_VER) && (_HAS_EXCEPTIONS == 0)
-// Workaround for MSVC standard library bug, which fails to include <thread>
-// when
-// exceptions are disabled.
-#include <eh.h>
-#endif
-
#include <cstdio>
#include <functional>
#include <thread>
@@ -203,17 +196,14 @@ TEST_F(SocketTest, TCPGetAddress) {
}
TEST_F(SocketTest, UDPConnect) {
- Socket *socket_a;
- Socket *socket_b;
+ Socket *socket;
bool child_processes_inherit = false;
auto error = UDPSocket::Connect("127.0.0.1:0", child_processes_inherit,
- socket_a, socket_b);
+ socket);
- std::unique_ptr<Socket> a_up(socket_a);
- std::unique_ptr<Socket> b_up(socket_b);
+ std::unique_ptr<Socket> socket_up(socket);
EXPECT_TRUE(error.Success());
- EXPECT_TRUE(a_up->IsValid());
- EXPECT_TRUE(b_up->IsValid());
+ EXPECT_TRUE(socket_up->IsValid());
}
diff --git a/unittests/Host/linux/HostTest.cpp b/unittests/Host/linux/HostTest.cpp
new file mode 100644
index 000000000000..36d3fd206dac
--- /dev/null
+++ b/unittests/Host/linux/HostTest.cpp
@@ -0,0 +1,48 @@
+//===-- HostTest.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/Host/Host.h"
+#include "lldb/Host/HostInfo.h"
+#include "lldb/Target/Process.h"
+#include "gtest/gtest.h"
+
+using namespace lldb_private;
+
+namespace {
+class HostTest : public testing::Test {
+public:
+ static void SetUpTestCase() { HostInfo::Initialize(); }
+ static void TearDownTestCase() { HostInfo::Terminate(); }
+};
+} // namespace
+
+TEST_F(HostTest, GetProcessInfo) {
+ ProcessInstanceInfo Info;
+ ASSERT_FALSE(Host::GetProcessInfo(0, Info));
+
+ ASSERT_TRUE(Host::GetProcessInfo(getpid(), Info));
+
+ ASSERT_TRUE(Info.ProcessIDIsValid());
+ EXPECT_EQ(lldb::pid_t(getpid()), Info.GetProcessID());
+
+ ASSERT_TRUE(Info.ParentProcessIDIsValid());
+ EXPECT_EQ(lldb::pid_t(getppid()), Info.GetParentProcessID());
+
+ ASSERT_TRUE(Info.EffectiveUserIDIsValid());
+ EXPECT_EQ(geteuid(), Info.GetEffectiveUserID());
+
+ ASSERT_TRUE(Info.EffectiveGroupIDIsValid());
+ EXPECT_EQ(getegid(), Info.GetEffectiveGroupID());
+
+ ASSERT_TRUE(Info.UserIDIsValid());
+ EXPECT_EQ(geteuid(), Info.GetUserID());
+
+ ASSERT_TRUE(Info.GroupIDIsValid());
+ EXPECT_EQ(getegid(), Info.GetGroupID());
+}
diff --git a/unittests/Host/linux/SupportTest.cpp b/unittests/Host/linux/SupportTest.cpp
new file mode 100644
index 000000000000..9b63084827af
--- /dev/null
+++ b/unittests/Host/linux/SupportTest.cpp
@@ -0,0 +1,26 @@
+//===-- SupportTest.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/Host/linux/Support.h"
+#include "llvm/Support/Threading.h"
+#include "gtest/gtest.h"
+
+using namespace lldb_private;
+
+TEST(Support, getProcFile_Pid) {
+ auto BufferOrError = getProcFile(getpid(), "maps");
+ ASSERT_TRUE(BufferOrError);
+ ASSERT_TRUE(*BufferOrError);
+}
+
+TEST(Support, getProcFile_Tid) {
+ auto BufferOrError = getProcFile(getpid(), llvm::get_threadid(), "comm");
+ ASSERT_TRUE(BufferOrError);
+ ASSERT_TRUE(*BufferOrError);
+}
diff --git a/unittests/Interpreter/CMakeLists.txt b/unittests/Interpreter/CMakeLists.txt
index 4078476bc75a..d884dee62ec5 100644
--- a/unittests/Interpreter/CMakeLists.txt
+++ b/unittests/Interpreter/CMakeLists.txt
@@ -1,5 +1,10 @@
add_lldb_unittest(InterpreterTests
TestArgs.cpp
+ TestCompletion.cpp
+
+ LINK_LIBS
+ lldbInterpreter
+ lldbUtilityMocks
)
target_link_libraries(InterpreterTests
diff --git a/unittests/Interpreter/TestArgs.cpp b/unittests/Interpreter/TestArgs.cpp
index 9dcf09d54aea..2aeed0f542b1 100644
--- a/unittests/Interpreter/TestArgs.cpp
+++ b/unittests/Interpreter/TestArgs.cpp
@@ -169,6 +169,14 @@ TEST(ArgsTest, AppendArguments) {
EXPECT_STREQ("4", args.GetArgumentAtIndex(3));
}
+TEST(ArgsTest, GetArgumentArrayRef) {
+ Args args("foo bar");
+ auto ref = args.GetArgumentArrayRef();
+ ASSERT_EQ(2u, ref.size());
+ EXPECT_STREQ("foo", ref[0]);
+ EXPECT_STREQ("bar", ref[1]);
+}
+
TEST(ArgsTest, StringToBoolean) {
bool success = false;
EXPECT_TRUE(Args::StringToBoolean(llvm::StringRef("true"), false, nullptr));
diff --git a/unittests/Interpreter/TestCompletion.cpp b/unittests/Interpreter/TestCompletion.cpp
new file mode 100644
index 000000000000..0548b93d6f72
--- /dev/null
+++ b/unittests/Interpreter/TestCompletion.cpp
@@ -0,0 +1,307 @@
+//===-- TestCompletion.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/Interpreter/CommandCompletions.h"
+#include "lldb/Utility/StringList.h"
+#include "lldb/Utility/TildeExpressionResolver.h"
+
+#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/raw_ostream.h"
+
+#include "unittests/Utility/Mocks/MockTildeExpressionResolver.h"
+
+namespace fs = llvm::sys::fs;
+namespace path = llvm::sys::path;
+using namespace llvm;
+using namespace lldb_private;
+
+#define ASSERT_NO_ERROR(x) \
+ if (std::error_code ASSERT_NO_ERROR_ec = x) { \
+ SmallString<128> MessageStorage; \
+ raw_svector_ostream Message(MessageStorage); \
+ Message << #x ": did not return errc::success.\n" \
+ << "error number: " << ASSERT_NO_ERROR_ec.value() << "\n" \
+ << "error message: " << ASSERT_NO_ERROR_ec.message() << "\n"; \
+ GTEST_FATAL_FAILURE_(MessageStorage.c_str()); \
+ } else { \
+ }
+
+namespace {
+
+class CompletionTest : public testing::Test {
+protected:
+ /// Unique temporary directory in which all created filesystem entities must
+ /// be placed. It is removed at the end of the test suite.
+ static SmallString<128> BaseDir;
+
+ static SmallString<128> OriginalWorkingDir;
+
+ static SmallString<128> DirFoo;
+ static SmallString<128> DirFooA;
+ static SmallString<128> DirFooB;
+ static SmallString<128> DirFooC;
+ static SmallString<128> DirBar;
+ static SmallString<128> DirBaz;
+ static SmallString<128> DirTestFolder;
+
+ static SmallString<128> FileAA;
+ static SmallString<128> FileAB;
+ static SmallString<128> FileAC;
+ static SmallString<128> FileFoo;
+ static SmallString<128> FileBar;
+ static SmallString<128> FileBaz;
+
+ void SetUp() override { llvm::sys::fs::set_current_path(OriginalWorkingDir); }
+
+ static void SetUpTestCase() {
+ llvm::sys::fs::current_path(OriginalWorkingDir);
+
+ ASSERT_NO_ERROR(fs::createUniqueDirectory("FsCompletion", BaseDir));
+ const char *DirNames[] = {"foo", "fooa", "foob", "fooc",
+ "bar", "baz", "test_folder"};
+ const char *FileNames[] = {"aa1234.tmp", "ab1234.tmp", "ac1234.tmp",
+ "foo1234.tmp", "bar1234.tmp", "baz1234.tmp"};
+ SmallString<128> *Dirs[] = {&DirFoo, &DirFooA, &DirFooB, &DirFooC,
+ &DirBar, &DirBaz, &DirTestFolder};
+ for (auto Dir : llvm::zip(DirNames, Dirs)) {
+ auto &Path = *std::get<1>(Dir);
+ Path = BaseDir;
+ path::append(Path, std::get<0>(Dir));
+ ASSERT_NO_ERROR(fs::create_directory(Path));
+ }
+
+ SmallString<128> *Files[] = {&FileAA, &FileAB, &FileAC,
+ &FileFoo, &FileBar, &FileBaz};
+ for (auto File : llvm::zip(FileNames, Files)) {
+ auto &Path = *std::get<1>(File);
+ Path = BaseDir;
+ path::append(Path, std::get<0>(File));
+ int FD;
+ ASSERT_NO_ERROR(fs::createUniqueFile(Path, FD, Path));
+ ::close(FD);
+ }
+ }
+
+ static void TearDownTestCase() {
+ ASSERT_NO_ERROR(fs::remove_directories(BaseDir));
+ }
+
+ static bool HasEquivalentFile(const Twine &Path, const StringList &Paths) {
+ for (size_t I = 0; I < Paths.GetSize(); ++I) {
+ if (fs::equivalent(Path, Paths[I]))
+ return true;
+ }
+ return false;
+ }
+
+ static bool ContainsExactString(const Twine &Str, const StringList &Paths) {
+ SmallString<16> Storage;
+ StringRef Rendered = Str.toStringRef(Storage);
+ for (size_t I = 0; I < Paths.GetSize(); ++I) {
+ if (Paths[I] == Rendered)
+ return true;
+ }
+ return false;
+ }
+
+ void DoDirCompletions(const Twine &Prefix,
+ StandardTildeExpressionResolver &Resolver,
+ StringList &Results) {
+ // When a partial name matches, it returns all matches. If it matches both
+ // a full name AND some partial names, it returns all of them.
+ uint32_t Count =
+ CommandCompletions::DiskDirectories(Prefix + "foo", Results, Resolver);
+ ASSERT_EQ(4u, Count);
+ ASSERT_EQ(Count, Results.GetSize());
+ EXPECT_TRUE(HasEquivalentFile(DirFoo, Results));
+ EXPECT_TRUE(HasEquivalentFile(DirFooA, Results));
+ EXPECT_TRUE(HasEquivalentFile(DirFooB, Results));
+ EXPECT_TRUE(HasEquivalentFile(DirFooC, Results));
+
+ // If it matches only partial names, it still works as expected.
+ Count = CommandCompletions::DiskDirectories(Twine(Prefix) + "b", Results,
+ Resolver);
+ ASSERT_EQ(2u, Count);
+ ASSERT_EQ(Count, Results.GetSize());
+ EXPECT_TRUE(HasEquivalentFile(DirBar, Results));
+ EXPECT_TRUE(HasEquivalentFile(DirBaz, Results));
+ }
+};
+
+SmallString<128> CompletionTest::BaseDir;
+SmallString<128> CompletionTest::OriginalWorkingDir;
+
+SmallString<128> CompletionTest::DirFoo;
+SmallString<128> CompletionTest::DirFooA;
+SmallString<128> CompletionTest::DirFooB;
+SmallString<128> CompletionTest::DirFooC;
+SmallString<128> CompletionTest::DirBar;
+SmallString<128> CompletionTest::DirBaz;
+SmallString<128> CompletionTest::DirTestFolder;
+
+SmallString<128> CompletionTest::FileAA;
+SmallString<128> CompletionTest::FileAB;
+SmallString<128> CompletionTest::FileAC;
+SmallString<128> CompletionTest::FileFoo;
+SmallString<128> CompletionTest::FileBar;
+SmallString<128> CompletionTest::FileBaz;
+}
+
+TEST_F(CompletionTest, DirCompletionAbsolute) {
+ // All calls to DiskDirectories() return only directories, even when
+ // there are files which also match. The tests below all check this
+ // by asserting an exact result count, and verifying against known
+ // folders.
+
+ std::string Prefixes[] = {(Twine(BaseDir) + "/").str(), ""};
+
+ StandardTildeExpressionResolver Resolver;
+ StringList Results;
+
+ // When a directory is specified that doesn't end in a slash, it searches
+ // for that directory, not items under it.
+ size_t Count =
+ CommandCompletions::DiskDirectories(BaseDir, Results, Resolver);
+ ASSERT_EQ(1u, Count);
+ ASSERT_EQ(Count, Results.GetSize());
+ EXPECT_TRUE(HasEquivalentFile(BaseDir, Results));
+
+ // When the same directory ends with a slash, it finds all children.
+ Count = CommandCompletions::DiskDirectories(Prefixes[0], Results, Resolver);
+ ASSERT_EQ(7u, Count);
+ ASSERT_EQ(Count, Results.GetSize());
+ EXPECT_TRUE(HasEquivalentFile(DirFoo, Results));
+ EXPECT_TRUE(HasEquivalentFile(DirFooA, Results));
+ EXPECT_TRUE(HasEquivalentFile(DirFooB, Results));
+ EXPECT_TRUE(HasEquivalentFile(DirFooC, Results));
+ EXPECT_TRUE(HasEquivalentFile(DirBar, Results));
+ EXPECT_TRUE(HasEquivalentFile(DirBaz, Results));
+ EXPECT_TRUE(HasEquivalentFile(DirTestFolder, Results));
+
+ DoDirCompletions(Twine(BaseDir) + "/", Resolver, Results);
+ llvm::sys::fs::set_current_path(BaseDir);
+ DoDirCompletions("", Resolver, Results);
+}
+
+TEST_F(CompletionTest, FileCompletionAbsolute) {
+ // All calls to DiskFiles() return both files and directories The tests below
+ // all check this by asserting an exact result count, and verifying against
+ // known folders.
+
+ StandardTildeExpressionResolver Resolver;
+ StringList Results;
+ // When an item is specified that doesn't end in a slash but exactly matches
+ // one item, it returns that item.
+ size_t Count = CommandCompletions::DiskFiles(Twine(BaseDir) + "/fooa",
+ Results, Resolver);
+ ASSERT_EQ(1u, Count);
+ ASSERT_EQ(Count, Results.GetSize());
+ EXPECT_TRUE(HasEquivalentFile(DirFooA, Results));
+
+ // The previous check verified a directory match. But it should work for
+ // files too.
+ Count =
+ CommandCompletions::DiskFiles(Twine(BaseDir) + "/aa", Results, Resolver);
+ ASSERT_EQ(1u, Count);
+ ASSERT_EQ(Count, Results.GetSize());
+ EXPECT_TRUE(HasEquivalentFile(FileAA, Results));
+
+ // When it ends with a slash, it should find all files and directories.
+ Count =
+ CommandCompletions::DiskFiles(Twine(BaseDir) + "/", Results, Resolver);
+ ASSERT_EQ(13u, Count);
+ ASSERT_EQ(Count, Results.GetSize());
+ EXPECT_TRUE(HasEquivalentFile(DirFoo, Results));
+ EXPECT_TRUE(HasEquivalentFile(DirFooA, Results));
+ EXPECT_TRUE(HasEquivalentFile(DirFooB, Results));
+ EXPECT_TRUE(HasEquivalentFile(DirFooC, Results));
+ EXPECT_TRUE(HasEquivalentFile(DirBar, Results));
+ EXPECT_TRUE(HasEquivalentFile(DirBaz, Results));
+ EXPECT_TRUE(HasEquivalentFile(DirTestFolder, Results));
+
+ EXPECT_TRUE(HasEquivalentFile(FileAA, Results));
+ EXPECT_TRUE(HasEquivalentFile(FileAB, Results));
+ EXPECT_TRUE(HasEquivalentFile(FileAC, Results));
+ EXPECT_TRUE(HasEquivalentFile(FileFoo, Results));
+ EXPECT_TRUE(HasEquivalentFile(FileBar, Results));
+ EXPECT_TRUE(HasEquivalentFile(FileBaz, Results));
+
+ // When a partial name matches, it returns all file & directory matches.
+ Count =
+ CommandCompletions::DiskFiles(Twine(BaseDir) + "/foo", Results, Resolver);
+ ASSERT_EQ(5u, Count);
+ ASSERT_EQ(Count, Results.GetSize());
+ EXPECT_TRUE(HasEquivalentFile(DirFoo, Results));
+ EXPECT_TRUE(HasEquivalentFile(DirFooA, Results));
+ EXPECT_TRUE(HasEquivalentFile(DirFooB, Results));
+ EXPECT_TRUE(HasEquivalentFile(DirFooC, Results));
+ EXPECT_TRUE(HasEquivalentFile(FileFoo, Results));
+}
+
+TEST_F(CompletionTest, DirCompletionUsername) {
+ MockTildeExpressionResolver Resolver("James", BaseDir);
+ Resolver.AddKnownUser("Kirk", DirFooB);
+ Resolver.AddKnownUser("Lars", DirFooC);
+ Resolver.AddKnownUser("Jason", DirFoo);
+ Resolver.AddKnownUser("Larry", DirFooA);
+
+ // Just resolving current user's home directory by itself should return the
+ // directory.
+ StringList Results;
+ size_t Count = CommandCompletions::DiskDirectories("~", Results, Resolver);
+ ASSERT_EQ(1u, Count);
+ ASSERT_EQ(Count, Results.GetSize());
+ EXPECT_TRUE(ContainsExactString(Twine("~") + path::get_separator(), Results));
+
+ // With a slash appended, it should return all items in the directory.
+ Count = CommandCompletions::DiskDirectories("~/", Results, Resolver);
+ ASSERT_EQ(7u, Count);
+ ASSERT_EQ(Count, Results.GetSize());
+ EXPECT_TRUE(
+ ContainsExactString(Twine("~/foo") + path::get_separator(), Results));
+ EXPECT_TRUE(
+ ContainsExactString(Twine("~/fooa") + path::get_separator(), Results));
+ EXPECT_TRUE(
+ ContainsExactString(Twine("~/foob") + path::get_separator(), Results));
+ EXPECT_TRUE(
+ ContainsExactString(Twine("~/fooc") + path::get_separator(), Results));
+ EXPECT_TRUE(
+ ContainsExactString(Twine("~/bar") + path::get_separator(), Results));
+ EXPECT_TRUE(
+ ContainsExactString(Twine("~/baz") + path::get_separator(), Results));
+ EXPECT_TRUE(ContainsExactString(
+ Twine("~/test_folder") + path::get_separator(), Results));
+
+ // With ~username syntax it should return one match if there is an exact
+ // match.
+ // It shouldn't translate to the actual directory, it should keep the form the
+ // user typed.
+ Count = CommandCompletions::DiskDirectories("~Lars", Results, Resolver);
+ ASSERT_EQ(1u, Count);
+ ASSERT_EQ(Count, Results.GetSize());
+ EXPECT_TRUE(
+ ContainsExactString(Twine("~Lars") + path::get_separator(), Results));
+
+ // But with a username that is not found, no results are returned.
+ Count = CommandCompletions::DiskDirectories("~Dave", Results, Resolver);
+ ASSERT_EQ(0u, Count);
+ ASSERT_EQ(Count, Results.GetSize());
+
+ // And if there are multiple matches, it should return all of them.
+ Count = CommandCompletions::DiskDirectories("~La", Results, Resolver);
+ ASSERT_EQ(2u, Count);
+ ASSERT_EQ(Count, Results.GetSize());
+ EXPECT_TRUE(
+ ContainsExactString(Twine("~Lars") + path::get_separator(), Results));
+ EXPECT_TRUE(
+ ContainsExactString(Twine("~Larry") + path::get_separator(), Results));
+}
diff --git a/unittests/Language/CPlusPlus/CMakeLists.txt b/unittests/Language/CPlusPlus/CMakeLists.txt
index 6cad97cc6d3c..4882eafc8d85 100644
--- a/unittests/Language/CPlusPlus/CMakeLists.txt
+++ b/unittests/Language/CPlusPlus/CMakeLists.txt
@@ -1,3 +1,6 @@
add_lldb_unittest(LanguageCPlusPlusTests
CPlusPlusLanguageTest.cpp
+
+ LINK_LIBS
+ lldbPluginCPlusPlusLanguage
)
diff --git a/unittests/Language/CPlusPlus/CPlusPlusLanguageTest.cpp b/unittests/Language/CPlusPlus/CPlusPlusLanguageTest.cpp
index 26de31d52a33..8c7fade83759 100644
--- a/unittests/Language/CPlusPlus/CPlusPlusLanguageTest.cpp
+++ b/unittests/Language/CPlusPlus/CPlusPlusLanguageTest.cpp
@@ -6,35 +6,153 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-
#include "gtest/gtest.h"
#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
using namespace lldb_private;
-TEST(CPlusPlusLanguage, MethodName) {
+TEST(CPlusPlusLanguage, MethodNameParsing) {
struct TestCase {
std::string input;
std::string context, basename, arguments, qualifiers, scope_qualified_name;
};
TestCase test_cases[] = {
- {"foo::bar(baz)", "foo", "bar", "(baz)", "", "foo::bar"},
+ {"main(int, char *[]) ", "", "main", "(int, char *[])", "", "main"},
+ {"foo::bar(baz) const", "foo", "bar", "(baz)", "const", "foo::bar"},
+ {"foo::~bar(baz)", "foo", "~bar", "(baz)", "", "foo::~bar"},
+ {"a::b::c::d(e,f)", "a::b::c", "d", "(e,f)", "", "a::b::c::d"},
+ {"void f(int)", "", "f", "(int)", "", "f"},
+
+ // Operators
{"std::basic_ostream<char, std::char_traits<char> >& "
"std::operator<<<std::char_traits<char> >"
"(std::basic_ostream<char, std::char_traits<char> >&, char const*)",
"std", "operator<<<std::char_traits<char> >",
"(std::basic_ostream<char, std::char_traits<char> >&, char const*)", "",
- "std::operator<<<std::char_traits<char> >"}};
+ "std::operator<<<std::char_traits<char> >"},
+ {"operator delete[](void*, clang::ASTContext const&, unsigned long)", "",
+ "operator delete[]", "(void*, clang::ASTContext const&, unsigned long)",
+ "", "operator delete[]"},
+ {"llvm::Optional<clang::PostInitializer>::operator bool() const",
+ "llvm::Optional<clang::PostInitializer>", "operator bool", "()", "const",
+ "llvm::Optional<clang::PostInitializer>::operator bool"},
+ {"(anonymous namespace)::FactManager::operator[](unsigned short)",
+ "(anonymous namespace)::FactManager", "operator[]", "(unsigned short)",
+ "", "(anonymous namespace)::FactManager::operator[]"},
+ {"const int& std::map<int, pair<short, int>>::operator[](short) const",
+ "std::map<int, pair<short, int>>", "operator[]", "(short)", "const",
+ "std::map<int, pair<short, int>>::operator[]"},
+ {"CompareInsn::operator()(llvm::StringRef, InsnMatchEntry const&)",
+ "CompareInsn", "operator()", "(llvm::StringRef, InsnMatchEntry const&)",
+ "", "CompareInsn::operator()"},
+ {"llvm::Optional<llvm::MCFixupKind>::operator*() const &",
+ "llvm::Optional<llvm::MCFixupKind>", "operator*", "()", "const &",
+ "llvm::Optional<llvm::MCFixupKind>::operator*"},
+ // Internal classes
+ {"operator<<(Cls, Cls)::Subclass::function()",
+ "operator<<(Cls, Cls)::Subclass", "function", "()", "",
+ "operator<<(Cls, Cls)::Subclass::function"},
+ {"SAEC::checkFunction(context&) const::CallBack::CallBack(int)",
+ "SAEC::checkFunction(context&) const::CallBack", "CallBack", "(int)", "",
+ "SAEC::checkFunction(context&) const::CallBack::CallBack"},
+ // Anonymous namespace
+ {"XX::(anonymous namespace)::anon_class::anon_func() const",
+ "XX::(anonymous namespace)::anon_class", "anon_func", "()", "const",
+ "XX::(anonymous namespace)::anon_class::anon_func"},
+
+ // Function pointers
+ {"string (*f(vector<int>&&))(float)", "", "f", "(vector<int>&&)", "",
+ "f"},
+ {"void (*&std::_Any_data::_M_access<void (*)()>())()", "std::_Any_data",
+ "_M_access<void (*)()>", "()", "",
+ "std::_Any_data::_M_access<void (*)()>"},
+ {"void (*(*(*(*(*(*(*(* const&func1(int))())())())())())())())()", "",
+ "func1", "(int)", "", "func1"},
+
+ // Decltype
+ {"decltype(nullptr)&& std::forward<decltype(nullptr)>"
+ "(std::remove_reference<decltype(nullptr)>::type&)",
+ "std", "forward<decltype(nullptr)>",
+ "(std::remove_reference<decltype(nullptr)>::type&)", "",
+ "std::forward<decltype(nullptr)>"},
+
+ // Templates
+ {"void llvm::PM<llvm::Module, llvm::AM<llvm::Module>>::"
+ "addPass<llvm::VP>(llvm::VP)",
+ "llvm::PM<llvm::Module, llvm::AM<llvm::Module>>", "addPass<llvm::VP>",
+ "(llvm::VP)", "",
+ "llvm::PM<llvm::Module, llvm::AM<llvm::Module>>::"
+ "addPass<llvm::VP>"},
+ {"void std::vector<Class, std::allocator<Class> >"
+ "::_M_emplace_back_aux<Class const&>(Class const&)",
+ "std::vector<Class, std::allocator<Class> >",
+ "_M_emplace_back_aux<Class const&>", "(Class const&)", "",
+ "std::vector<Class, std::allocator<Class> >::"
+ "_M_emplace_back_aux<Class const&>"},
+ {"unsigned long llvm::countTrailingOnes<unsigned int>"
+ "(unsigned int, llvm::ZeroBehavior)",
+ "llvm", "countTrailingOnes<unsigned int>",
+ "(unsigned int, llvm::ZeroBehavior)", "",
+ "llvm::countTrailingOnes<unsigned int>"},
+ {"std::enable_if<(10u)<(64), bool>::type llvm::isUInt<10u>(unsigned "
+ "long)",
+ "llvm", "isUInt<10u>", "(unsigned long)", "", "llvm::isUInt<10u>"},
+ {"f<A<operator<(X,Y)::Subclass>, sizeof(B)<sizeof(C)>()", "",
+ "f<A<operator<(X,Y)::Subclass>, sizeof(B)<sizeof(C)>", "()", "",
+ "f<A<operator<(X,Y)::Subclass>, sizeof(B)<sizeof(C)>"}};
for (const auto &test : test_cases) {
CPlusPlusLanguage::MethodName method(ConstString(test.input));
- EXPECT_TRUE(method.IsValid());
- EXPECT_EQ(test.context, method.GetContext());
- EXPECT_EQ(test.basename, method.GetBasename());
- EXPECT_EQ(test.arguments, method.GetArguments());
- EXPECT_EQ(test.qualifiers, method.GetQualifiers());
- EXPECT_EQ(test.scope_qualified_name, method.GetScopeQualifiedName());
+ EXPECT_TRUE(method.IsValid()) << test.input;
+ if (method.IsValid()) {
+ EXPECT_EQ(test.context, method.GetContext().str());
+ EXPECT_EQ(test.basename, method.GetBasename().str());
+ EXPECT_EQ(test.arguments, method.GetArguments().str());
+ EXPECT_EQ(test.qualifiers, method.GetQualifiers().str());
+ EXPECT_EQ(test.scope_qualified_name, method.GetScopeQualifiedName());
+ }
+ }
+}
+
+TEST(CPlusPlusLanguage, ExtractContextAndIdentifier) {
+ struct TestCase {
+ std::string input;
+ std::string context, basename;
+ };
+
+ TestCase test_cases[] = {
+ {"main", "", "main"},
+ {"main ", "", "main"},
+ {"foo01::bar", "foo01", "bar"},
+ {"foo::~bar", "foo", "~bar"},
+ {"std::vector<int>::push_back", "std::vector<int>", "push_back"},
+ {"operator<<(Cls, Cls)::Subclass::function",
+ "operator<<(Cls, Cls)::Subclass", "function"},
+ {"std::vector<Class, std::allocator<Class>>"
+ "::_M_emplace_back_aux<Class const&>",
+ "std::vector<Class, std::allocator<Class>>",
+ "_M_emplace_back_aux<Class const&>"}};
+
+ llvm::StringRef context, basename;
+ for (const auto &test : test_cases) {
+ EXPECT_TRUE(CPlusPlusLanguage::ExtractContextAndIdentifier(
+ test.input.c_str(), context, basename));
+ EXPECT_EQ(test.context, context.str());
+ EXPECT_EQ(test.basename, basename.str());
}
+
+ EXPECT_FALSE(CPlusPlusLanguage::ExtractContextAndIdentifier("void", context,
+ basename));
+ EXPECT_FALSE(
+ CPlusPlusLanguage::ExtractContextAndIdentifier("321", context, basename));
+ EXPECT_FALSE(
+ CPlusPlusLanguage::ExtractContextAndIdentifier("", context, basename));
+ EXPECT_FALSE(CPlusPlusLanguage::ExtractContextAndIdentifier(
+ "selector:", context, basename));
+ EXPECT_FALSE(CPlusPlusLanguage::ExtractContextAndIdentifier(
+ "selector:otherField:", context, basename));
+ EXPECT_FALSE(CPlusPlusLanguage::ExtractContextAndIdentifier(
+ "abc::", context, basename));
}
diff --git a/unittests/ObjectFile/CMakeLists.txt b/unittests/ObjectFile/CMakeLists.txt
new file mode 100644
index 000000000000..8a98a9e34e51
--- /dev/null
+++ b/unittests/ObjectFile/CMakeLists.txt
@@ -0,0 +1 @@
+add_subdirectory(ELF)
diff --git a/unittests/ObjectFile/ELF/CMakeLists.txt b/unittests/ObjectFile/ELF/CMakeLists.txt
new file mode 100644
index 000000000000..4cae7ab2c0d6
--- /dev/null
+++ b/unittests/ObjectFile/ELF/CMakeLists.txt
@@ -0,0 +1,7 @@
+add_lldb_unittest(ObjectFileELFTests
+ TestELFHeader.cpp
+
+ LINK_LIBS
+ lldbPluginObjectFileELF
+ lldbCore
+ )
diff --git a/unittests/ObjectFile/ELF/TestELFHeader.cpp b/unittests/ObjectFile/ELF/TestELFHeader.cpp
new file mode 100644
index 000000000000..979011f66a27
--- /dev/null
+++ b/unittests/ObjectFile/ELF/TestELFHeader.cpp
@@ -0,0 +1,62 @@
+//===-- TestELFHeader.cpp ---------------------------------------*- C++ -*-===//
+//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Plugins/ObjectFile/ELF/ELFHeader.h"
+#include "lldb/Utility/DataExtractor.h"
+#include "gtest/gtest.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+
+TEST(ELFHeader, ParseHeaderExtension) {
+ uint8_t data[] = {
+ // e_ident
+ 0x7f, 0x45, 0x4c, 0x46, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+
+ // e_type, e_machine, e_version, e_entry
+ 0x03, 0x00, 0x3e, 0x00, 0x01, 0x00, 0x00, 0x00, 0x90, 0x48, 0x40, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+
+ // e_phoff, e_shoff
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+
+ // e_flags, e_ehsize, e_phentsize, e_phnum, e_shentsize, e_shnum,
+ // e_shstrndx
+ 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x38, 0x00, 0xff, 0xff, 0x40, 0x00,
+ 0x00, 0x00, 0xff, 0xff,
+
+ // sh_name, sh_type, sh_flags
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+
+ // sh_addr, sh_offset
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+
+ // sh_size, sh_link, sh_info
+ 0x23, 0x45, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x56, 0x78, 0x00,
+ 0x12, 0x34, 0x56, 0x00,
+
+ // sh_addralign, sh_entsize
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ };
+
+ DataExtractor extractor(data, sizeof data, eByteOrderLittle, 8);
+ elf::ELFHeader header;
+ offset_t offset = 0;
+ ASSERT_TRUE(header.Parse(extractor, &offset));
+ EXPECT_EQ(0x563412u, header.e_phnum);
+ EXPECT_EQ(0x785634u, header.e_shstrndx);
+ EXPECT_EQ(0x674523u, header.e_shnum);
+}
diff --git a/unittests/Platform/CMakeLists.txt b/unittests/Platform/CMakeLists.txt
index af1121dac7b6..3362ca08d60c 100644
--- a/unittests/Platform/CMakeLists.txt
+++ b/unittests/Platform/CMakeLists.txt
@@ -1,3 +1,8 @@
add_lldb_unittest(LLDBPlatformTests
PlatformDarwinTest.cpp
+
+ LINK_LIBS
+ lldbPluginPlatformMacOSX
+ LINK_COMPONENTS
+ Support
)
diff --git a/unittests/Process/gdb-remote/CMakeLists.txt b/unittests/Process/gdb-remote/CMakeLists.txt
index de4cac11b233..694ba182d42f 100644
--- a/unittests/Process/gdb-remote/CMakeLists.txt
+++ b/unittests/Process/gdb-remote/CMakeLists.txt
@@ -2,4 +2,13 @@ add_lldb_unittest(ProcessGdbRemoteTests
GDBRemoteClientBaseTest.cpp
GDBRemoteCommunicationClientTest.cpp
GDBRemoteTestUtils.cpp
+
+ LINK_LIBS
+ lldbCore
+ lldbHost
+ lldbPluginPlatformMacOSX
+ lldbPluginProcessUtility
+ lldbPluginProcessGDBRemote
+ LINK_COMPONENTS
+ Support
)
diff --git a/unittests/Process/gdb-remote/GDBRemoteClientBaseTest.cpp b/unittests/Process/gdb-remote/GDBRemoteClientBaseTest.cpp
index 2cfd52f5767a..5e709815b2d5 100644
--- a/unittests/Process/gdb-remote/GDBRemoteClientBaseTest.cpp
+++ b/unittests/Process/gdb-remote/GDBRemoteClientBaseTest.cpp
@@ -6,13 +6,6 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-
-#if defined(_MSC_VER) && (_HAS_EXCEPTIONS == 0)
-// Workaround for MSVC standard library bug, which fails to include <thread>
-// when
-// exceptions are disabled.
-#include <eh.h>
-#endif
#include <future>
#include "GDBRemoteTestUtils.h"
@@ -20,7 +13,7 @@
#include "Plugins/Process/Utility/LinuxSignals.h"
#include "Plugins/Process/gdb-remote/GDBRemoteClientBase.h"
#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h"
-#include "lldb/Core/StreamGDBRemote.h"
+#include "lldb/Utility/StreamGDBRemote.h"
#include "llvm/ADT/STLExtras.h"
diff --git a/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp b/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp
index 4bac9ebd404f..d1eb3a7e9c9e 100644
--- a/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp
+++ b/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp
@@ -6,21 +6,15 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-
-#if defined(_MSC_VER) && (_HAS_EXCEPTIONS == 0)
-// Workaround for MSVC standard library bug, which fails to include <thread>
-// when
-// exceptions are disabled.
-#include <eh.h>
-#endif
#include <future>
#include "GDBRemoteTestUtils.h"
#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h"
-#include "lldb/Core/DataBuffer.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/StructuredData.h"
+#include "lldb/Target/MemoryRegionInfo.h"
+#include "lldb/Utility/DataBuffer.h"
#include "llvm/ADT/ArrayRef.h"
@@ -298,6 +292,7 @@ TEST_F(GDBRemoteCommunicationClientTest, TestPacketSpeedJSON) {
client.Disconnect();
server_thread.join();
+ GTEST_LOG_(INFO) << "Formatted output: " << ss.GetData();
auto object_sp = StructuredData::ParseJSON(ss.GetString());
ASSERT_TRUE(bool(object_sp));
auto dict_sp = object_sp->GetAsDictionary();
@@ -313,3 +308,65 @@ TEST_F(GDBRemoteCommunicationClientTest, TestPacketSpeedJSON) {
<< ss.GetString();
ASSERT_EQ(10, num_packets);
}
+
+TEST_F(GDBRemoteCommunicationClientTest, SendSignalsToIgnore) {
+ TestClient client;
+ MockServer server;
+ Connect(client, server);
+ if (HasFailure())
+ return;
+
+ const lldb::tid_t tid = 0x47;
+ const uint32_t reg_num = 4;
+ std::future<Error> result = std::async(std::launch::async, [&] {
+ return client.SendSignalsToIgnore({2, 3, 5, 7, 0xB, 0xD, 0x11});
+ });
+
+ HandlePacket(server, "QPassSignals:02;03;05;07;0b;0d;11", "OK");
+ EXPECT_TRUE(result.get().Success());
+
+ result = std::async(std::launch::async, [&] {
+ return client.SendSignalsToIgnore(std::vector<int32_t>());
+ });
+
+ HandlePacket(server, "QPassSignals:", "OK");
+ EXPECT_TRUE(result.get().Success());
+}
+
+TEST_F(GDBRemoteCommunicationClientTest, GetMemoryRegionInfo) {
+ TestClient client;
+ MockServer server;
+ Connect(client, server);
+ if (HasFailure())
+ return;
+
+ const lldb::addr_t addr = 0xa000;
+ MemoryRegionInfo region_info;
+ std::future<Error> result = std::async(std::launch::async, [&] {
+ return client.GetMemoryRegionInfo(addr, region_info);
+ });
+
+ // name is: /foo/bar.so
+ HandlePacket(server,
+ "qMemoryRegionInfo:a000",
+ "start:a000;size:2000;permissions:rx;name:2f666f6f2f6261722e736f;");
+ EXPECT_TRUE(result.get().Success());
+
+}
+
+TEST_F(GDBRemoteCommunicationClientTest, GetMemoryRegionInfoInvalidResponse) {
+ TestClient client;
+ MockServer server;
+ Connect(client, server);
+ if (HasFailure())
+ return;
+
+ const lldb::addr_t addr = 0x4000;
+ MemoryRegionInfo region_info;
+ std::future<Error> result = std::async(std::launch::async, [&] {
+ return client.GetMemoryRegionInfo(addr, region_info);
+ });
+
+ HandlePacket(server, "qMemoryRegionInfo:4000", "start:4000;size:0000;");
+ EXPECT_FALSE(result.get().Success());
+}
diff --git a/unittests/Process/gdb-remote/GDBRemoteTestUtils.cpp b/unittests/Process/gdb-remote/GDBRemoteTestUtils.cpp
index 58cc9f50586a..08501f50f65a 100644
--- a/unittests/Process/gdb-remote/GDBRemoteTestUtils.cpp
+++ b/unittests/Process/gdb-remote/GDBRemoteTestUtils.cpp
@@ -7,13 +7,6 @@
//
//===----------------------------------------------------------------------===//
-#if defined(_MSC_VER) && (_HAS_EXCEPTIONS == 0)
-// Workaround for MSVC standard library bug, which fails to include <thread>
-// when
-// exceptions are disabled.
-#include <eh.h>
-#endif
-
#include "GDBRemoteTestUtils.h"
#include "lldb/Host/common/TCPSocket.h"
diff --git a/unittests/Process/minidump/CMakeLists.txt b/unittests/Process/minidump/CMakeLists.txt
index 10cb8c34f352..2b2df6327e9a 100644
--- a/unittests/Process/minidump/CMakeLists.txt
+++ b/unittests/Process/minidump/CMakeLists.txt
@@ -1,5 +1,14 @@
add_lldb_unittest(LLDBMinidumpTests
MinidumpParserTest.cpp
+
+ LINK_LIBS
+ lldbCore
+ lldbHost
+ lldbTarget
+ lldbPluginProcessUtility
+ lldbPluginProcessMinidump
+ LINK_COMPONENTS
+ Support
)
set(test_inputs
diff --git a/unittests/Process/minidump/MinidumpParserTest.cpp b/unittests/Process/minidump/MinidumpParserTest.cpp
index 83225e88ee03..755095f75918 100644
--- a/unittests/Process/minidump/MinidumpParserTest.cpp
+++ b/unittests/Process/minidump/MinidumpParserTest.cpp
@@ -19,13 +19,15 @@
#include "gtest/gtest.h"
#include "lldb/Core/ArchSpec.h"
-#include "lldb/Core/DataExtractor.h"
-#include "lldb/Host/FileSpec.h"
#include "lldb/Target/MemoryRegionInfo.h"
+#include "lldb/Utility/DataBufferLLVM.h"
+#include "lldb/Utility/DataExtractor.h"
+#include "lldb/Utility/FileSpec.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/Optional.h"
#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
// C includes
@@ -46,14 +48,15 @@ public:
llvm::sys::path::append(inputs_folder, "Inputs");
}
- void SetUpData(const char *minidump_filename, size_t load_size = SIZE_MAX) {
+ void SetUpData(const char *minidump_filename,
+ uint64_t load_size = UINT64_MAX) {
llvm::SmallString<128> filename = inputs_folder;
llvm::sys::path::append(filename, minidump_filename);
- FileSpec minidump_file(filename.c_str(), false);
- lldb::DataBufferSP data_sp(
- minidump_file.MemoryMapFileContents(0, load_size));
+
+ auto BufferPtr = DataBufferLLVM::CreateSliceFromPath(filename, load_size, 0);
+
llvm::Optional<MinidumpParser> optional_parser =
- MinidumpParser::Create(data_sp);
+ MinidumpParser::Create(BufferPtr);
ASSERT_TRUE(optional_parser.hasValue());
parser.reset(new MinidumpParser(optional_parser.getValue()));
ASSERT_GT(parser->GetData().size(), 0UL);
@@ -450,4 +453,4 @@ TEST_F(MinidumpParserTest, ConvertMinidumpContext_x86_32_wow64) {
REG_VAL32(buf->GetBytes() + reg_info[reg_index].byte_offset));
}
}
-} \ No newline at end of file
+}
diff --git a/unittests/ScriptInterpreter/Python/CMakeLists.txt b/unittests/ScriptInterpreter/Python/CMakeLists.txt
index f011200e6475..891ade25b76b 100644
--- a/unittests/ScriptInterpreter/Python/CMakeLists.txt
+++ b/unittests/ScriptInterpreter/Python/CMakeLists.txt
@@ -2,7 +2,12 @@ add_lldb_unittest(ScriptInterpreterPythonTests
PythonDataObjectsTests.cpp
PythonExceptionStateTests.cpp
PythonTestSuite.cpp
- )
- target_link_libraries(ScriptInterpreterPythonTests lldbPluginScriptInterpreterPython ${PYTHON_LIBRARY})
+ LINK_LIBS
+ lldbHost
+ lldbPluginScriptInterpreterPython
+ ${PYTHON_LIBRARY}
+ LINK_COMPONENTS
+ Support
+ )
\ No newline at end of file
diff --git a/unittests/Signals/CMakeLists.txt b/unittests/Signals/CMakeLists.txt
new file mode 100644
index 000000000000..e3f2e884d930
--- /dev/null
+++ b/unittests/Signals/CMakeLists.txt
@@ -0,0 +1,6 @@
+add_lldb_unittest(SignalsTests
+ UnixSignalsTest.cpp
+
+ LINK_LIBS
+ lldbTarget
+ )
diff --git a/unittests/Signals/UnixSignalsTest.cpp b/unittests/Signals/UnixSignalsTest.cpp
new file mode 100644
index 000000000000..9183aed76aef
--- /dev/null
+++ b/unittests/Signals/UnixSignalsTest.cpp
@@ -0,0 +1,140 @@
+//===-- UnixSignalsTest.cpp -------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <string>
+
+#include "gtest/gtest.h"
+
+#include "lldb/Target/UnixSignals.h"
+#include "llvm/Support/FormatVariadic.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using llvm::None;
+
+class TestSignals : public UnixSignals {
+public:
+ TestSignals() {
+ m_signals.clear();
+ AddSignal(2, "SIG2", false, true, true, "DESC2");
+ AddSignal(4, "SIG4", true, false, true, "DESC4");
+ AddSignal(8, "SIG8", true, true, true, "DESC8");
+ AddSignal(16, "SIG16", true, false, false, "DESC16");
+ }
+};
+
+void ExpectEqArrays(llvm::ArrayRef<int32_t> expected,
+ llvm::ArrayRef<int32_t> observed, const char *file,
+ int line) {
+ std::string location = llvm::formatv("{0}:{1}", file, line);
+ ASSERT_EQ(expected.size(), observed.size()) << location;
+
+ for (size_t i = 0; i < observed.size(); ++i) {
+ ASSERT_EQ(expected[i], observed[i])
+ << "array index: " << i << "location:" << location;
+ }
+}
+
+#define EXPECT_EQ_ARRAYS(expected, observed) \
+ ExpectEqArrays((expected), (observed), __FILE__, __LINE__);
+
+TEST(UnixSignalsTest, Iteration) {
+ TestSignals signals;
+
+ EXPECT_EQ(4, signals.GetNumSignals());
+ EXPECT_EQ(2, signals.GetFirstSignalNumber());
+ EXPECT_EQ(4, signals.GetNextSignalNumber(2));
+ EXPECT_EQ(8, signals.GetNextSignalNumber(4));
+ EXPECT_EQ(16, signals.GetNextSignalNumber(8));
+ EXPECT_EQ(LLDB_INVALID_SIGNAL_NUMBER, signals.GetNextSignalNumber(16));
+}
+
+TEST(UnixSignalsTest, GetInfo) {
+ TestSignals signals;
+
+ bool should_suppress = false, should_stop = false, should_notify = false;
+ int32_t signo = 4;
+ std::string name =
+ signals.GetSignalInfo(signo, should_suppress, should_stop, should_notify);
+ EXPECT_EQ("SIG4", name);
+ EXPECT_EQ(true, should_suppress);
+ EXPECT_EQ(false, should_stop);
+ EXPECT_EQ(true, should_notify);
+
+ EXPECT_EQ(true, signals.GetShouldSuppress(signo));
+ EXPECT_EQ(false, signals.GetShouldStop(signo));
+ EXPECT_EQ(true, signals.GetShouldNotify(signo));
+ EXPECT_EQ(name, signals.GetSignalAsCString(signo));
+}
+
+TEST(UnixSignalsTest, VersionChange) {
+ TestSignals signals;
+
+ int32_t signo = 8;
+ uint64_t ver = signals.GetVersion();
+ EXPECT_GT(ver, 0ull);
+ EXPECT_EQ(true, signals.GetShouldSuppress(signo));
+ EXPECT_EQ(true, signals.GetShouldStop(signo));
+ EXPECT_EQ(true, signals.GetShouldNotify(signo));
+
+ EXPECT_EQ(signals.GetVersion(), ver);
+
+ signals.SetShouldSuppress(signo, false);
+ EXPECT_LT(ver, signals.GetVersion());
+ ver = signals.GetVersion();
+
+ signals.SetShouldStop(signo, true);
+ EXPECT_LT(ver, signals.GetVersion());
+ ver = signals.GetVersion();
+
+ signals.SetShouldNotify(signo, false);
+ EXPECT_LT(ver, signals.GetVersion());
+ ver = signals.GetVersion();
+
+ EXPECT_EQ(false, signals.GetShouldSuppress(signo));
+ EXPECT_EQ(true, signals.GetShouldStop(signo));
+ EXPECT_EQ(false, signals.GetShouldNotify(signo));
+
+ EXPECT_EQ(ver, signals.GetVersion());
+}
+
+TEST(UnixSignalsTest, GetFilteredSignals) {
+ TestSignals signals;
+
+ auto all_signals = signals.GetFilteredSignals(None, None, None);
+ std::vector<int32_t> expected = {2, 4, 8, 16};
+ EXPECT_EQ_ARRAYS(expected, all_signals);
+
+ auto supressed = signals.GetFilteredSignals(true, None, None);
+ expected = {4, 8, 16};
+ EXPECT_EQ_ARRAYS(expected, supressed);
+
+ auto not_supressed = signals.GetFilteredSignals(false, None, None);
+ expected = {2};
+ EXPECT_EQ_ARRAYS(expected, not_supressed);
+
+ auto stopped = signals.GetFilteredSignals(None, true, None);
+ expected = {2, 8};
+ EXPECT_EQ_ARRAYS(expected, stopped);
+
+ auto not_stopped = signals.GetFilteredSignals(None, false, None);
+ expected = {4, 16};
+ EXPECT_EQ_ARRAYS(expected, not_stopped);
+
+ auto notified = signals.GetFilteredSignals(None, None, true);
+ expected = {2, 4, 8};
+ EXPECT_EQ_ARRAYS(expected, notified);
+
+ auto not_notified = signals.GetFilteredSignals(None, None, false);
+ expected = {16};
+ EXPECT_EQ_ARRAYS(expected, not_notified);
+
+ auto signal4 = signals.GetFilteredSignals(true, false, true);
+ expected = {4};
+ EXPECT_EQ_ARRAYS(expected, signal4);
+}
diff --git a/unittests/Symbol/CMakeLists.txt b/unittests/Symbol/CMakeLists.txt
index 75cabddba5c4..dca5f17b15de 100644
--- a/unittests/Symbol/CMakeLists.txt
+++ b/unittests/Symbol/CMakeLists.txt
@@ -1,4 +1,8 @@
add_lldb_unittest(SymbolTests
TestClangASTContext.cpp
TestType.cpp
+
+ LINK_LIBS
+ lldbHost
+ lldbSymbol
)
diff --git a/unittests/SymbolFile/DWARF/CMakeLists.txt b/unittests/SymbolFile/DWARF/CMakeLists.txt
index c0e4300dadd7..c764bd477fab 100644
--- a/unittests/SymbolFile/DWARF/CMakeLists.txt
+++ b/unittests/SymbolFile/DWARF/CMakeLists.txt
@@ -1,5 +1,16 @@
add_lldb_unittest(SymbolFileDWARFTests
SymbolFileDWARFTests.cpp
+
+ LINK_LIBS
+ lldbCore
+ lldbHost
+ lldbSymbol
+ lldbPluginObjectFilePECOFF
+ lldbPluginSymbolFileDWARF
+ lldbPluginSymbolFilePDB
+ LINK_COMPONENTS
+ Support
+ DebugInfoPDB
)
set(test_inputs
diff --git a/unittests/SymbolFile/DWARF/SymbolFileDWARFTests.cpp b/unittests/SymbolFile/DWARF/SymbolFileDWARFTests.cpp
index 10465d785ac9..8ef6ad05bd54 100644
--- a/unittests/SymbolFile/DWARF/SymbolFileDWARFTests.cpp
+++ b/unittests/SymbolFile/DWARF/SymbolFileDWARFTests.cpp
@@ -19,12 +19,12 @@
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Host/FileSpec.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/LineTable.h"
#include "lldb/Symbol/SymbolVendor.h"
+#include "lldb/Utility/FileSpec.h"
#include "Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h"
#include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h"
diff --git a/unittests/SymbolFile/PDB/CMakeLists.txt b/unittests/SymbolFile/PDB/CMakeLists.txt
index 37adf39463d4..d9aff4e2eaca 100644
--- a/unittests/SymbolFile/PDB/CMakeLists.txt
+++ b/unittests/SymbolFile/PDB/CMakeLists.txt
@@ -1,5 +1,16 @@
add_lldb_unittest(SymbolFilePDBTests
SymbolFilePDBTests.cpp
+
+ LINK_LIBS
+ lldbCore
+ lldbHost
+ lldbSymbol
+ lldbPluginObjectFilePECOFF
+ lldbPluginSymbolFileDWARF
+ lldbPluginSymbolFilePDB
+ LINK_COMPONENTS
+ Support
+ DebugInfoPDB
)
set(test_inputs
diff --git a/unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp b/unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp
index 5aedffecfe90..226057f89369 100644
--- a/unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp
+++ b/unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp
@@ -19,12 +19,12 @@
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Host/FileSpec.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/LineTable.h"
#include "lldb/Symbol/SymbolVendor.h"
+#include "lldb/Utility/FileSpec.h"
#include "Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h"
#include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h"
@@ -120,7 +120,7 @@ protected:
return false;
}
- uint64_t GetGlobalConstantInteger(const llvm::pdb::IPDBSession &session,
+ uint64_t GetGlobalConstantInteger(llvm::pdb::IPDBSession &session,
llvm::StringRef var) const {
auto global = session.getGlobalScope();
auto results =
@@ -371,7 +371,7 @@ TEST_F(SymbolFilePDBTests, TestSimpleClassTypes) {
SymbolVendor *plugin = module->GetSymbolVendor();
SymbolFilePDB *symfile =
static_cast<SymbolFilePDB *>(plugin->GetSymbolFile());
- const llvm::pdb::IPDBSession &session = symfile->GetPDBSession();
+ llvm::pdb::IPDBSession &session = symfile->GetPDBSession();
SymbolContext sc;
llvm::DenseSet<SymbolFile *> searched_files;
TypeMap results;
@@ -394,7 +394,7 @@ TEST_F(SymbolFilePDBTests, TestNestedClassTypes) {
SymbolVendor *plugin = module->GetSymbolVendor();
SymbolFilePDB *symfile =
static_cast<SymbolFilePDB *>(plugin->GetSymbolFile());
- const llvm::pdb::IPDBSession &session = symfile->GetPDBSession();
+ llvm::pdb::IPDBSession &session = symfile->GetPDBSession();
SymbolContext sc;
llvm::DenseSet<SymbolFile *> searched_files;
TypeMap results;
@@ -417,7 +417,7 @@ TEST_F(SymbolFilePDBTests, TestClassInNamespace) {
SymbolVendor *plugin = module->GetSymbolVendor();
SymbolFilePDB *symfile =
static_cast<SymbolFilePDB *>(plugin->GetSymbolFile());
- const llvm::pdb::IPDBSession &session = symfile->GetPDBSession();
+ llvm::pdb::IPDBSession &session = symfile->GetPDBSession();
SymbolContext sc;
llvm::DenseSet<SymbolFile *> searched_files;
TypeMap results;
@@ -440,7 +440,7 @@ TEST_F(SymbolFilePDBTests, TestEnumTypes) {
SymbolVendor *plugin = module->GetSymbolVendor();
SymbolFilePDB *symfile =
static_cast<SymbolFilePDB *>(plugin->GetSymbolFile());
- const llvm::pdb::IPDBSession &session = symfile->GetPDBSession();
+ llvm::pdb::IPDBSession &session = symfile->GetPDBSession();
SymbolContext sc;
llvm::DenseSet<SymbolFile *> searched_files;
const char *EnumsToCheck[] = {"Enum", "ShortEnum"};
@@ -487,7 +487,7 @@ TEST_F(SymbolFilePDBTests, TestTypedefs) {
SymbolVendor *plugin = module->GetSymbolVendor();
SymbolFilePDB *symfile =
static_cast<SymbolFilePDB *>(plugin->GetSymbolFile());
- const llvm::pdb::IPDBSession &session = symfile->GetPDBSession();
+ llvm::pdb::IPDBSession &session = symfile->GetPDBSession();
SymbolContext sc;
llvm::DenseSet<SymbolFile *> searched_files;
TypeMap results;
diff --git a/unittests/Target/CMakeLists.txt b/unittests/Target/CMakeLists.txt
new file mode 100644
index 000000000000..e4f6e52b0634
--- /dev/null
+++ b/unittests/Target/CMakeLists.txt
@@ -0,0 +1,15 @@
+add_lldb_unittest(TargetTests
+ MemoryRegionInfoTest.cpp
+ ModuleCacheTest.cpp
+
+ LINK_LIBS
+ lldbCore
+ lldbHost
+ lldbSymbol
+ lldbUtility
+ lldbPluginObjectFileELF
+ LINK_COMPONENTS
+ Support
+ )
+
+add_unittest_inputs(TargetTests TestModule.so)
diff --git a/unittests/Utility/Inputs/TestModule.c b/unittests/Target/Inputs/TestModule.c
index 6347f7264944..6347f7264944 100644
--- a/unittests/Utility/Inputs/TestModule.c
+++ b/unittests/Target/Inputs/TestModule.c
diff --git a/unittests/Utility/Inputs/TestModule.so b/unittests/Target/Inputs/TestModule.so
index 9e9bf0b6e17e..9e9bf0b6e17e 100644
--- a/unittests/Utility/Inputs/TestModule.so
+++ b/unittests/Target/Inputs/TestModule.so
Binary files differ
diff --git a/unittests/Target/MemoryRegionInfoTest.cpp b/unittests/Target/MemoryRegionInfoTest.cpp
new file mode 100644
index 000000000000..704f7f8c48c6
--- /dev/null
+++ b/unittests/Target/MemoryRegionInfoTest.cpp
@@ -0,0 +1,20 @@
+//===-- MemoryRegionInfoTest.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/Target/MemoryRegionInfo.h"
+#include "llvm/Support/FormatVariadic.h"
+#include "gtest/gtest.h"
+
+using namespace lldb_private;
+
+TEST(MemoryRegionInfoTest, Formatv) {
+ EXPECT_EQ("yes", llvm::formatv("{0}", MemoryRegionInfo::eYes).str());
+ EXPECT_EQ("no", llvm::formatv("{0}", MemoryRegionInfo::eNo).str());
+ EXPECT_EQ("don't know", llvm::formatv("{0}", MemoryRegionInfo::eDontKnow).str());
+}
diff --git a/unittests/Utility/ModuleCacheTest.cpp b/unittests/Target/ModuleCacheTest.cpp
index 911c278c1626..09b3edc4148b 100644
--- a/unittests/Utility/ModuleCacheTest.cpp
+++ b/unittests/Target/ModuleCacheTest.cpp
@@ -5,11 +5,11 @@
#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"
+#include "lldb/Target/ModuleCache.h"
extern const char *TestMainArgv0;
diff --git a/unittests/UnwindAssembly/InstEmulation/CMakeLists.txt b/unittests/UnwindAssembly/InstEmulation/CMakeLists.txt
index 5e274a229919..7cc0befa386b 100644
--- a/unittests/UnwindAssembly/InstEmulation/CMakeLists.txt
+++ b/unittests/UnwindAssembly/InstEmulation/CMakeLists.txt
@@ -1,3 +1,15 @@
if ("AArch64" IN_LIST LLVM_TARGETS_TO_BUILD)
- add_lldb_unittest(InstEmulationTests TestArm64InstEmulation.cpp)
+ add_lldb_unittest(InstEmulationTests
+ TestArm64InstEmulation.cpp
+ LINK_LIBS
+ lldbCore
+ lldbSymbol
+ lldbTarget
+ lldbPluginUnwindAssemblyInstEmulation
+ lldbPluginDisassemblerLLVM
+ lldbPluginInstructionARM64
+ lldbPluginProcessUtility
+ LINK_COMPONENTS
+ Support
+ ${LLVM_TARGETS_TO_BUILD})
endif()
diff --git a/unittests/UnwindAssembly/x86/CMakeLists.txt b/unittests/UnwindAssembly/x86/CMakeLists.txt
index 7112467b3975..2b5b31f79063 100644
--- a/unittests/UnwindAssembly/x86/CMakeLists.txt
+++ b/unittests/UnwindAssembly/x86/CMakeLists.txt
@@ -1,3 +1,10 @@
add_lldb_unittest(UnwindAssemblyx86Tests
Testx86AssemblyInspectionEngine.cpp
+ LINK_LIBS
+ lldbCore
+ lldbSymbol
+ lldbPluginUnwindAssemblyX86
+ LINK_COMPONENTS
+ Support
+ ${LLVM_TARGETS_TO_BUILD}
)
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/Core/ErrorTest.cpp b/unittests/Utility/ErrorTest.cpp
index f3727bbd78ae..a114b26ebe54 100644
--- a/unittests/Core/ErrorTest.cpp
+++ b/unittests/Utility/ErrorTest.cpp
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/Utility/Error.h"
#include "gtest/gtest.h"
-#include "lldb/Core/Error.h"
using namespace lldb_private;
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/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());
+}
diff --git a/unittests/debugserver/CMakeLists.txt b/unittests/debugserver/CMakeLists.txt
new file mode 100644
index 000000000000..cfb520a0dc76
--- /dev/null
+++ b/unittests/debugserver/CMakeLists.txt
@@ -0,0 +1,19 @@
+# Note: debugserver is a Darwin-only implementation of a remote debugging
+# server. It is not intended to be used on other platforms. The tests are here
+# because using the LLDB Host API is convienent and allows testing of both parts
+# of the debugserver communication path. If you are looking for a non-darwin
+# remote debugging server, please use lldb-server.
+
+include_directories(${LLDB_SOURCE_DIR}/tools/debugserver/source
+ ${LLDB_SOURCE_DIR}/tools/debugserver/source/MacOSX)
+
+add_lldb_unittest(debugserverTests
+ RNBSocketTest.cpp
+ debugserver_LogCallback.cpp
+
+ LINK_LIBS
+ lldbDebugserverCommon
+ lldbHost
+ LINK_COMPONENTS
+ Support
+ )
diff --git a/unittests/debugserver/RNBSocketTest.cpp b/unittests/debugserver/RNBSocketTest.cpp
new file mode 100644
index 000000000000..997041f6154b
--- /dev/null
+++ b/unittests/debugserver/RNBSocketTest.cpp
@@ -0,0 +1,133 @@
+//===-- RNBSocketTest.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 <arpa/inet.h>
+#include <sys/sysctl.h>
+#include <unistd.h>
+
+#include "RNBDefs.h"
+#include "RNBSocket.h"
+#include "lldb/Host/Socket.h"
+#include "lldb/Host/StringConvert.h"
+#include "lldb/Host/common/TCPSocket.h"
+
+using namespace lldb_private;
+
+std::string hello = "Hello, world!";
+std::string goodbye = "Goodbye!";
+
+static void ServerCallbackv4(const void *baton, in_port_t port) {
+ auto child_pid = fork();
+ if (child_pid == 0) {
+ Socket *client_socket;
+ char addr_buffer[256];
+ sprintf(addr_buffer, "%s:%d", baton, port);
+ Error err = Socket::TcpConnect(addr_buffer, false, client_socket);
+ if (err.Fail())
+ abort();
+ char buffer[32];
+ size_t read_size = 32;
+ err = client_socket->Read((void *)&buffer[0], read_size);
+ if (err.Fail())
+ abort();
+ std::string Recv(&buffer[0], read_size);
+ if (Recv != hello)
+ abort();
+ size_t write_size = goodbye.length();
+ err = client_socket->Write(goodbye.c_str(), write_size);
+ if (err.Fail())
+ abort();
+ if (write_size != goodbye.length())
+ abort();
+ delete client_socket;
+ exit(0);
+ }
+}
+
+void TestSocketListen(const char *addr) {
+ RNBSocket server_socket;
+ auto result =
+ server_socket.Listen(addr, 0, ServerCallbackv4, (const void *)addr);
+ ASSERT_TRUE(result == rnb_success);
+ result = server_socket.Write(hello.c_str(), hello.length());
+ ASSERT_TRUE(result == rnb_success);
+ std::string bye;
+ result = server_socket.Read(bye);
+ ASSERT_TRUE(result == rnb_success);
+ ASSERT_EQ(bye, goodbye);
+
+ int exit_status;
+ wait(&exit_status);
+ ASSERT_EQ(exit_status, 0);
+}
+
+TEST(RNBSocket, LoopBackListenIPv4) { TestSocketListen("127.0.0.1"); }
+
+void TestSocketConnect(const char *addr) {
+ char addr_wrap[256];
+ sprintf(addr_wrap, "%s:0", addr);
+
+ Socket *server_socket;
+ Predicate<uint16_t> port_predicate;
+ port_predicate.SetValue(0, eBroadcastNever);
+ Error err =
+ Socket::TcpListen(addr_wrap, false, server_socket, &port_predicate);
+ ASSERT_FALSE(err.Fail());
+
+ auto port = ((TCPSocket *)server_socket)->GetLocalPortNumber();
+ auto child_pid = fork();
+ if (child_pid != 0) {
+ RNBSocket client_socket;
+ auto result = client_socket.Connect(addr, port);
+ ASSERT_TRUE(result == rnb_success);
+ result = client_socket.Write(hello.c_str(), hello.length());
+ ASSERT_TRUE(result == rnb_success);
+ std::string bye;
+ result = client_socket.Read(bye);
+ ASSERT_TRUE(result == rnb_success);
+ ASSERT_EQ(bye, goodbye);
+ } else {
+ Socket *connected_socket;
+ err = server_socket->Accept(addr_wrap, false, connected_socket);
+ if (err.Fail()) {
+ llvm::errs() << err.AsCString();
+ abort();
+ }
+ char buffer[32];
+ size_t read_size = 32;
+ err = connected_socket->Read((void *)&buffer[0], read_size);
+ if (err.Fail()) {
+ llvm::errs() << err.AsCString();
+ abort();
+ }
+ std::string Recv(&buffer[0], read_size);
+ if (Recv != hello) {
+ llvm::errs() << err.AsCString();
+ abort();
+ }
+ size_t write_size = goodbye.length();
+ err = connected_socket->Write(goodbye.c_str(), write_size);
+ if (err.Fail()) {
+ llvm::errs() << err.AsCString();
+ abort();
+ }
+ if (write_size != goodbye.length()) {
+ llvm::errs() << err.AsCString();
+ abort();
+ }
+ exit(0);
+ }
+ int exit_status;
+ wait(&exit_status);
+ ASSERT_EQ(exit_status, 0);
+}
+
+TEST(RNBSocket, LoopBackConnectIPv4) { TestSocketConnect("127.0.0.1"); }
diff --git a/unittests/debugserver/debugserver_LogCallback.cpp b/unittests/debugserver/debugserver_LogCallback.cpp
new file mode 100644
index 000000000000..7a724b419775
--- /dev/null
+++ b/unittests/debugserver/debugserver_LogCallback.cpp
@@ -0,0 +1,20 @@
+//===-- debugserver_LogCallback.cpp -----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//------------------------------------------------------------------------------
+// this function is defined in debugserver.cpp, but is needed to link the
+// debugserver Common library. It is for logging only, so it is left
+// unimplemented here.
+//------------------------------------------------------------------------------
+
+#include <stdint.h>
+#include <stdarg.h>
+
+void FileLogCallback(void *baton, uint32_t flags, const char *format,
+ va_list args) {}
diff --git a/unittests/gtest_common.h b/unittests/gtest_common.h
index c8fe92575941..f61ba9d0c371 100644
--- a/unittests/gtest_common.h
+++ b/unittests/gtest_common.h
@@ -15,12 +15,3 @@
// This header file is force included by all of LLDB's unittest compilation
// units. Be very leary about putting anything in this file.
-
-#if defined(_MSC_VER) && (_HAS_EXCEPTIONS == 0)
-// Due to a bug in <thread>, when _HAS_EXCEPTIONS == 0 the header will try to
-// call
-// uncaught_exception() without having a declaration for it. The fix for this
-// is
-// to manually #include <eh.h>, which contains this declaration.
-#include <eh.h>
-#endif