diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2019-01-19 10:06:29 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2019-01-19 10:06:29 +0000 |
commit | 94994d372d014ce4c8758b9605d63fae651bd8aa (patch) | |
tree | 51c0b708bd59f205d6b35cb2a8c24d62f0c33d77 /unittests/Host | |
parent | 39be7ce23363d12ae3e49aeb1fdb2bfeb892e836 (diff) |
Notes
Diffstat (limited to 'unittests/Host')
-rw-r--r-- | unittests/Host/CMakeLists.txt | 3 | ||||
-rw-r--r-- | unittests/Host/FileSystemTest.cpp | 271 | ||||
-rw-r--r-- | unittests/Host/HostInfoTest.cpp | 21 | ||||
-rw-r--r-- | unittests/Host/NativeProcessProtocolTest.cpp | 225 | ||||
-rw-r--r-- | unittests/Host/PredicateTest.cpp | 34 | ||||
-rw-r--r-- | unittests/Host/SocketTest.cpp | 19 | ||||
-rw-r--r-- | unittests/Host/SymbolsTest.cpp | 30 | ||||
-rw-r--r-- | unittests/Host/linux/HostTest.cpp | 11 |
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 |