summaryrefslogtreecommitdiff
path: root/unittests/Host
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2019-01-19 10:06:29 +0000
committerDimitry Andric <dim@FreeBSD.org>2019-01-19 10:06:29 +0000
commit94994d372d014ce4c8758b9605d63fae651bd8aa (patch)
tree51c0b708bd59f205d6b35cb2a8c24d62f0c33d77 /unittests/Host
parent39be7ce23363d12ae3e49aeb1fdb2bfeb892e836 (diff)
Notes
Diffstat (limited to 'unittests/Host')
-rw-r--r--unittests/Host/CMakeLists.txt3
-rw-r--r--unittests/Host/FileSystemTest.cpp271
-rw-r--r--unittests/Host/HostInfoTest.cpp21
-rw-r--r--unittests/Host/NativeProcessProtocolTest.cpp225
-rw-r--r--unittests/Host/PredicateTest.cpp34
-rw-r--r--unittests/Host/SocketTest.cpp19
-rw-r--r--unittests/Host/SymbolsTest.cpp30
-rw-r--r--unittests/Host/linux/HostTest.cpp11
8 files changed, 548 insertions, 66 deletions
diff --git a/unittests/Host/CMakeLists.txt b/unittests/Host/CMakeLists.txt
index f1768537ed86..93394661d36d 100644
--- a/unittests/Host/CMakeLists.txt
+++ b/unittests/Host/CMakeLists.txt
@@ -3,7 +3,7 @@ set (FILES
HostInfoTest.cpp
HostTest.cpp
MainLoopTest.cpp
- PredicateTest.cpp
+ NativeProcessProtocolTest.cpp
SocketAddressTest.cpp
SocketTest.cpp
SymbolsTest.cpp
@@ -23,4 +23,5 @@ add_lldb_unittest(HostTests
lldbCore
lldbHost
lldbUtilityHelpers
+ LLVMTestingSupport
)
diff --git a/unittests/Host/FileSystemTest.cpp b/unittests/Host/FileSystemTest.cpp
index d5160b1a0da1..254694037488 100644
--- a/unittests/Host/FileSystemTest.cpp
+++ b/unittests/Host/FileSystemTest.cpp
@@ -7,26 +7,285 @@
//
//===----------------------------------------------------------------------===//
+#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "lldb/Host/FileSystem.h"
+#include "llvm/Support/Errc.h"
extern const char *TestMainArgv0;
using namespace lldb_private;
+using namespace llvm;
+using llvm::sys::fs::UniqueID;
+
+// Modified from llvm/unittests/Support/VirtualFileSystemTest.cpp
+namespace {
+struct DummyFile : public vfs::File {
+ vfs::Status S;
+ explicit DummyFile(vfs::Status S) : S(S) {}
+ llvm::ErrorOr<vfs::Status> status() override { return S; }
+ llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
+ getBuffer(const Twine &Name, int64_t FileSize, bool RequiresNullTerminator,
+ bool IsVolatile) override {
+ llvm_unreachable("unimplemented");
+ }
+ std::error_code close() override { return std::error_code(); }
+};
+
+class DummyFileSystem : public vfs::FileSystem {
+ int FSID; // used to produce UniqueIDs
+ int FileID; // used to produce UniqueIDs
+ std::string cwd;
+ std::map<std::string, vfs::Status> FilesAndDirs;
+
+ static int getNextFSID() {
+ static int Count = 0;
+ return Count++;
+ }
+
+public:
+ DummyFileSystem() : FSID(getNextFSID()), FileID(0) {}
+
+ ErrorOr<vfs::Status> status(const Twine &Path) override {
+ std::map<std::string, vfs::Status>::iterator I =
+ FilesAndDirs.find(Path.str());
+ if (I == FilesAndDirs.end())
+ return make_error_code(llvm::errc::no_such_file_or_directory);
+ return I->second;
+ }
+ ErrorOr<std::unique_ptr<vfs::File>>
+ openFileForRead(const Twine &Path) override {
+ auto S = status(Path);
+ if (S)
+ return std::unique_ptr<vfs::File>(new DummyFile{*S});
+ return S.getError();
+ }
+ llvm::ErrorOr<std::string> getCurrentWorkingDirectory() const override {
+ return cwd;
+ }
+ std::error_code setCurrentWorkingDirectory(const Twine &Path) override {
+ cwd = Path.str();
+ return std::error_code();
+ }
+ // Map any symlink to "/symlink".
+ std::error_code getRealPath(const Twine &Path,
+ SmallVectorImpl<char> &Output) const override {
+ auto I = FilesAndDirs.find(Path.str());
+ if (I == FilesAndDirs.end())
+ return make_error_code(llvm::errc::no_such_file_or_directory);
+ if (I->second.isSymlink()) {
+ Output.clear();
+ Twine("/symlink").toVector(Output);
+ return std::error_code();
+ }
+ Output.clear();
+ Path.toVector(Output);
+ return std::error_code();
+ }
+
+ struct DirIterImpl : public llvm::vfs::detail::DirIterImpl {
+ std::map<std::string, vfs::Status> &FilesAndDirs;
+ std::map<std::string, vfs::Status>::iterator I;
+ std::string Path;
+ bool isInPath(StringRef S) {
+ if (Path.size() < S.size() && S.find(Path) == 0) {
+ auto LastSep = S.find_last_of('/');
+ if (LastSep == Path.size() || LastSep == Path.size() - 1)
+ return true;
+ }
+ return false;
+ }
+ DirIterImpl(std::map<std::string, vfs::Status> &FilesAndDirs,
+ const Twine &_Path)
+ : FilesAndDirs(FilesAndDirs), I(FilesAndDirs.begin()),
+ Path(_Path.str()) {
+ for (; I != FilesAndDirs.end(); ++I) {
+ if (isInPath(I->first)) {
+ CurrentEntry =
+ vfs::directory_entry(I->second.getName(), I->second.getType());
+ break;
+ }
+ }
+ }
+ std::error_code increment() override {
+ ++I;
+ for (; I != FilesAndDirs.end(); ++I) {
+ if (isInPath(I->first)) {
+ CurrentEntry =
+ vfs::directory_entry(I->second.getName(), I->second.getType());
+ break;
+ }
+ }
+ if (I == FilesAndDirs.end())
+ CurrentEntry = vfs::directory_entry();
+ return std::error_code();
+ }
+ };
+
+ vfs::directory_iterator dir_begin(const Twine &Dir,
+ std::error_code &EC) override {
+ return vfs::directory_iterator(
+ std::make_shared<DirIterImpl>(FilesAndDirs, Dir));
+ }
+
+ void addEntry(StringRef Path, const vfs::Status &Status) {
+ FilesAndDirs[Path] = Status;
+ }
+
+ void addRegularFile(StringRef Path, sys::fs::perms Perms = sys::fs::all_all) {
+ vfs::Status S(Path, UniqueID(FSID, FileID++),
+ std::chrono::system_clock::now(), 0, 0, 1024,
+ sys::fs::file_type::regular_file, Perms);
+ addEntry(Path, S);
+ }
+
+ void addDirectory(StringRef Path, sys::fs::perms Perms = sys::fs::all_all) {
+ vfs::Status S(Path, UniqueID(FSID, FileID++),
+ std::chrono::system_clock::now(), 0, 0, 0,
+ sys::fs::file_type::directory_file, Perms);
+ addEntry(Path, S);
+ }
+
+ void addSymlink(StringRef Path) {
+ vfs::Status S(Path, UniqueID(FSID, FileID++),
+ std::chrono::system_clock::now(), 0, 0, 0,
+ sys::fs::file_type::symlink_file, sys::fs::all_all);
+ addEntry(Path, S);
+ }
+};
+} // namespace
TEST(FileSystemTest, FileAndDirectoryComponents) {
using namespace std::chrono;
+ FileSystem fs;
- const bool resolve = true;
#ifdef _WIN32
- FileSpec fs1("C:\\FILE\\THAT\\DOES\\NOT\\EXIST.TXT", !resolve);
+ FileSpec fs1("C:\\FILE\\THAT\\DOES\\NOT\\EXIST.TXT");
#else
- FileSpec fs1("/file/that/does/not/exist.txt", !resolve);
+ FileSpec fs1("/file/that/does/not/exist.txt");
#endif
- FileSpec fs2(TestMainArgv0, resolve);
+ FileSpec fs2(TestMainArgv0);
+
+ fs.Resolve(fs2);
- EXPECT_EQ(system_clock::time_point(), FileSystem::GetModificationTime(fs1));
+ EXPECT_EQ(system_clock::time_point(), fs.GetModificationTime(fs1));
EXPECT_LT(system_clock::time_point() + hours(24 * 365 * 20),
- FileSystem::GetModificationTime(fs2));
+ fs.GetModificationTime(fs2));
+}
+
+static IntrusiveRefCntPtr<DummyFileSystem> GetSimpleDummyFS() {
+ IntrusiveRefCntPtr<DummyFileSystem> D(new DummyFileSystem());
+ D->addRegularFile("/foo");
+ D->addDirectory("/bar");
+ D->addSymlink("/baz");
+ D->addRegularFile("/qux", ~sys::fs::perms::all_read);
+ D->setCurrentWorkingDirectory("/");
+ return D;
+}
+
+TEST(FileSystemTest, Exists) {
+ FileSystem fs(GetSimpleDummyFS());
+
+ EXPECT_TRUE(fs.Exists("/foo"));
+ EXPECT_TRUE(fs.Exists(FileSpec("/foo", FileSpec::Style::posix)));
+}
+
+TEST(FileSystemTest, Readable) {
+ FileSystem fs(GetSimpleDummyFS());
+
+ EXPECT_TRUE(fs.Readable("/foo"));
+ EXPECT_TRUE(fs.Readable(FileSpec("/foo", FileSpec::Style::posix)));
+
+ EXPECT_FALSE(fs.Readable("/qux"));
+ EXPECT_FALSE(fs.Readable(FileSpec("/qux", FileSpec::Style::posix)));
+}
+
+TEST(FileSystemTest, GetByteSize) {
+ FileSystem fs(GetSimpleDummyFS());
+
+ EXPECT_EQ((uint64_t)1024, fs.GetByteSize("/foo"));
+ EXPECT_EQ((uint64_t)1024,
+ fs.GetByteSize(FileSpec("/foo", FileSpec::Style::posix)));
+}
+
+TEST(FileSystemTest, GetPermissions) {
+ FileSystem fs(GetSimpleDummyFS());
+
+ EXPECT_EQ(sys::fs::all_all, fs.GetPermissions("/foo"));
+ EXPECT_EQ(sys::fs::all_all,
+ fs.GetPermissions(FileSpec("/foo", FileSpec::Style::posix)));
+}
+
+TEST(FileSystemTest, MakeAbsolute) {
+ FileSystem fs(GetSimpleDummyFS());
+
+ {
+ StringRef foo_relative = "foo";
+ SmallString<16> foo(foo_relative);
+ auto EC = fs.MakeAbsolute(foo);
+ EXPECT_FALSE(EC);
+ EXPECT_TRUE(foo.equals("/foo"));
+ }
+
+ {
+ FileSpec file_spec("foo");
+ auto EC = fs.MakeAbsolute(file_spec);
+ EXPECT_FALSE(EC);
+ EXPECT_EQ(FileSpec("/foo"), file_spec);
+ }
+}
+
+TEST(FileSystemTest, Resolve) {
+ FileSystem fs(GetSimpleDummyFS());
+
+ {
+ StringRef foo_relative = "foo";
+ SmallString<16> foo(foo_relative);
+ fs.Resolve(foo);
+ EXPECT_TRUE(foo.equals("/foo"));
+ }
+
+ {
+ FileSpec file_spec("foo");
+ fs.Resolve(file_spec);
+ EXPECT_EQ(FileSpec("/foo"), file_spec);
+ }
+
+ {
+ StringRef foo_relative = "bogus";
+ SmallString<16> foo(foo_relative);
+ fs.Resolve(foo);
+ EXPECT_TRUE(foo.equals("bogus"));
+ }
+
+ {
+ FileSpec file_spec("bogus");
+ fs.Resolve(file_spec);
+ EXPECT_EQ(FileSpec("bogus"), file_spec);
+ }
+}
+
+FileSystem::EnumerateDirectoryResult
+VFSCallback(void *baton, llvm::sys::fs::file_type file_type,
+ llvm::StringRef path) {
+ auto visited = static_cast<std::vector<std::string> *>(baton);
+ visited->push_back(path.str());
+ return FileSystem::eEnumerateDirectoryResultNext;
+}
+
+TEST(FileSystemTest, EnumerateDirectory) {
+ FileSystem fs(GetSimpleDummyFS());
+
+ std::vector<std::string> visited;
+
+ constexpr bool find_directories = true;
+ constexpr bool find_files = true;
+ constexpr bool find_other = true;
+
+ fs.EnumerateDirectory("/", find_directories, find_files, find_other,
+ VFSCallback, &visited);
+
+ EXPECT_THAT(visited,
+ testing::UnorderedElementsAre("/foo", "/bar", "/baz", "/qux"));
}
diff --git a/unittests/Host/HostInfoTest.cpp b/unittests/Host/HostInfoTest.cpp
index 3870673d0f47..d2d1fdc256a9 100644
--- a/unittests/Host/HostInfoTest.cpp
+++ b/unittests/Host/HostInfoTest.cpp
@@ -8,20 +8,27 @@
//===----------------------------------------------------------------------===//
#include "lldb/Host/HostInfo.h"
-#include "lldb/lldb-defines.h"
#include "TestingSupport/TestUtilities.h"
+#include "lldb/Host/FileSystem.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(); }
+class HostInfoTest : public ::testing::Test {
+public:
+ void SetUp() override {
+ FileSystem::Initialize();
+ HostInfo::Initialize();
+ }
+ void TearDown() override {
+ HostInfo::Terminate();
+ FileSystem::Terminate();
+ }
};
-}
+} // namespace
TEST_F(HostInfoTest, GetAugmentedArchSpec) {
// Fully specified triple should not be changed.
@@ -43,4 +50,4 @@ TEST_F(HostInfoTest, GetAugmentedArchSpec) {
// Test LLDB_ARCH_DEFAULT
EXPECT_EQ(HostInfo::GetAugmentedArchSpec(LLDB_ARCH_DEFAULT).GetTriple(),
HostInfo::GetArchitecture(HostInfo::eArchKindDefault).GetTriple());
-} \ No newline at end of file
+}
diff --git a/unittests/Host/NativeProcessProtocolTest.cpp b/unittests/Host/NativeProcessProtocolTest.cpp
new file mode 100644
index 000000000000..8a9271af771e
--- /dev/null
+++ b/unittests/Host/NativeProcessProtocolTest.cpp
@@ -0,0 +1,225 @@
+//===-- NativeProcessProtocolTest.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/common/NativeProcessProtocol.h"
+#include "llvm/Testing/Support/Error.h"
+#include "gmock/gmock.h"
+
+using namespace lldb_private;
+using namespace lldb;
+using namespace testing;
+
+namespace {
+class MockDelegate : public NativeProcessProtocol::NativeDelegate {
+public:
+ MOCK_METHOD1(InitializeDelegate, void(NativeProcessProtocol *Process));
+ MOCK_METHOD2(ProcessStateChanged,
+ void(NativeProcessProtocol *Process, StateType State));
+ MOCK_METHOD1(DidExec, void(NativeProcessProtocol *Process));
+};
+
+// NB: This class doesn't use the override keyword to avoid
+// -Winconsistent-missing-override warnings from the compiler. The
+// inconsistency comes from the overriding definitions in the MOCK_*** macros.
+class MockProcess : public NativeProcessProtocol {
+public:
+ MockProcess(NativeDelegate &Delegate, const ArchSpec &Arch,
+ lldb::pid_t Pid = 1)
+ : NativeProcessProtocol(Pid, -1, Delegate), Arch(Arch) {}
+
+ MOCK_METHOD1(Resume, Status(const ResumeActionList &ResumeActions));
+ MOCK_METHOD0(Halt, Status());
+ MOCK_METHOD0(Detach, Status());
+ MOCK_METHOD1(Signal, Status(int Signo));
+ MOCK_METHOD0(Kill, Status());
+ MOCK_METHOD3(AllocateMemory,
+ Status(size_t Size, uint32_t Permissions, addr_t &Addr));
+ MOCK_METHOD1(DeallocateMemory, Status(addr_t Addr));
+ MOCK_METHOD0(GetSharedLibraryInfoAddress, addr_t());
+ MOCK_METHOD0(UpdateThreads, size_t());
+ MOCK_CONST_METHOD0(GetAuxvData,
+ llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>());
+ MOCK_METHOD2(GetLoadedModuleFileSpec,
+ Status(const char *ModulePath, FileSpec &Spec));
+ MOCK_METHOD2(GetFileLoadAddress,
+ Status(const llvm::StringRef &FileName, addr_t &Addr));
+
+ const ArchSpec &GetArchitecture() const /*override*/ { return Arch; }
+ Status SetBreakpoint(lldb::addr_t Addr, uint32_t Size,
+ bool Hardware) /*override*/ {
+ if (Hardware)
+ return SetHardwareBreakpoint(Addr, Size);
+ else
+ return SetSoftwareBreakpoint(Addr, Size);
+ }
+
+ // Redirect base class Read/Write Memory methods to functions whose signatures
+ // are more mock-friendly.
+ Status ReadMemory(addr_t Addr, void *Buf, size_t Size,
+ size_t &BytesRead) /*override*/;
+ Status WriteMemory(addr_t Addr, const void *Buf, size_t Size,
+ size_t &BytesWritten) /*override*/;
+
+ MOCK_METHOD2(ReadMemory,
+ llvm::Expected<std::vector<uint8_t>>(addr_t Addr, size_t Size));
+ MOCK_METHOD2(WriteMemory,
+ llvm::Expected<size_t>(addr_t Addr,
+ llvm::ArrayRef<uint8_t> Data));
+
+ using NativeProcessProtocol::GetSoftwareBreakpointTrapOpcode;
+ llvm::Expected<std::vector<uint8_t>> ReadMemoryWithoutTrap(addr_t Addr,
+ size_t Size);
+
+private:
+ ArchSpec Arch;
+};
+
+class FakeMemory {
+public:
+ FakeMemory(llvm::ArrayRef<uint8_t> Data) : Data(Data) {}
+ llvm::Expected<std::vector<uint8_t>> Read(addr_t Addr, size_t Size);
+ llvm::Expected<size_t> Write(addr_t Addr, llvm::ArrayRef<uint8_t> Chunk);
+
+private:
+ std::vector<uint8_t> Data;
+};
+} // namespace
+
+Status MockProcess::ReadMemory(addr_t Addr, void *Buf, size_t Size,
+ size_t &BytesRead) {
+ auto ExpectedMemory = ReadMemory(Addr, Size);
+ if (!ExpectedMemory) {
+ BytesRead = 0;
+ return Status(ExpectedMemory.takeError());
+ }
+ BytesRead = ExpectedMemory->size();
+ assert(BytesRead <= Size);
+ std::memcpy(Buf, ExpectedMemory->data(), BytesRead);
+ return Status();
+}
+
+Status MockProcess::WriteMemory(addr_t Addr, const void *Buf, size_t Size,
+ size_t &BytesWritten) {
+ auto ExpectedBytes = WriteMemory(
+ Addr, llvm::makeArrayRef(static_cast<const uint8_t *>(Buf), Size));
+ if (!ExpectedBytes) {
+ BytesWritten = 0;
+ return Status(ExpectedBytes.takeError());
+ }
+ BytesWritten = *ExpectedBytes;
+ return Status();
+}
+
+llvm::Expected<std::vector<uint8_t>>
+MockProcess::ReadMemoryWithoutTrap(addr_t Addr, size_t Size) {
+ std::vector<uint8_t> Data(Size, 0);
+ size_t BytesRead;
+ Status ST = NativeProcessProtocol::ReadMemoryWithoutTrap(
+ Addr, Data.data(), Data.size(), BytesRead);
+ if (ST.Fail())
+ return ST.ToError();
+ Data.resize(BytesRead);
+ return std::move(Data);
+}
+
+llvm::Expected<std::vector<uint8_t>> FakeMemory::Read(addr_t Addr,
+ size_t Size) {
+ if (Addr >= Data.size())
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "Address out of range.");
+ Size = std::min(Size, Data.size() - (size_t)Addr);
+ auto Begin = std::next(Data.begin(), Addr);
+ return std::vector<uint8_t>(Begin, std::next(Begin, Size));
+}
+
+llvm::Expected<size_t> FakeMemory::Write(addr_t Addr,
+ llvm::ArrayRef<uint8_t> Chunk) {
+ if (Addr >= Data.size())
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "Address out of range.");
+ size_t Size = std::min(Chunk.size(), Data.size() - (size_t)Addr);
+ std::copy_n(Chunk.begin(), Size, &Data[Addr]);
+ return Size;
+}
+
+TEST(NativeProcessProtocolTest, SetBreakpoint) {
+ NiceMock<MockDelegate> DummyDelegate;
+ MockProcess Process(DummyDelegate, ArchSpec("x86_64-pc-linux"));
+ auto Trap = cantFail(Process.GetSoftwareBreakpointTrapOpcode(1));
+ InSequence S;
+ EXPECT_CALL(Process, ReadMemory(0x47, 1))
+ .WillOnce(Return(ByMove(std::vector<uint8_t>{0xbb})));
+ EXPECT_CALL(Process, WriteMemory(0x47, Trap)).WillOnce(Return(ByMove(1)));
+ EXPECT_CALL(Process, ReadMemory(0x47, 1)).WillOnce(Return(ByMove(Trap)));
+ EXPECT_THAT_ERROR(Process.SetBreakpoint(0x47, 0, false).ToError(),
+ llvm::Succeeded());
+}
+
+TEST(NativeProcessProtocolTest, SetBreakpointFailRead) {
+ NiceMock<MockDelegate> DummyDelegate;
+ MockProcess Process(DummyDelegate, ArchSpec("x86_64-pc-linux"));
+ EXPECT_CALL(Process, ReadMemory(0x47, 1))
+ .WillOnce(Return(ByMove(
+ llvm::createStringError(llvm::inconvertibleErrorCode(), "Foo"))));
+ EXPECT_THAT_ERROR(Process.SetBreakpoint(0x47, 0, false).ToError(),
+ llvm::Failed());
+}
+
+TEST(NativeProcessProtocolTest, SetBreakpointFailWrite) {
+ NiceMock<MockDelegate> DummyDelegate;
+ MockProcess Process(DummyDelegate, ArchSpec("x86_64-pc-linux"));
+ auto Trap = cantFail(Process.GetSoftwareBreakpointTrapOpcode(1));
+ InSequence S;
+ EXPECT_CALL(Process, ReadMemory(0x47, 1))
+ .WillOnce(Return(ByMove(std::vector<uint8_t>{0xbb})));
+ EXPECT_CALL(Process, WriteMemory(0x47, Trap))
+ .WillOnce(Return(ByMove(
+ llvm::createStringError(llvm::inconvertibleErrorCode(), "Foo"))));
+ EXPECT_THAT_ERROR(Process.SetBreakpoint(0x47, 0, false).ToError(),
+ llvm::Failed());
+}
+
+TEST(NativeProcessProtocolTest, SetBreakpointFailVerify) {
+ NiceMock<MockDelegate> DummyDelegate;
+ MockProcess Process(DummyDelegate, ArchSpec("x86_64-pc-linux"));
+ auto Trap = cantFail(Process.GetSoftwareBreakpointTrapOpcode(1));
+ InSequence S;
+ EXPECT_CALL(Process, ReadMemory(0x47, 1))
+ .WillOnce(Return(ByMove(std::vector<uint8_t>{0xbb})));
+ EXPECT_CALL(Process, WriteMemory(0x47, Trap)).WillOnce(Return(ByMove(1)));
+ EXPECT_CALL(Process, ReadMemory(0x47, 1))
+ .WillOnce(Return(ByMove(
+ llvm::createStringError(llvm::inconvertibleErrorCode(), "Foo"))));
+ EXPECT_THAT_ERROR(Process.SetBreakpoint(0x47, 0, false).ToError(),
+ llvm::Failed());
+}
+
+TEST(NativeProcessProtocolTest, ReadMemoryWithoutTrap) {
+ NiceMock<MockDelegate> DummyDelegate;
+ MockProcess Process(DummyDelegate, ArchSpec("aarch64-pc-linux"));
+ FakeMemory M{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}};
+ EXPECT_CALL(Process, ReadMemory(_, _))
+ .WillRepeatedly(Invoke(&M, &FakeMemory::Read));
+ EXPECT_CALL(Process, WriteMemory(_, _))
+ .WillRepeatedly(Invoke(&M, &FakeMemory::Write));
+
+ EXPECT_THAT_ERROR(Process.SetBreakpoint(0x4, 0, false).ToError(),
+ llvm::Succeeded());
+ EXPECT_THAT_EXPECTED(
+ Process.ReadMemoryWithoutTrap(0, 10),
+ llvm::HasValue(std::vector<uint8_t>{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}));
+ EXPECT_THAT_EXPECTED(Process.ReadMemoryWithoutTrap(0, 6),
+ llvm::HasValue(std::vector<uint8_t>{0, 1, 2, 3, 4, 5}));
+ EXPECT_THAT_EXPECTED(Process.ReadMemoryWithoutTrap(6, 4),
+ llvm::HasValue(std::vector<uint8_t>{6, 7, 8, 9}));
+ EXPECT_THAT_EXPECTED(Process.ReadMemoryWithoutTrap(6, 2),
+ llvm::HasValue(std::vector<uint8_t>{6, 7}));
+ EXPECT_THAT_EXPECTED(Process.ReadMemoryWithoutTrap(4, 2),
+ llvm::HasValue(std::vector<uint8_t>{4, 5}));
+}
diff --git a/unittests/Host/PredicateTest.cpp b/unittests/Host/PredicateTest.cpp
deleted file mode 100644
index 88ee6b6fc106..000000000000
--- a/unittests/Host/PredicateTest.cpp
+++ /dev/null
@@ -1,34 +0,0 @@
-//===-- PredicateTest.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/Predicate.h"
-#include "gtest/gtest.h"
-#include <thread>
-
-using namespace lldb_private;
-
-TEST(Predicate, WaitForValueEqualTo) {
- Predicate<int> P(0);
- EXPECT_TRUE(P.WaitForValueEqualTo(0));
- EXPECT_FALSE(P.WaitForValueEqualTo(1, std::chrono::milliseconds(10)));
-
- std::thread Setter([&P] {
- std::this_thread::sleep_for(std::chrono::milliseconds(100));
- P.SetValue(1, eBroadcastAlways);
- });
- EXPECT_TRUE(P.WaitForValueEqualTo(1));
- Setter.join();
-}
-
-TEST(Predicate, WaitForValueNotEqualTo) {
- Predicate<int> P(0);
- EXPECT_EQ(0, P.WaitForValueNotEqualTo(1));
- EXPECT_EQ(llvm::None,
- P.WaitForValueNotEqualTo(0, std::chrono::milliseconds(10)));
-}
diff --git a/unittests/Host/SocketTest.cpp b/unittests/Host/SocketTest.cpp
index 59f59fc0ada7..e7e713861441 100644
--- a/unittests/Host/SocketTest.cpp
+++ b/unittests/Host/SocketTest.cpp
@@ -17,6 +17,8 @@
#include "lldb/Host/Socket.h"
#include "lldb/Host/common/TCPSocket.h"
#include "lldb/Host/common/UDPSocket.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
#ifndef LLDB_DISABLE_POSIX
#include "lldb/Host/posix/DomainSocket.h"
@@ -41,7 +43,6 @@ public:
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);
@@ -49,7 +50,7 @@ protected:
template <typename SocketType>
void CreateConnectedSockets(
- const char *listen_remote_address,
+ llvm::StringRef 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;
@@ -64,8 +65,8 @@ protected:
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);
+ 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(
@@ -158,15 +159,15 @@ TEST_F(SocketTest, DecodeHostAndPort) {
#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);
+ llvm::SmallString<64> Path;
+ std::error_code EC = llvm::sys::fs::createUniqueDirectory("DomainListenConnectAccept", Path);
+ ASSERT_FALSE(EC);
+ llvm::sys::path::append(Path, "test");
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; },
+ Path, [=](const DomainSocket &) { return Path.str().str(); },
&socket_a_up, &socket_b_up);
}
#endif
diff --git a/unittests/Host/SymbolsTest.cpp b/unittests/Host/SymbolsTest.cpp
index 253ce39e31b5..e525f3d36801 100644
--- a/unittests/Host/SymbolsTest.cpp
+++ b/unittests/Host/SymbolsTest.cpp
@@ -9,25 +9,41 @@
#include "gtest/gtest.h"
-#include "lldb/Host/Symbols.h"
#include "lldb/Core/ModuleSpec.h"
+#include "lldb/Host/FileSystem.h"
+#include "lldb/Host/HostInfo.h"
+#include "lldb/Host/Symbols.h"
using namespace lldb_private;
-TEST(SymbolsTest,
- LocateExecutableSymbolFileForUnknownExecutableAndUnknownSymbolFile) {
+namespace {
+class SymbolsTest : public ::testing::Test {
+public:
+ void SetUp() override {
+ FileSystem::Initialize();
+ HostInfo::Initialize();
+ }
+ void TearDown() override {
+ HostInfo::Terminate();
+ FileSystem::Terminate();
+ }
+};
+} // namespace
+
+TEST_F(
+ SymbolsTest,
+ TerminateLocateExecutableSymbolFileForUnknownExecutableAndUnknownSymbolFile) {
ModuleSpec module_spec;
FileSpec symbol_file_spec = Symbols::LocateExecutableSymbolFile(module_spec);
EXPECT_TRUE(symbol_file_spec.GetFilename().IsEmpty());
}
-TEST(SymbolsTest,
- LocateExecutableSymbolFileForUnknownExecutableAndMissingSymbolFile) {
+TEST_F(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::Style::native);
+ "4A524676-B24B-4F4E-968A-551D465EBAF1.so", FileSpec::Style::native);
FileSpec symbol_file_spec = Symbols::LocateExecutableSymbolFile(module_spec);
EXPECT_TRUE(symbol_file_spec.GetFilename().IsEmpty());
}
diff --git a/unittests/Host/linux/HostTest.cpp b/unittests/Host/linux/HostTest.cpp
index 7ea702d8b18a..d539dbca6eae 100644
--- a/unittests/Host/linux/HostTest.cpp
+++ b/unittests/Host/linux/HostTest.cpp
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include "lldb/Host/Host.h"
+#include "lldb/Host/FileSystem.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Target/Process.h"
#include "gtest/gtest.h"
@@ -17,8 +18,14 @@ using namespace lldb_private;
namespace {
class HostTest : public testing::Test {
public:
- static void SetUpTestCase() { HostInfo::Initialize(); }
- static void TearDownTestCase() { HostInfo::Terminate(); }
+ static void SetUpTestCase() {
+ FileSystem::Initialize();
+ HostInfo::Initialize();
+ }
+ static void TearDownTestCase() {
+ HostInfo::Terminate();
+ FileSystem::Terminate();
+ }
};
} // namespace