Imported Upstream version 6.10.0.49

Former-commit-id: 1d6753294b2993e1fbf92de9366bb9544db4189b
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2020-01-16 16:38:04 +00:00
parent d94e79959b
commit 468663ddbb
48518 changed files with 2789335 additions and 61176 deletions

View File

@@ -0,0 +1,25 @@
set (FILES
FileSpecTest.cpp
FileSystemTest.cpp
HostInfoTest.cpp
HostTest.cpp
MainLoopTest.cpp
SocketAddressTest.cpp
SocketTest.cpp
SymbolsTest.cpp
TaskPoolTest.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
)

View File

@@ -0,0 +1,310 @@
//===-- FileSpecTest.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/FileSpec.h"
using namespace lldb_private;
TEST(FileSpecTest, FileAndDirectoryComponents) {
FileSpec fs_posix("/foo/bar", false, FileSpec::ePathSyntaxPosix);
EXPECT_STREQ("/foo/bar", fs_posix.GetCString());
EXPECT_STREQ("/foo", fs_posix.GetDirectory().GetCString());
EXPECT_STREQ("bar", fs_posix.GetFilename().GetCString());
FileSpec fs_windows("F:\\bar", false, FileSpec::ePathSyntaxWindows);
EXPECT_STREQ("F:\\bar", fs_windows.GetCString());
// EXPECT_STREQ("F:\\", fs_windows.GetDirectory().GetCString()); // It returns
// "F:/"
EXPECT_STREQ("bar", fs_windows.GetFilename().GetCString());
FileSpec fs_posix_root("/", false, FileSpec::ePathSyntaxPosix);
EXPECT_STREQ("/", fs_posix_root.GetCString());
EXPECT_EQ(nullptr, fs_posix_root.GetDirectory().GetCString());
EXPECT_STREQ("/", fs_posix_root.GetFilename().GetCString());
FileSpec fs_windows_drive("F:", false, FileSpec::ePathSyntaxWindows);
EXPECT_STREQ("F:", fs_windows_drive.GetCString());
EXPECT_EQ(nullptr, fs_windows_drive.GetDirectory().GetCString());
EXPECT_STREQ("F:", fs_windows_drive.GetFilename().GetCString());
FileSpec fs_windows_root("F:\\", false, FileSpec::ePathSyntaxWindows);
EXPECT_STREQ("F:\\", fs_windows_root.GetCString());
EXPECT_STREQ("F:", fs_windows_root.GetDirectory().GetCString());
// EXPECT_STREQ("\\", fs_windows_root.GetFilename().GetCString()); // It
// returns "/"
FileSpec fs_posix_long("/foo/bar/baz", false, FileSpec::ePathSyntaxPosix);
EXPECT_STREQ("/foo/bar/baz", fs_posix_long.GetCString());
EXPECT_STREQ("/foo/bar", fs_posix_long.GetDirectory().GetCString());
EXPECT_STREQ("baz", fs_posix_long.GetFilename().GetCString());
FileSpec fs_windows_long("F:\\bar\\baz", false, FileSpec::ePathSyntaxWindows);
EXPECT_STREQ("F:\\bar\\baz", fs_windows_long.GetCString());
// EXPECT_STREQ("F:\\bar", fs_windows_long.GetDirectory().GetCString()); // It
// returns "F:/bar"
EXPECT_STREQ("baz", fs_windows_long.GetFilename().GetCString());
FileSpec fs_posix_trailing_slash("/foo/bar/", false,
FileSpec::ePathSyntaxPosix);
EXPECT_STREQ("/foo/bar/.", fs_posix_trailing_slash.GetCString());
EXPECT_STREQ("/foo/bar", fs_posix_trailing_slash.GetDirectory().GetCString());
EXPECT_STREQ(".", fs_posix_trailing_slash.GetFilename().GetCString());
FileSpec fs_windows_trailing_slash("F:\\bar\\", false,
FileSpec::ePathSyntaxWindows);
EXPECT_STREQ("F:\\bar\\.", fs_windows_trailing_slash.GetCString());
// EXPECT_STREQ("F:\\bar",
// fs_windows_trailing_slash.GetDirectory().GetCString()); // It returns
// "F:/bar"
EXPECT_STREQ(".", fs_windows_trailing_slash.GetFilename().GetCString());
}
TEST(FileSpecTest, AppendPathComponent) {
FileSpec fs_posix("/foo", false, FileSpec::ePathSyntaxPosix);
fs_posix.AppendPathComponent("bar");
EXPECT_STREQ("/foo/bar", fs_posix.GetCString());
EXPECT_STREQ("/foo", fs_posix.GetDirectory().GetCString());
EXPECT_STREQ("bar", fs_posix.GetFilename().GetCString());
FileSpec fs_posix_2("/foo", false, FileSpec::ePathSyntaxPosix);
fs_posix_2.AppendPathComponent("//bar/baz");
EXPECT_STREQ("/foo/bar/baz", fs_posix_2.GetCString());
EXPECT_STREQ("/foo/bar", fs_posix_2.GetDirectory().GetCString());
EXPECT_STREQ("baz", fs_posix_2.GetFilename().GetCString());
FileSpec fs_windows("F:\\bar", false, FileSpec::ePathSyntaxWindows);
fs_windows.AppendPathComponent("baz");
EXPECT_STREQ("F:\\bar\\baz", fs_windows.GetCString());
// EXPECT_STREQ("F:\\bar", fs_windows.GetDirectory().GetCString()); // It
// returns "F:/bar"
EXPECT_STREQ("baz", fs_windows.GetFilename().GetCString());
FileSpec fs_posix_root("/", false, FileSpec::ePathSyntaxPosix);
fs_posix_root.AppendPathComponent("bar");
EXPECT_STREQ("/bar", fs_posix_root.GetCString());
EXPECT_STREQ("/", fs_posix_root.GetDirectory().GetCString());
EXPECT_STREQ("bar", fs_posix_root.GetFilename().GetCString());
FileSpec fs_windows_root("F:\\", false, FileSpec::ePathSyntaxWindows);
fs_windows_root.AppendPathComponent("bar");
EXPECT_STREQ("F:\\bar", fs_windows_root.GetCString());
// EXPECT_STREQ("F:\\", fs_windows_root.GetDirectory().GetCString()); // It
// returns "F:/"
EXPECT_STREQ("bar", fs_windows_root.GetFilename().GetCString());
}
TEST(FileSpecTest, CopyByAppendingPathComponent) {
FileSpec fs = FileSpec("/foo", false, FileSpec::ePathSyntaxPosix)
.CopyByAppendingPathComponent("bar");
EXPECT_STREQ("/foo/bar", fs.GetCString());
EXPECT_STREQ("/foo", fs.GetDirectory().GetCString());
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))
<< "File one: " << one.GetCString() << "\nFile two: " << two.GetCString()
<< "\nFull match: " << full_match
<< "\nRemove backup dots: " << remove_backup_dots;
}
TEST(FileSpecTest, EqualSeparator) {
FileSpec backward("C:\\foo\\bar", false, FileSpec::ePathSyntaxWindows);
FileSpec forward("C:/foo/bar", false, FileSpec::ePathSyntaxWindows);
EXPECT_EQ(forward, backward);
const bool full_match = true;
const bool remove_backup_dots = true;
const bool match = true;
Compare(forward, backward, full_match, remove_backup_dots, match);
Compare(forward, backward, full_match, !remove_backup_dots, match);
Compare(forward, backward, !full_match, remove_backup_dots, match);
Compare(forward, backward, !full_match, !remove_backup_dots, match);
}
TEST(FileSpecTest, EqualDotsWindows) {
const bool full_match = true;
const bool remove_backup_dots = true;
const bool match = true;
std::pair<const char *, const char *> tests[] = {
{R"(C:\foo\bar\baz)", R"(C:\foo\foo\..\bar\baz)"},
{R"(C:\bar\baz)", R"(C:\foo\..\bar\baz)"},
{R"(C:\bar\baz)", R"(C:/foo/../bar/baz)"},
{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) {
FileSpec one(test.first, false, FileSpec::ePathSyntaxWindows);
FileSpec two(test.second, false, FileSpec::ePathSyntaxWindows);
EXPECT_NE(one, two);
Compare(one, two, full_match, remove_backup_dots, match);
Compare(one, two, full_match, !remove_backup_dots, !match);
Compare(one, two, !full_match, remove_backup_dots, match);
Compare(one, two, !full_match, !remove_backup_dots, !match);
}
}
TEST(FileSpecTest, EqualDotsPosix) {
const bool full_match = true;
const bool remove_backup_dots = true;
const bool match = true;
std::pair<const char *, const char *> tests[] = {
{R"(/foo/bar/baz)", R"(/foo/foo/../bar/baz)"},
{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) {
FileSpec one(test.first, false, FileSpec::ePathSyntaxPosix);
FileSpec two(test.second, false, FileSpec::ePathSyntaxPosix);
EXPECT_NE(one, two);
Compare(one, two, full_match, remove_backup_dots, match);
Compare(one, two, full_match, !remove_backup_dots, !match);
Compare(one, two, !full_match, remove_backup_dots, match);
Compare(one, two, !full_match, !remove_backup_dots, !match);
}
}
TEST(FileSpecTest, EqualDotsPosixRoot) {
const bool full_match = true;
const bool remove_backup_dots = true;
const bool match = true;
std::pair<const char *, const char *> tests[] = {
{R"(/)", R"(/..)"}, {R"(/)", R"(/.)"}, {R"(/)", R"(/foo/..)"},
};
for(const auto &test: tests) {
FileSpec one(test.first, false, FileSpec::ePathSyntaxPosix);
FileSpec two(test.second, false, FileSpec::ePathSyntaxPosix);
EXPECT_NE(one, two);
Compare(one, two, full_match, remove_backup_dots, match);
Compare(one, two, full_match, !remove_backup_dots, !match);
Compare(one, two, !full_match, remove_backup_dots, !match);
Compare(one, two, !full_match, !remove_backup_dots, !match);
}
}
TEST(FileSpecTest, GetNormalizedPath) {
std::pair<const char *, const char *> posix_tests[] = {
{"/foo/.././bar", "/bar"},
{"/foo/./../bar", "/bar"},
{"/foo/../bar", "/bar"},
{"/foo/./bar", "/foo/bar"},
{"/foo/..", "/"},
{"/foo/.", "/foo"},
{"/foo//bar", "/foo/bar"},
{"/foo//bar/baz", "/foo/bar/baz"},
{"/foo//bar/./baz", "/foo/bar/baz"},
{"/./foo", "/foo"},
{"/", "/"},
{"//", "//"},
{"//net", "//net"},
{"/..", "/"},
{"/.", "/"},
{"..", ".."},
{".", "."},
{"../..", "../.."},
{"foo/..", "."},
{"foo/../bar", "bar"},
{"../foo/..", ".."},
{"./foo", "foo"},
};
for (auto test : posix_tests) {
EXPECT_EQ(test.second,
FileSpec(test.first, false, FileSpec::ePathSyntaxPosix)
.GetNormalizedPath()
.GetPath());
}
std::pair<const char *, const char *> windows_tests[] = {
{R"(c:\bar\..\bar)", R"(c:\bar)"},
{R"(c:\bar\.\bar)", R"(c:\bar\bar)"},
{R"(c:\bar\..)", R"(c:\)"},
{R"(c:\bar\.)", R"(c:\bar)"},
{R"(c:\.\bar)", R"(c:\bar)"},
{R"(\)", R"(\)"},
// {R"(\\)", R"(\\)"},
// {R"(\\net)", R"(\\net)"},
{R"(c:\..)", R"(c:\)"},
{R"(c:\.)", R"(c:\)"},
{R"(\..)", R"(\)"},
// {R"(c:..)", R"(c:..)"},
{R"(..)", R"(..)"},
{R"(.)", R"(.)"},
{R"(c:..\..)", R"(c:..\..)"},
{R"(..\..)", R"(..\..)"},
{R"(foo\..)", R"(.)"},
{R"(foo\..\bar)", R"(bar)"},
{R"(..\foo\..)", R"(..)"},
{R"(.\foo)", R"(foo)"},
};
for (auto test : windows_tests) {
EXPECT_EQ(test.second,
FileSpec(test.first, false, FileSpec::ePathSyntaxWindows)
.GetNormalizedPath()
.GetPath())
<< "Original path: " << test.first;
}
}
TEST(FileSpecTest, FormatFileSpec) {
auto win = FileSpec::ePathSyntaxWindows;
FileSpec F;
EXPECT_EQ("(empty)", llvm::formatv("{0}", F).str());
EXPECT_EQ("(empty)", llvm::formatv("{0:D}", F).str());
EXPECT_EQ("(empty)", llvm::formatv("{0:F}", F).str());
F = FileSpec("C:\\foo\\bar.txt", false, win);
EXPECT_EQ("C:\\foo\\bar.txt", llvm::formatv("{0}", F).str());
EXPECT_EQ("C:\\foo\\", llvm::formatv("{0:D}", F).str());
EXPECT_EQ("bar.txt", llvm::formatv("{0:F}", F).str());
F = FileSpec("foo\\bar.txt", false, win);
EXPECT_EQ("foo\\bar.txt", llvm::formatv("{0}", F).str());
EXPECT_EQ("foo\\", llvm::formatv("{0:D}", F).str());
EXPECT_EQ("bar.txt", llvm::formatv("{0:F}", F).str());
F = FileSpec("foo", false, win);
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());
}

View File

@@ -0,0 +1,32 @@
//===-- FileSystemTest.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/Host/FileSystem.h"
extern const char *TestMainArgv0;
using namespace lldb_private;
TEST(FileSystemTest, FileAndDirectoryComponents) {
using namespace std::chrono;
const bool resolve = true;
#ifdef _WIN32
FileSpec fs1("C:\\FILE\\THAT\\DOES\\NOT\\EXIST.TXT", !resolve);
#else
FileSpec fs1("/file/that/does/not/exist.txt", !resolve);
#endif
FileSpec fs2(TestMainArgv0, resolve);
EXPECT_EQ(system_clock::time_point(), FileSystem::GetModificationTime(fs1));
EXPECT_LT(system_clock::time_point() + hours(24 * 365 * 20),
FileSystem::GetModificationTime(fs2));
}

View File

@@ -0,0 +1,45 @@
//===-- HostInfoTest.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/HostInfo.h"
#include "lldb/lldb-defines.h"
#include "gtest/gtest.h"
using namespace lldb_private;
using namespace llvm;
namespace {
class HostInfoTest: public ::testing::Test {
public:
void SetUp() override { HostInfo::Initialize(); }
void TearDown() override { HostInfo::Terminate(); }
};
}
TEST_F(HostInfoTest, GetAugmentedArchSpec) {
// Fully specified triple should not be changed.
ArchSpec spec = HostInfo::GetAugmentedArchSpec("x86_64-pc-linux-gnu");
EXPECT_EQ(spec.GetTriple().getTriple(), "x86_64-pc-linux-gnu");
// Same goes if we specify at least one of (os, vendor, env).
spec = HostInfo::GetAugmentedArchSpec("x86_64-pc");
EXPECT_EQ(spec.GetTriple().getTriple(), "x86_64-pc");
// But if we specify only an arch, we should fill in the rest from the host.
spec = HostInfo::GetAugmentedArchSpec("x86_64");
Triple triple(sys::getDefaultTargetTriple());
EXPECT_EQ(spec.GetTriple().getArch(), Triple::x86_64);
EXPECT_EQ(spec.GetTriple().getOS(), triple.getOS());
EXPECT_EQ(spec.GetTriple().getVendor(), triple.getVendor());
EXPECT_EQ(spec.GetTriple().getEnvironment(), triple.getEnvironment());
// Test LLDB_ARCH_DEFAULT
EXPECT_EQ(HostInfo::GetAugmentedArchSpec(LLDB_ARCH_DEFAULT).GetTriple(),
HostInfo::GetArchitecture(HostInfo::eArchKindDefault).GetTriple());
}

View File

@@ -0,0 +1,22 @@
//===-- 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 "gtest/gtest.h"
using namespace lldb_private;
using namespace llvm;
TEST(Host, WaitStatusFormat) {
EXPECT_EQ("W01", formatv("{0:g}", WaitStatus{WaitStatus::Exit, 1}).str());
EXPECT_EQ("X02", formatv("{0:g}", WaitStatus{WaitStatus::Signal, 2}).str());
EXPECT_EQ("S03", formatv("{0:g}", WaitStatus{WaitStatus::Stop, 3}).str());
EXPECT_EQ("Exited with status 4",
formatv("{0}", WaitStatus{WaitStatus::Exit, 4}).str());
}

View File

@@ -0,0 +1,140 @@
//===-- MainLoopTest.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/MainLoop.h"
#include "lldb/Host/ConnectionFileDescriptor.h"
#include "lldb/Host/PseudoTerminal.h"
#include "lldb/Host/common/TCPSocket.h"
#include "gtest/gtest.h"
#include <future>
using namespace lldb_private;
namespace {
class MainLoopTest : public testing::Test {
public:
static void SetUpTestCase() {
#ifdef _MSC_VER
WSADATA data;
ASSERT_EQ(0, WSAStartup(MAKEWORD(2, 2), &data));
#endif
}
static void TearDownTestCase() {
#ifdef _MSC_VER
ASSERT_EQ(0, WSACleanup());
#endif
}
void SetUp() override {
bool child_processes_inherit = false;
Status error;
std::unique_ptr<TCPSocket> listen_socket_up(
new TCPSocket(true, child_processes_inherit));
ASSERT_TRUE(error.Success());
error = listen_socket_up->Listen("localhost:0", 5);
ASSERT_TRUE(error.Success());
Socket *accept_socket;
std::future<Status> accept_error = std::async(std::launch::async, [&] {
return listen_socket_up->Accept(accept_socket);
});
std::unique_ptr<TCPSocket> connect_socket_up(
new TCPSocket(true, child_processes_inherit));
error = connect_socket_up->Connect(
llvm::formatv("localhost:{0}", listen_socket_up->GetLocalPortNumber())
.str());
ASSERT_TRUE(error.Success());
ASSERT_TRUE(accept_error.get().Success());
callback_count = 0;
socketpair[0] = std::move(connect_socket_up);
socketpair[1].reset(accept_socket);
}
void TearDown() override {
socketpair[0].reset();
socketpair[1].reset();
}
protected:
MainLoop::Callback make_callback() {
return [&](MainLoopBase &loop) {
++callback_count;
loop.RequestTermination();
};
}
std::shared_ptr<Socket> socketpair[2];
unsigned callback_count;
};
} // namespace
TEST_F(MainLoopTest, ReadObject) {
char X = 'X';
size_t len = sizeof(X);
ASSERT_TRUE(socketpair[0]->Write(&X, len).Success());
MainLoop loop;
Status error;
auto handle = loop.RegisterReadObject(socketpair[1], make_callback(), error);
ASSERT_TRUE(error.Success());
ASSERT_TRUE(handle);
ASSERT_TRUE(loop.Run().Success());
ASSERT_EQ(1u, callback_count);
}
TEST_F(MainLoopTest, TerminatesImmediately) {
char X = 'X';
size_t len = sizeof(X);
ASSERT_TRUE(socketpair[0]->Write(&X, len).Success());
ASSERT_TRUE(socketpair[1]->Write(&X, len).Success());
MainLoop loop;
Status error;
auto handle0 = loop.RegisterReadObject(socketpair[0], make_callback(), error);
ASSERT_TRUE(error.Success());
auto handle1 = loop.RegisterReadObject(socketpair[1], make_callback(), error);
ASSERT_TRUE(error.Success());
ASSERT_TRUE(loop.Run().Success());
ASSERT_EQ(1u, callback_count);
}
#ifdef LLVM_ON_UNIX
TEST_F(MainLoopTest, DetectsEOF) {
PseudoTerminal term;
ASSERT_TRUE(term.OpenFirstAvailableMaster(O_RDWR, nullptr, 0));
ASSERT_TRUE(term.OpenSlave(O_RDWR | O_NOCTTY, nullptr, 0));
auto conn = llvm::make_unique<ConnectionFileDescriptor>(
term.ReleaseMasterFileDescriptor(), true);
Status error;
MainLoop loop;
auto handle =
loop.RegisterReadObject(conn->GetReadObject(), make_callback(), error);
ASSERT_TRUE(error.Success());
term.CloseSlaveFileDescriptor();
ASSERT_TRUE(loop.Run().Success());
ASSERT_EQ(1u, callback_count);
}
TEST_F(MainLoopTest, Signal) {
MainLoop loop;
Status error;
auto handle = loop.RegisterSignal(SIGUSR1, make_callback(), error);
ASSERT_TRUE(error.Success());
kill(getpid(), SIGUSR1);
ASSERT_TRUE(loop.Run().Success());
ASSERT_EQ(1u, callback_count);
}
#endif

View File

@@ -0,0 +1,91 @@
//===-- SocketAddressTest.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/Host/SocketAddress.h"
namespace {
class SocketAddressTest : public testing::Test {
public:
static void SetUpTestCase() {
#ifdef _MSC_VER
WSADATA data;
ASSERT_EQ(0, WSAStartup(MAKEWORD(2, 2), &data));
#endif
}
static void TearDownTestCase() {
#ifdef _MSC_VER
ASSERT_EQ(0, WSACleanup());
#endif
}
};
} // namespace
using namespace lldb_private;
TEST_F(SocketAddressTest, Set) {
SocketAddress sa;
ASSERT_TRUE(sa.SetToLocalhost(AF_INET, 1138));
ASSERT_STREQ("127.0.0.1", sa.GetIPAddress().c_str());
ASSERT_EQ(1138, sa.GetPort());
ASSERT_TRUE(sa.SetToAnyAddress(AF_INET, 0));
ASSERT_STREQ("0.0.0.0", sa.GetIPAddress().c_str());
ASSERT_EQ(0, sa.GetPort());
ASSERT_TRUE(sa.SetToLocalhost(AF_INET6, 1139));
ASSERT_TRUE(sa.GetIPAddress() == "::1" ||
sa.GetIPAddress() == "0:0:0:0:0:0:0:1")
<< "Address was: " << sa.GetIPAddress();
ASSERT_EQ(1139, sa.GetPort());
}
TEST_F(SocketAddressTest, GetAddressInfo) {
auto addr = SocketAddress::GetAddressInfo("127.0.0.1", nullptr, AF_UNSPEC,
SOCK_STREAM, IPPROTO_TCP);
ASSERT_EQ(1u, addr.size());
EXPECT_EQ(AF_INET, addr[0].GetFamily());
EXPECT_EQ("127.0.0.1", addr[0].GetIPAddress());
}
#ifdef _WIN32
// we need to test our inet_ntop implementation for Windows XP
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
TEST_F(SocketAddressTest, inet_ntop) {
const uint8_t address4[4] = {255, 0, 1, 100};
const uint8_t address6[16] = {0, 1, 2, 3, 4, 5, 6, 7,
8, 9, 10, 11, 12, 13, 255, 0};
char buffer[INET6_ADDRSTRLEN];
memset(buffer, 'x', sizeof(buffer));
EXPECT_STREQ("1:203:405:607:809:a0b:c0d:ff00",
inet_ntop(AF_INET6, address6, buffer, sizeof(buffer)));
memset(buffer, 'x', sizeof(buffer));
EXPECT_STREQ("1:203:405:607:809:a0b:c0d:ff00",
inet_ntop(AF_INET6, address6, buffer, 31));
memset(buffer, 'x', sizeof(buffer));
EXPECT_STREQ(nullptr, inet_ntop(AF_INET6, address6, buffer, 0));
memset(buffer, 'x', sizeof(buffer));
EXPECT_STREQ(nullptr, inet_ntop(AF_INET6, address6, buffer, 30));
memset(buffer, 'x', sizeof(buffer));
EXPECT_STREQ("255.0.1.100",
inet_ntop(AF_INET, address4, buffer, sizeof(buffer)));
memset(buffer, 'x', sizeof(buffer));
EXPECT_STREQ("255.0.1.100", inet_ntop(AF_INET, address4, buffer, 12));
memset(buffer, 'x', sizeof(buffer));
EXPECT_STREQ(nullptr, inet_ntop(AF_INET, address4, buffer, 0));
memset(buffer, 'x', sizeof(buffer));
EXPECT_STREQ(nullptr, inet_ntop(AF_INET, address4, buffer, 11));
}
#endif

View File

@@ -0,0 +1,233 @@
//===-- SocketTest.cpp ------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <cstdio>
#include <functional>
#include <thread>
#include "gtest/gtest.h"
#include "lldb/Host/Config.h"
#include "lldb/Host/Socket.h"
#include "lldb/Host/common/TCPSocket.h"
#include "lldb/Host/common/UDPSocket.h"
#ifndef LLDB_DISABLE_POSIX
#include "lldb/Host/posix/DomainSocket.h"
#endif
using namespace lldb_private;
class SocketTest : public testing::Test {
public:
void SetUp() override {
#if defined(_MSC_VER)
WSADATA data;
::WSAStartup(MAKEWORD(2, 2), &data);
#endif
}
void TearDown() override {
#if defined(_MSC_VER)
::WSACleanup();
#endif
}
protected:
static void AcceptThread(Socket *listen_socket,
const char *listen_remote_address,
bool child_processes_inherit, Socket **accept_socket,
Status *error) {
*error = listen_socket->Accept(*accept_socket);
}
template <typename SocketType>
void CreateConnectedSockets(
const char *listen_remote_address,
const std::function<std::string(const SocketType &)> &get_connect_addr,
std::unique_ptr<SocketType> *a_up, std::unique_ptr<SocketType> *b_up) {
bool child_processes_inherit = false;
Status error;
std::unique_ptr<SocketType> listen_socket_up(
new SocketType(true, child_processes_inherit));
EXPECT_FALSE(error.Fail());
error = listen_socket_up->Listen(listen_remote_address, 5);
EXPECT_FALSE(error.Fail());
EXPECT_TRUE(listen_socket_up->IsValid());
Status accept_error;
Socket *accept_socket;
std::thread accept_thread(AcceptThread, listen_socket_up.get(),
listen_remote_address, child_processes_inherit,
&accept_socket, &accept_error);
std::string connect_remote_address = get_connect_addr(*listen_socket_up);
std::unique_ptr<SocketType> connect_socket_up(
new SocketType(true, child_processes_inherit));
EXPECT_FALSE(error.Fail());
error = connect_socket_up->Connect(connect_remote_address);
EXPECT_FALSE(error.Fail());
EXPECT_TRUE(connect_socket_up->IsValid());
a_up->swap(connect_socket_up);
EXPECT_TRUE(error.Success());
EXPECT_NE(nullptr, a_up->get());
EXPECT_TRUE((*a_up)->IsValid());
accept_thread.join();
b_up->reset(static_cast<SocketType *>(accept_socket));
EXPECT_TRUE(accept_error.Success());
EXPECT_NE(nullptr, b_up->get());
EXPECT_TRUE((*b_up)->IsValid());
listen_socket_up.reset();
}
};
TEST_F(SocketTest, DecodeHostAndPort) {
std::string host_str;
std::string port_str;
int32_t port;
Status error;
EXPECT_TRUE(Socket::DecodeHostAndPort("localhost:1138", host_str, port_str,
port, &error));
EXPECT_STREQ("localhost", host_str.c_str());
EXPECT_STREQ("1138", port_str.c_str());
EXPECT_EQ(1138, port);
EXPECT_TRUE(error.Success());
EXPECT_FALSE(Socket::DecodeHostAndPort("google.com:65536", host_str, port_str,
port, &error));
EXPECT_TRUE(error.Fail());
EXPECT_STREQ("invalid host:port specification: 'google.com:65536'",
error.AsCString());
EXPECT_FALSE(Socket::DecodeHostAndPort("google.com:-1138", host_str, port_str,
port, &error));
EXPECT_TRUE(error.Fail());
EXPECT_STREQ("invalid host:port specification: 'google.com:-1138'",
error.AsCString());
EXPECT_FALSE(Socket::DecodeHostAndPort("google.com:65536", host_str, port_str,
port, &error));
EXPECT_TRUE(error.Fail());
EXPECT_STREQ("invalid host:port specification: 'google.com:65536'",
error.AsCString());
EXPECT_TRUE(
Socket::DecodeHostAndPort("12345", host_str, port_str, port, &error));
EXPECT_STREQ("", host_str.c_str());
EXPECT_STREQ("12345", port_str.c_str());
EXPECT_EQ(12345, port);
EXPECT_TRUE(error.Success());
EXPECT_TRUE(
Socket::DecodeHostAndPort("*:0", host_str, port_str, port, &error));
EXPECT_STREQ("*", host_str.c_str());
EXPECT_STREQ("0", port_str.c_str());
EXPECT_EQ(0, port);
EXPECT_TRUE(error.Success());
EXPECT_TRUE(
Socket::DecodeHostAndPort("*:65535", host_str, port_str, port, &error));
EXPECT_STREQ("*", host_str.c_str());
EXPECT_STREQ("65535", port_str.c_str());
EXPECT_EQ(65535, port);
EXPECT_TRUE(error.Success());
EXPECT_TRUE(
Socket::DecodeHostAndPort("[::1]:12345", host_str, port_str, port, &error));
EXPECT_STREQ("::1", host_str.c_str());
EXPECT_STREQ("12345", port_str.c_str());
EXPECT_EQ(12345, port);
EXPECT_TRUE(error.Success());
EXPECT_TRUE(
Socket::DecodeHostAndPort("[abcd:12fg:AF58::1]:12345", host_str, port_str, port, &error));
EXPECT_STREQ("abcd:12fg:AF58::1", host_str.c_str());
EXPECT_STREQ("12345", port_str.c_str());
EXPECT_EQ(12345, port);
EXPECT_TRUE(error.Success());
}
#ifndef LLDB_DISABLE_POSIX
TEST_F(SocketTest, DomainListenConnectAccept) {
char *file_name_str = tempnam(nullptr, nullptr);
EXPECT_NE(nullptr, file_name_str);
const std::string file_name(file_name_str);
free(file_name_str);
std::unique_ptr<DomainSocket> socket_a_up;
std::unique_ptr<DomainSocket> socket_b_up;
CreateConnectedSockets<DomainSocket>(
file_name.c_str(), [=](const DomainSocket &) { return file_name; },
&socket_a_up, &socket_b_up);
}
#endif
TEST_F(SocketTest, TCPListen0ConnectAccept) {
std::unique_ptr<TCPSocket> socket_a_up;
std::unique_ptr<TCPSocket> socket_b_up;
CreateConnectedSockets<TCPSocket>(
"127.0.0.1:0",
[=](const TCPSocket &s) {
char connect_remote_address[64];
snprintf(connect_remote_address, sizeof(connect_remote_address),
"localhost:%u", s.GetLocalPortNumber());
return std::string(connect_remote_address);
},
&socket_a_up, &socket_b_up);
}
TEST_F(SocketTest, TCPGetAddress) {
std::unique_ptr<TCPSocket> socket_a_up;
std::unique_ptr<TCPSocket> socket_b_up;
CreateConnectedSockets<TCPSocket>(
"127.0.0.1:0",
[=](const TCPSocket &s) {
char connect_remote_address[64];
snprintf(connect_remote_address, sizeof(connect_remote_address),
"localhost:%u", s.GetLocalPortNumber());
return std::string(connect_remote_address);
},
&socket_a_up, &socket_b_up);
EXPECT_EQ(socket_a_up->GetLocalPortNumber(),
socket_b_up->GetRemotePortNumber());
EXPECT_EQ(socket_b_up->GetLocalPortNumber(),
socket_a_up->GetRemotePortNumber());
EXPECT_NE(socket_a_up->GetLocalPortNumber(),
socket_b_up->GetLocalPortNumber());
EXPECT_STREQ("127.0.0.1", socket_a_up->GetRemoteIPAddress().c_str());
EXPECT_STREQ("127.0.0.1", socket_b_up->GetRemoteIPAddress().c_str());
}
TEST_F(SocketTest, UDPConnect) {
Socket *socket;
bool child_processes_inherit = false;
auto error = UDPSocket::Connect("127.0.0.1:0", child_processes_inherit,
socket);
std::unique_ptr<Socket> socket_up(socket);
EXPECT_TRUE(error.Success());
EXPECT_TRUE(socket_up->IsValid());
}
TEST_F(SocketTest, TCPListen0GetPort) {
Socket *server_socket;
Predicate<uint16_t> port_predicate;
port_predicate.SetValue(0, eBroadcastNever);
Status err =
Socket::TcpListen("10.10.12.3:0", false, server_socket, &port_predicate);
std::unique_ptr<TCPSocket> socket_up((TCPSocket*)server_socket);
EXPECT_TRUE(socket_up->IsValid());
EXPECT_NE(socket_up->GetLocalPortNumber(), 0);
}

View File

@@ -0,0 +1,32 @@
//===-- SymbolsTest.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/Host/Symbols.h"
#include "lldb/Core/ModuleSpec.h"
using namespace lldb_private;
TEST(SymbolsTest,
LocateExecutableSymbolFileForUnknownExecutableAndUnknownSymbolFile) {
ModuleSpec module_spec;
FileSpec symbol_file_spec = Symbols::LocateExecutableSymbolFile(module_spec);
EXPECT_TRUE(symbol_file_spec.GetFilename().IsEmpty());
}
TEST(SymbolsTest,
LocateExecutableSymbolFileForUnknownExecutableAndMissingSymbolFile) {
ModuleSpec module_spec;
// using a GUID here because the symbol file shouldn't actually exist on disk
module_spec.GetSymbolFileSpec().SetFile(
"4A524676-B24B-4F4E-968A-551D465EBAF1.so", false);
FileSpec symbol_file_spec = Symbols::LocateExecutableSymbolFile(module_spec);
EXPECT_TRUE(symbol_file_spec.GetFilename().IsEmpty());
}

View File

@@ -0,0 +1,45 @@
#include "gtest/gtest.h"
#include "lldb/Host/TaskPool.h"
using namespace lldb_private;
TEST(TaskPoolTest, AddTask) {
auto fn = [](int x) { return x * x + 1; };
auto f1 = TaskPool::AddTask(fn, 1);
auto f2 = TaskPool::AddTask(fn, 2);
auto f3 = TaskPool::AddTask(fn, 3);
auto f4 = TaskPool::AddTask(fn, 4);
ASSERT_EQ(10, f3.get());
ASSERT_EQ(2, f1.get());
ASSERT_EQ(17, f4.get());
ASSERT_EQ(5, f2.get());
}
TEST(TaskPoolTest, RunTasks) {
std::vector<int> r(4);
auto fn = [](int x, int &y) { y = x * x + 1; };
TaskPool::RunTasks([fn, &r]() { fn(1, r[0]); }, [fn, &r]() { fn(2, r[1]); },
[fn, &r]() { fn(3, r[2]); }, [fn, &r]() { fn(4, r[3]); });
ASSERT_EQ(2, r[0]);
ASSERT_EQ(5, r[1]);
ASSERT_EQ(10, r[2]);
ASSERT_EQ(17, r[3]);
}
TEST(TaskPoolTest, TaskMap) {
int data[4];
auto fn = [&data](int x) { data[x] = x * x; };
TaskMapOverInt(0, 4, fn);
ASSERT_EQ(data[0], 0);
ASSERT_EQ(data[1], 1);
ASSERT_EQ(data[2], 4);
ASSERT_EQ(data[3], 9);
}

View File

@@ -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());
}

View File

@@ -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);
}