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,30 @@
//===-- BreakpointIDTest.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/Breakpoint/BreakpointID.h"
#include "lldb/Utility/Status.h"
#include "llvm/ADT/StringRef.h"
using namespace lldb;
using namespace lldb_private;
TEST(BreakpointIDTest, StringIsBreakpointName) {
Status E;
EXPECT_FALSE(BreakpointID::StringIsBreakpointName("1breakpoint", E));
EXPECT_FALSE(BreakpointID::StringIsBreakpointName("-", E));
EXPECT_FALSE(BreakpointID::StringIsBreakpointName("", E));
EXPECT_FALSE(BreakpointID::StringIsBreakpointName("3.4", E));
EXPECT_TRUE(BreakpointID::StringIsBreakpointName("_", E));
EXPECT_TRUE(BreakpointID::StringIsBreakpointName("a123", E));
EXPECT_TRUE(BreakpointID::StringIsBreakpointName("test", E));
}

View File

@@ -0,0 +1,9 @@
add_lldb_unittest(LLDBBreakpointTests
BreakpointIDTest.cpp
LINK_LIBS
lldbBreakpoint
lldbCore
LINK_COMPONENTS
Support
)

View File

@@ -0,0 +1,82 @@
add_custom_target(LLDBUnitTests)
set_target_properties(LLDBUnitTests PROPERTIES FOLDER "LLDB tests")
include_directories(${LLDB_SOURCE_ROOT})
include_directories(${LLDB_PROJECT_ROOT}/unittests)
set(LLDB_GTEST_COMMON_INCLUDE ${CMAKE_CURRENT_SOURCE_DIR}/gtest_common.h)
if (MSVC)
list(APPEND LLVM_COMPILE_FLAGS /FI ${LLDB_GTEST_COMMON_INCLUDE})
else ()
list(APPEND LLVM_COMPILE_FLAGS -include ${LLDB_GTEST_COMMON_INCLUDE})
endif ()
if (LLDB_BUILT_STANDALONE)
# Build the gtest library needed for unittests, if we have LLVM sources
# handy.
if (EXISTS ${LLVM_MAIN_SRC_DIR}/utils/unittest AND NOT TARGET gtest)
add_subdirectory(${LLVM_MAIN_SRC_DIR}/utils/unittest utils/unittest)
endif()
# LLVMTestingSupport library is needed for Process/gdb-remote.
if (EXISTS ${LLVM_MAIN_SRC_DIR}/lib/Testing/Support
AND NOT TARGET LLVMTestingSupport)
add_subdirectory(${LLVM_MAIN_SRC_DIR}/lib/Testing/Support
lib/Testing/Support)
endif()
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}
${ARG_UNPARSED_ARGUMENTS}
)
add_custom_command(
TARGET ${test_name}
POST_BUILD
COMMAND "${CMAKE_COMMAND}" -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/Inputs)
target_link_libraries(${test_name} PRIVATE ${ARG_LINK_LIBS})
endfunction()
function(add_unittest_inputs test_name inputs)
foreach (INPUT ${inputs})
add_custom_command(
TARGET ${test_name}
POST_BUILD
COMMAND "${CMAKE_COMMAND}" -E copy ${CMAKE_CURRENT_SOURCE_DIR}/Inputs/${INPUT} ${CMAKE_CURRENT_BINARY_DIR}/Inputs
COMMENT "Copying ${INPUT} to binary directory.")
endforeach()
endfunction()
add_subdirectory(TestingSupport)
add_subdirectory(Breakpoint)
add_subdirectory(Core)
add_subdirectory(Editline)
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(tools)
add_subdirectory(UnwindAssembly)
add_subdirectory(Utility)
if(LLDB_CAN_USE_DEBUGSERVER)
add_subdirectory(debugserver)
endif()

View File

@@ -0,0 +1,75 @@
//===-- BroadcasterTest.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/Core/Broadcaster.h"
#include "lldb/Core/Event.h"
#include "lldb/Core/Listener.h"
#include "lldb/Host/Predicate.h"
#include <thread>
using namespace lldb;
using namespace lldb_private;
TEST(BroadcasterTest, BroadcastEvent) {
EventSP event_sp;
Broadcaster broadcaster(nullptr, "test-broadcaster");
std::chrono::seconds timeout(0);
// Create a listener, sign it up, make sure it recieves an event.
ListenerSP listener1_sp = Listener::MakeListener("test-listener1");
const uint32_t event_mask1 = 1;
EXPECT_EQ(event_mask1,
listener1_sp->StartListeningForEvents(&broadcaster, event_mask1));
broadcaster.BroadcastEvent(event_mask1, nullptr);
EXPECT_TRUE(listener1_sp->GetEvent(event_sp, timeout));
EXPECT_EQ(event_mask1, event_sp->GetType());
{
// Add one more listener, make sure it works as well.
ListenerSP listener2_sp = Listener::MakeListener("test-listener2");
const uint32_t event_mask2 = 1;
EXPECT_EQ(event_mask2, listener2_sp->StartListeningForEvents(
&broadcaster, event_mask1 | event_mask2));
broadcaster.BroadcastEvent(event_mask2, nullptr);
EXPECT_TRUE(listener2_sp->GetEvent(event_sp, timeout));
EXPECT_EQ(event_mask2, event_sp->GetType());
// Both listeners should get this event.
broadcaster.BroadcastEvent(event_mask1, nullptr);
EXPECT_TRUE(listener1_sp->GetEvent(event_sp, timeout));
EXPECT_EQ(event_mask1, event_sp->GetType());
EXPECT_TRUE(listener2_sp->GetEvent(event_sp, timeout));
EXPECT_EQ(event_mask2, event_sp->GetType());
}
// Now again only one listener should be active.
broadcaster.BroadcastEvent(event_mask1, nullptr);
EXPECT_TRUE(listener1_sp->GetEvent(event_sp, timeout));
EXPECT_EQ(event_mask1, event_sp->GetType());
}
TEST(BroadcasterTest, EventTypeHasListeners) {
EventSP event_sp;
Broadcaster broadcaster(nullptr, "test-broadcaster");
const uint32_t event_mask = 1;
EXPECT_FALSE(broadcaster.EventTypeHasListeners(event_mask));
{
ListenerSP listener_sp = Listener::MakeListener("test-listener");
EXPECT_EQ(event_mask,
listener_sp->StartListeningForEvents(&broadcaster, event_mask));
EXPECT_TRUE(broadcaster.EventTypeHasListeners(event_mask));
}
EXPECT_FALSE(broadcaster.EventTypeHasListeners(event_mask));
}

View File

@@ -0,0 +1,14 @@
add_lldb_unittest(LLDBCoreTests
BroadcasterTest.cpp
DataExtractorTest.cpp
ListenerTest.cpp
ScalarTest.cpp
StateTest.cpp
StreamCallbackTest.cpp
LINK_LIBS
lldbCore
lldbHost
LINK_COMPONENTS
Support
)

View File

@@ -0,0 +1,168 @@
//===-- DataExtractorTest.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/DataExtractor.h"
using namespace lldb_private;
TEST(DataExtractorTest, GetBitfield) {
uint8_t buffer[] = {0x01, 0x23, 0x45, 0x67};
DataExtractor LE(buffer, sizeof(buffer), lldb::eByteOrderLittle,
sizeof(void *));
DataExtractor BE(buffer, sizeof(buffer), lldb::eByteOrderBig, sizeof(void *));
lldb::offset_t offset;
offset = 0;
ASSERT_EQ(buffer[1], LE.GetMaxU64Bitfield(&offset, sizeof(buffer), 8, 8));
offset = 0;
ASSERT_EQ(buffer[1], BE.GetMaxU64Bitfield(&offset, sizeof(buffer), 8, 8));
offset = 0;
ASSERT_EQ(int8_t(buffer[1]),
LE.GetMaxS64Bitfield(&offset, sizeof(buffer), 8, 8));
offset = 0;
ASSERT_EQ(int8_t(buffer[1]),
BE.GetMaxS64Bitfield(&offset, sizeof(buffer), 8, 8));
}
TEST(DataExtractorTest, PeekData) {
uint8_t buffer[] = {0x01, 0x02, 0x03, 0x04};
DataExtractor E(buffer, sizeof buffer, lldb::eByteOrderLittle, 4);
EXPECT_EQ(buffer + 0, E.PeekData(0, 0));
EXPECT_EQ(buffer + 0, E.PeekData(0, 4));
EXPECT_EQ(nullptr, E.PeekData(0, 5));
EXPECT_EQ(buffer + 2, E.PeekData(2, 0));
EXPECT_EQ(buffer + 2, E.PeekData(2, 2));
EXPECT_EQ(nullptr, E.PeekData(2, 3));
EXPECT_EQ(buffer + 4, E.PeekData(4, 0));
EXPECT_EQ(nullptr, E.PeekData(4, 1));
}
TEST(DataExtractorTest, GetMaxU64) {
uint8_t buffer[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
DataExtractor LE(buffer, sizeof(buffer), lldb::eByteOrderLittle,
sizeof(void *));
DataExtractor BE(buffer, sizeof(buffer), lldb::eByteOrderBig, sizeof(void *));
lldb::offset_t offset;
// Check with the minimum allowed byte size.
offset = 0;
EXPECT_EQ(0x01U, LE.GetMaxU64(&offset, 1));
EXPECT_EQ(1U, offset);
offset = 0;
EXPECT_EQ(0x01U, BE.GetMaxU64(&offset, 1));
EXPECT_EQ(1U, offset);
// Check with a non-zero offset.
offset = 1;
EXPECT_EQ(0x0302U, LE.GetMaxU64(&offset, 2));
EXPECT_EQ(3U, offset);
offset = 1;
EXPECT_EQ(0x0203U, BE.GetMaxU64(&offset, 2));
EXPECT_EQ(3U, offset);
// Check with the byte size not being a multiple of 2.
offset = 0;
EXPECT_EQ(0x07060504030201U, LE.GetMaxU64(&offset, 7));
EXPECT_EQ(7U, offset);
offset = 0;
EXPECT_EQ(0x01020304050607U, BE.GetMaxU64(&offset, 7));
EXPECT_EQ(7U, offset);
// Check with the maximum allowed byte size.
offset = 0;
EXPECT_EQ(0x0807060504030201U, LE.GetMaxU64(&offset, 8));
EXPECT_EQ(8U, offset);
offset = 0;
EXPECT_EQ(0x0102030405060708U, BE.GetMaxU64(&offset, 8));
EXPECT_EQ(8U, offset);
}
TEST(DataExtractorTest, GetMaxS64) {
uint8_t buffer[] = {0x01, 0x02, 0x83, 0x04, 0x05, 0x06, 0x07, 0x08};
DataExtractor LE(buffer, sizeof(buffer), lldb::eByteOrderLittle,
sizeof(void *));
DataExtractor BE(buffer, sizeof(buffer), lldb::eByteOrderBig, sizeof(void *));
lldb::offset_t offset;
// Check with the minimum allowed byte size.
offset = 0;
EXPECT_EQ(0x01, LE.GetMaxS64(&offset, 1));
EXPECT_EQ(1U, offset);
offset = 0;
EXPECT_EQ(0x01, BE.GetMaxS64(&offset, 1));
EXPECT_EQ(1U, offset);
// Check that sign extension works correctly.
offset = 0;
int64_t value = LE.GetMaxS64(&offset, 3);
EXPECT_EQ(0xffffffffff830201U, *reinterpret_cast<uint64_t *>(&value));
EXPECT_EQ(3U, offset);
offset = 2;
value = BE.GetMaxS64(&offset, 3);
EXPECT_EQ(0xffffffffff830405U, *reinterpret_cast<uint64_t *>(&value));
EXPECT_EQ(5U, offset);
// Check with the maximum allowed byte size.
offset = 0;
EXPECT_EQ(0x0807060504830201, LE.GetMaxS64(&offset, 8));
EXPECT_EQ(8U, offset);
offset = 0;
EXPECT_EQ(0x0102830405060708, BE.GetMaxS64(&offset, 8));
EXPECT_EQ(8U, offset);
}
TEST(DataExtractorTest, GetMaxU64_unchecked) {
uint8_t buffer[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
DataExtractor LE(buffer, sizeof(buffer), lldb::eByteOrderLittle,
sizeof(void *));
DataExtractor BE(buffer, sizeof(buffer), lldb::eByteOrderBig, sizeof(void *));
lldb::offset_t offset;
// Check with the minimum allowed byte size.
offset = 0;
EXPECT_EQ(0x01U, LE.GetMaxU64_unchecked(&offset, 1));
EXPECT_EQ(1U, offset);
offset = 0;
EXPECT_EQ(0x01U, BE.GetMaxU64_unchecked(&offset, 1));
EXPECT_EQ(1U, offset);
// Check with a non-zero offset.
offset = 1;
EXPECT_EQ(0x0302U, LE.GetMaxU64_unchecked(&offset, 2));
EXPECT_EQ(3U, offset);
offset = 1;
EXPECT_EQ(0x0203U, BE.GetMaxU64_unchecked(&offset, 2));
EXPECT_EQ(3U, offset);
// Check with the byte size not being a multiple of 2.
offset = 0;
EXPECT_EQ(0x07060504030201U, LE.GetMaxU64_unchecked(&offset, 7));
EXPECT_EQ(7U, offset);
offset = 0;
EXPECT_EQ(0x01020304050607U, BE.GetMaxU64_unchecked(&offset, 7));
EXPECT_EQ(7U, offset);
// Check with the maximum allowed byte size.
offset = 0;
EXPECT_EQ(0x0807060504030201U, LE.GetMaxU64_unchecked(&offset, 8));
EXPECT_EQ(8U, offset);
offset = 0;
EXPECT_EQ(0x0102030405060708U, BE.GetMaxU64_unchecked(&offset, 8));
EXPECT_EQ(8U, offset);
}

View File

@@ -0,0 +1,114 @@
//===-- ListenerTest.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/Core/Broadcaster.h"
#include "lldb/Core/Listener.h"
#include <future>
#include <thread>
using namespace lldb;
using namespace lldb_private;
TEST(ListenerTest, GetEventImmediate) {
EventSP event_sp;
Broadcaster broadcaster(nullptr, "test-broadcaster");
// Create a listener, sign it up, make sure it recieves an event.
ListenerSP listener_sp = Listener::MakeListener("test-listener");
const uint32_t event_mask = 1;
ASSERT_EQ(event_mask,
listener_sp->StartListeningForEvents(&broadcaster, event_mask));
const std::chrono::seconds timeout(0);
// Without any events sent, these should return false.
EXPECT_FALSE(listener_sp->GetEvent(event_sp, timeout));
EXPECT_FALSE(listener_sp->GetEventForBroadcaster(nullptr, event_sp, timeout));
EXPECT_FALSE(
listener_sp->GetEventForBroadcaster(&broadcaster, event_sp, timeout));
EXPECT_FALSE(listener_sp->GetEventForBroadcasterWithType(
&broadcaster, event_mask, event_sp, timeout));
// Now send events and make sure they get it.
broadcaster.BroadcastEvent(event_mask, nullptr);
EXPECT_TRUE(listener_sp->GetEvent(event_sp, timeout));
broadcaster.BroadcastEvent(event_mask, nullptr);
EXPECT_TRUE(listener_sp->GetEventForBroadcaster(nullptr, event_sp, timeout));
broadcaster.BroadcastEvent(event_mask, nullptr);
EXPECT_TRUE(
listener_sp->GetEventForBroadcaster(&broadcaster, event_sp, timeout));
broadcaster.BroadcastEvent(event_mask, nullptr);
EXPECT_FALSE(listener_sp->GetEventForBroadcasterWithType(
&broadcaster, event_mask * 2, event_sp, timeout));
EXPECT_TRUE(listener_sp->GetEventForBroadcasterWithType(
&broadcaster, event_mask, event_sp, timeout));
}
TEST(ListenerTest, GetEventWait) {
EventSP event_sp;
Broadcaster broadcaster(nullptr, "test-broadcaster");
// Create a listener, sign it up, make sure it recieves an event.
ListenerSP listener_sp = Listener::MakeListener("test-listener");
const uint32_t event_mask = 1;
ASSERT_EQ(event_mask,
listener_sp->StartListeningForEvents(&broadcaster, event_mask));
// Without any events sent, these should make a short wait and return false.
std::chrono::microseconds timeout(10);
EXPECT_FALSE(listener_sp->GetEvent(event_sp, timeout));
EXPECT_FALSE(listener_sp->GetEventForBroadcaster(nullptr, event_sp, timeout));
EXPECT_FALSE(
listener_sp->GetEventForBroadcaster(&broadcaster, event_sp, timeout));
EXPECT_FALSE(listener_sp->GetEventForBroadcasterWithType(
&broadcaster, event_mask, event_sp, timeout));
// Now send events and make sure they get it.
broadcaster.BroadcastEvent(event_mask, nullptr);
EXPECT_TRUE(listener_sp->GetEvent(event_sp, timeout));
broadcaster.BroadcastEvent(event_mask, nullptr);
EXPECT_TRUE(listener_sp->GetEventForBroadcaster(nullptr, event_sp, timeout));
broadcaster.BroadcastEvent(event_mask, nullptr);
EXPECT_TRUE(
listener_sp->GetEventForBroadcaster(&broadcaster, event_sp, timeout));
broadcaster.BroadcastEvent(event_mask, nullptr);
EXPECT_FALSE(listener_sp->GetEventForBroadcasterWithType(
&broadcaster, event_mask * 2, event_sp, timeout));
EXPECT_TRUE(listener_sp->GetEventForBroadcasterWithType(
&broadcaster, event_mask, event_sp, timeout));
auto delayed_broadcast = [&] {
std::this_thread::sleep_for(std::chrono::milliseconds(10));
broadcaster.BroadcastEvent(event_mask, nullptr);
};
// These should do an infinite wait at return the event our asynchronous
// broadcast sends.
std::future<void> async_broadcast =
std::async(std::launch::async, delayed_broadcast);
EXPECT_TRUE(listener_sp->GetEvent(event_sp, llvm::None));
async_broadcast.get();
async_broadcast = std::async(std::launch::async, delayed_broadcast);
EXPECT_TRUE(
listener_sp->GetEventForBroadcaster(&broadcaster, event_sp, llvm::None));
async_broadcast.get();
async_broadcast = std::async(std::launch::async, delayed_broadcast);
EXPECT_TRUE(listener_sp->GetEventForBroadcasterWithType(
&broadcaster, event_mask, event_sp, llvm::None));
async_broadcast.get();
}

View File

@@ -0,0 +1,134 @@
//===-- ScalarTest.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/Core/Scalar.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Endian.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StreamString.h"
using namespace lldb_private;
TEST(ScalarTest, RightShiftOperator) {
int a = 0x00001000;
int b = 0xFFFFFFFF;
int c = 4;
Scalar a_scalar(a);
Scalar b_scalar(b);
Scalar c_scalar(c);
ASSERT_EQ(a >> c, a_scalar >> c_scalar);
ASSERT_EQ(b >> c, b_scalar >> c_scalar);
}
TEST(ScalarTest, GetBytes) {
int a = 0x01020304;
long long b = 0x0102030405060708LL;
float c = 1234567.89e42;
double d = 1234567.89e42;
char e[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
char f[32] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32};
Scalar a_scalar(a);
Scalar b_scalar(b);
Scalar c_scalar(c);
Scalar d_scalar(d);
Scalar e_scalar;
Scalar f_scalar;
DataExtractor e_data(e, sizeof(e), endian::InlHostByteOrder(),
sizeof(void *));
Status e_error =
e_scalar.SetValueFromData(e_data, lldb::eEncodingUint, sizeof(e));
DataExtractor f_data(f, sizeof(f), endian::InlHostByteOrder(),
sizeof(void *));
Status f_error =
f_scalar.SetValueFromData(f_data, lldb::eEncodingUint, sizeof(f));
ASSERT_EQ(0, memcmp(&a, a_scalar.GetBytes(), sizeof(a)));
ASSERT_EQ(0, memcmp(&b, b_scalar.GetBytes(), sizeof(b)));
ASSERT_EQ(0, memcmp(&c, c_scalar.GetBytes(), sizeof(c)));
ASSERT_EQ(0, memcmp(&d, d_scalar.GetBytes(), sizeof(d)));
ASSERT_EQ(0, e_error.Fail());
ASSERT_EQ(0, memcmp(e, e_scalar.GetBytes(), sizeof(e)));
ASSERT_EQ(0, f_error.Fail());
ASSERT_EQ(0, memcmp(f, f_scalar.GetBytes(), sizeof(f)));
}
TEST(ScalarTest, CastOperations) {
long long a = 0xf1f2f3f4f5f6f7f8LL;
Scalar a_scalar(a);
ASSERT_EQ((signed char)a, a_scalar.SChar());
ASSERT_EQ((unsigned char)a, a_scalar.UChar());
ASSERT_EQ((signed short)a, a_scalar.SShort());
ASSERT_EQ((unsigned short)a, a_scalar.UShort());
ASSERT_EQ((signed int)a, a_scalar.SInt());
ASSERT_EQ((unsigned int)a, a_scalar.UInt());
ASSERT_EQ((signed long)a, a_scalar.SLong());
ASSERT_EQ((unsigned long)a, a_scalar.ULong());
ASSERT_EQ((signed long long)a, a_scalar.SLongLong());
ASSERT_EQ((unsigned long long)a, a_scalar.ULongLong());
}
TEST(ScalarTest, ExtractBitfield) {
uint32_t len = sizeof(long long) * 8;
long long a1 = 0xf1f2f3f4f5f6f7f8LL;
long long b1 = 0xff1f2f3f4f5f6f7fLL;
Scalar s_scalar(a1);
ASSERT_TRUE(s_scalar.ExtractBitfield(0, 0));
ASSERT_EQ(0, memcmp(&a1, s_scalar.GetBytes(), sizeof(a1)));
ASSERT_TRUE(s_scalar.ExtractBitfield(len, 0));
ASSERT_EQ(0, memcmp(&a1, s_scalar.GetBytes(), sizeof(a1)));
ASSERT_TRUE(s_scalar.ExtractBitfield(len - 4, 4));
ASSERT_EQ(0, memcmp(&b1, s_scalar.GetBytes(), sizeof(b1)));
unsigned long long a2 = 0xf1f2f3f4f5f6f7f8ULL;
unsigned long long b2 = 0x0f1f2f3f4f5f6f7fULL;
Scalar u_scalar(a2);
ASSERT_TRUE(u_scalar.ExtractBitfield(0, 0));
ASSERT_EQ(0, memcmp(&a2, u_scalar.GetBytes(), sizeof(a2)));
ASSERT_TRUE(u_scalar.ExtractBitfield(len, 0));
ASSERT_EQ(0, memcmp(&a2, u_scalar.GetBytes(), sizeof(a2)));
ASSERT_TRUE(u_scalar.ExtractBitfield(len - 4, 4));
ASSERT_EQ(0, memcmp(&b2, u_scalar.GetBytes(), sizeof(b2)));
}
template <typename T> static std::string ScalarGetValue(T value) {
StreamString stream;
Scalar(value).GetValue(&stream, false);
return stream.GetString();
}
TEST(ScalarTest, GetValue) {
EXPECT_EQ("12345", ScalarGetValue<signed short>(12345));
EXPECT_EQ("-12345", ScalarGetValue<signed short>(-12345));
EXPECT_EQ("12345", ScalarGetValue<unsigned short>(12345));
EXPECT_EQ(std::to_string(std::numeric_limits<unsigned short>::max()),
ScalarGetValue(std::numeric_limits<unsigned short>::max()));
EXPECT_EQ("12345", ScalarGetValue<signed int>(12345));
EXPECT_EQ("-12345", ScalarGetValue<signed int>(-12345));
EXPECT_EQ("12345", ScalarGetValue<unsigned int>(12345));
EXPECT_EQ(std::to_string(std::numeric_limits<unsigned int>::max()),
ScalarGetValue(std::numeric_limits<unsigned int>::max()));
EXPECT_EQ("12345678", ScalarGetValue<signed long>(12345678L));
EXPECT_EQ("-12345678", ScalarGetValue<signed long>(-12345678L));
EXPECT_EQ("12345678", ScalarGetValue<unsigned long>(12345678UL));
EXPECT_EQ(std::to_string(std::numeric_limits<unsigned long>::max()),
ScalarGetValue(std::numeric_limits<unsigned long>::max()));
EXPECT_EQ("1234567890123", ScalarGetValue<signed long long>(1234567890123LL));
EXPECT_EQ("-1234567890123",
ScalarGetValue<signed long long>(-1234567890123LL));
EXPECT_EQ("1234567890123",
ScalarGetValue<unsigned long long>(1234567890123ULL));
EXPECT_EQ(std::to_string(std::numeric_limits<unsigned long long>::max()),
ScalarGetValue(std::numeric_limits<unsigned long long>::max()));
}

View File

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

View File

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

View File

@@ -0,0 +1,8 @@
add_lldb_unittest(EditlineTests
EditlineTest.cpp
LINK_LIBS
lldbCore
lldbHost
lldbUtility
)

View File

@@ -0,0 +1,315 @@
//===-- EditlineTest.cpp ----------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLDB_DISABLE_LIBEDIT
#define EDITLINE_TEST_DUMP_OUTPUT 0
#include <stdio.h>
#include <unistd.h>
#include <memory>
#include <thread>
#include "gtest/gtest.h"
#include "lldb/Host/Editline.h"
#include "lldb/Host/Pipe.h"
#include "lldb/Host/PseudoTerminal.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StringList.h"
using namespace lldb_private;
namespace {
const size_t TIMEOUT_MILLIS = 5000;
}
class FilePointer {
public:
FilePointer() = delete;
FilePointer(const FilePointer &) = delete;
FilePointer(FILE *file_p) : _file_p(file_p) {}
~FilePointer() {
if (_file_p != nullptr) {
const int close_result = fclose(_file_p);
EXPECT_EQ(0, close_result);
}
}
operator FILE *() { return _file_p; }
private:
FILE *_file_p;
};
/**
Wraps an Editline class, providing a simple way to feed
input (as if from the keyboard) and receive output from Editline.
*/
class EditlineAdapter {
public:
EditlineAdapter();
void CloseInput();
bool IsValid() const { return _editline_sp.get() != nullptr; }
lldb_private::Editline &GetEditline() { return *_editline_sp; }
bool SendLine(const std::string &line);
bool SendLines(const std::vector<std::string> &lines);
bool GetLine(std::string &line, bool &interrupted, size_t timeout_millis);
bool GetLines(lldb_private::StringList &lines, bool &interrupted,
size_t timeout_millis);
void ConsumeAllOutput();
private:
static bool IsInputComplete(lldb_private::Editline *editline,
lldb_private::StringList &lines, void *baton);
std::unique_ptr<lldb_private::Editline> _editline_sp;
PseudoTerminal _pty;
int _pty_master_fd;
int _pty_slave_fd;
std::unique_ptr<FilePointer> _el_slave_file;
};
EditlineAdapter::EditlineAdapter()
: _editline_sp(), _pty(), _pty_master_fd(-1), _pty_slave_fd(-1),
_el_slave_file() {
lldb_private::Status error;
// Open the first master pty available.
char error_string[256];
error_string[0] = '\0';
if (!_pty.OpenFirstAvailableMaster(O_RDWR, error_string,
sizeof(error_string))) {
fprintf(stderr, "failed to open first available master pty: '%s'\n",
error_string);
return;
}
// Grab the master fd. This is a file descriptor we will:
// (1) write to when we want to send input to editline.
// (2) read from when we want to see what editline sends back.
_pty_master_fd = _pty.GetMasterFileDescriptor();
// Open the corresponding slave pty.
if (!_pty.OpenSlave(O_RDWR, error_string, sizeof(error_string))) {
fprintf(stderr, "failed to open slave pty: '%s'\n", error_string);
return;
}
_pty_slave_fd = _pty.GetSlaveFileDescriptor();
_el_slave_file.reset(new FilePointer(fdopen(_pty_slave_fd, "rw")));
EXPECT_FALSE(nullptr == *_el_slave_file);
if (*_el_slave_file == nullptr)
return;
// Create an Editline instance.
_editline_sp.reset(new lldb_private::Editline("gtest editor", *_el_slave_file,
*_el_slave_file,
*_el_slave_file, false));
_editline_sp->SetPrompt("> ");
// Hookup our input complete callback.
_editline_sp->SetIsInputCompleteCallback(IsInputComplete, this);
}
void EditlineAdapter::CloseInput() {
if (_el_slave_file != nullptr)
_el_slave_file.reset(nullptr);
}
bool EditlineAdapter::SendLine(const std::string &line) {
// Ensure we're valid before proceeding.
if (!IsValid())
return false;
// Write the line out to the pipe connected to editline's input.
ssize_t input_bytes_written =
::write(_pty_master_fd, line.c_str(),
line.length() * sizeof(std::string::value_type));
const char *eoln = "\n";
const size_t eoln_length = strlen(eoln);
input_bytes_written =
::write(_pty_master_fd, eoln, eoln_length * sizeof(char));
EXPECT_NE(-1, input_bytes_written) << strerror(errno);
EXPECT_EQ(eoln_length * sizeof(char), size_t(input_bytes_written));
return eoln_length * sizeof(char) == size_t(input_bytes_written);
}
bool EditlineAdapter::SendLines(const std::vector<std::string> &lines) {
for (auto &line : lines) {
#if EDITLINE_TEST_DUMP_OUTPUT
printf("<stdin> sending line \"%s\"\n", line.c_str());
#endif
if (!SendLine(line))
return false;
}
return true;
}
// We ignore the timeout for now.
bool EditlineAdapter::GetLine(std::string &line, bool &interrupted,
size_t /* timeout_millis */) {
// Ensure we're valid before proceeding.
if (!IsValid())
return false;
_editline_sp->GetLine(line, interrupted);
return true;
}
bool EditlineAdapter::GetLines(lldb_private::StringList &lines,
bool &interrupted, size_t /* timeout_millis */) {
// Ensure we're valid before proceeding.
if (!IsValid())
return false;
_editline_sp->GetLines(1, lines, interrupted);
return true;
}
bool EditlineAdapter::IsInputComplete(lldb_private::Editline *editline,
lldb_private::StringList &lines,
void *baton) {
// We'll call ourselves complete if we've received a balanced set of braces.
int start_block_count = 0;
int brace_balance = 0;
for (size_t i = 0; i < lines.GetSize(); ++i) {
for (auto ch : lines[i]) {
if (ch == '{') {
++start_block_count;
++brace_balance;
} else if (ch == '}')
--brace_balance;
}
}
return (start_block_count > 0) && (brace_balance == 0);
}
void EditlineAdapter::ConsumeAllOutput() {
FilePointer output_file(fdopen(_pty_master_fd, "r"));
int ch;
while ((ch = fgetc(output_file)) != EOF) {
#if EDITLINE_TEST_DUMP_OUTPUT
char display_str[] = {0, 0, 0};
switch (ch) {
case '\t':
display_str[0] = '\\';
display_str[1] = 't';
break;
case '\n':
display_str[0] = '\\';
display_str[1] = 'n';
break;
case '\r':
display_str[0] = '\\';
display_str[1] = 'r';
break;
default:
display_str[0] = ch;
break;
}
printf("<stdout> 0x%02x (%03d) (%s)\n", ch, ch, display_str);
// putc(ch, stdout);
#endif
}
}
class EditlineTestFixture : public ::testing::Test {
private:
EditlineAdapter _el_adapter;
std::shared_ptr<std::thread> _sp_output_thread;
public:
void SetUp() {
// We need a TERM set properly for editline to work as expected.
setenv("TERM", "vt100", 1);
// Validate the editline adapter.
EXPECT_TRUE(_el_adapter.IsValid());
if (!_el_adapter.IsValid())
return;
// Dump output.
_sp_output_thread.reset(
new std::thread([&] { _el_adapter.ConsumeAllOutput(); }));
}
void TearDown() {
_el_adapter.CloseInput();
if (_sp_output_thread)
_sp_output_thread->join();
}
EditlineAdapter &GetEditlineAdapter() { return _el_adapter; }
};
TEST_F(EditlineTestFixture, EditlineReceivesSingleLineText) {
// Send it some text via our virtual keyboard.
const std::string input_text("Hello, world");
EXPECT_TRUE(GetEditlineAdapter().SendLine(input_text));
// Verify editline sees what we put in.
std::string el_reported_line;
bool input_interrupted = false;
const bool received_line = GetEditlineAdapter().GetLine(
el_reported_line, input_interrupted, TIMEOUT_MILLIS);
EXPECT_TRUE(received_line);
EXPECT_FALSE(input_interrupted);
EXPECT_EQ(input_text, el_reported_line);
}
TEST_F(EditlineTestFixture, EditlineReceivesMultiLineText) {
// Send it some text via our virtual keyboard.
std::vector<std::string> input_lines;
input_lines.push_back("int foo()");
input_lines.push_back("{");
input_lines.push_back("printf(\"Hello, world\");");
input_lines.push_back("}");
input_lines.push_back("");
EXPECT_TRUE(GetEditlineAdapter().SendLines(input_lines));
// Verify editline sees what we put in.
lldb_private::StringList el_reported_lines;
bool input_interrupted = false;
EXPECT_TRUE(GetEditlineAdapter().GetLines(el_reported_lines,
input_interrupted, TIMEOUT_MILLIS));
EXPECT_FALSE(input_interrupted);
// Without any auto indentation support, our output should directly match our
// input.
EXPECT_EQ(input_lines.size(), el_reported_lines.GetSize());
if (input_lines.size() == el_reported_lines.GetSize()) {
for (size_t i = 0; i < input_lines.size(); ++i)
EXPECT_EQ(input_lines[i], el_reported_lines[i]);
}
}
#endif

View File

@@ -0,0 +1,7 @@
add_lldb_unittest(ExpressionTests
GoParserTest.cpp
LINK_LIBS
lldbCore
lldbPluginExpressionParserGo
)

View File

@@ -0,0 +1,273 @@
//===-- GoParserTest.cpp ------------------------------------------*- C++
//-*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <sstream>
#include "gtest/gtest.h"
#include "Plugins/ExpressionParser/Go/GoParser.h"
#include "lldb/Utility/Status.h"
using namespace lldb_private;
namespace {
struct ASTPrinter {
ASTPrinter(GoASTNode *n) { (*this)(n); }
void operator()(GoASTNode *n) {
if (n == nullptr) {
m_stream << "nil ";
return;
}
m_stream << "(" << n->GetKindName() << " ";
n->WalkChildren(*this);
if (auto *nn = llvm::dyn_cast<GoASTAssignStmt>(n))
m_stream << nn->GetDefine() << " ";
if (auto *nn = llvm::dyn_cast<GoASTBasicLit>(n))
m_stream << nn->GetValue().m_value.str() << " ";
if (auto *nn = llvm::dyn_cast<GoASTBinaryExpr>(n))
m_stream << GoLexer::LookupToken(nn->GetOp()).str() << " ";
if (auto *nn = llvm::dyn_cast<GoASTIdent>(n))
m_stream << nn->GetName().m_value.str() << " ";
if (auto *nn = llvm::dyn_cast<GoASTBranchStmt>(n))
m_stream << GoLexer::LookupToken(nn->GetTok()).str() << " ";
if (auto *nn = llvm::dyn_cast<GoASTCallExpr>(n))
m_stream << (nn->GetEllipsis() ? "..." : "") << " ";
if (auto *nn = llvm::dyn_cast<GoASTChanType>(n))
m_stream << nn->GetDir() << " ";
if (auto *nn = llvm::dyn_cast<GoASTGenDecl>(n))
m_stream << GoLexer::LookupToken(nn->GetTok()).str() << " ";
if (auto *nn = llvm::dyn_cast<GoASTIncDecStmt>(n))
m_stream << GoLexer::LookupToken(nn->GetTok()).str() << " ";
if (auto *nn = llvm::dyn_cast<GoASTRangeStmt>(n))
m_stream << nn->GetDefine() << " ";
if (auto *nn = llvm::dyn_cast<GoASTSliceExpr>(n))
m_stream << nn->GetSlice3() << " ";
if (auto *nn = llvm::dyn_cast<GoASTUnaryExpr>(n))
m_stream << GoLexer::LookupToken(nn->GetOp()).str() << " ";
m_stream << ") ";
}
const std::string str() const { return m_stream.str(); }
std::stringstream m_stream;
};
testing::AssertionResult CheckStatement(const char *_s, const char *c_expr,
const char *sexpr, const char *code) {
GoParser parser(code);
std::unique_ptr<GoASTStmt> stmt(parser.Statement());
if (parser.Failed() || !stmt) {
Status err;
parser.GetError(err);
return testing::AssertionFailure() << "Error parsing " << c_expr << "\n\t"
<< err.AsCString();
}
std::string actual_sexpr = ASTPrinter(stmt.get()).str();
if (actual_sexpr == sexpr)
return testing::AssertionSuccess();
return testing::AssertionFailure() << "Parsing: " << c_expr
<< "\nExpected: " << sexpr
<< "\nGot: " << actual_sexpr;
}
} // namespace
#define EXPECT_PARSE(s, c) EXPECT_PRED_FORMAT2(CheckStatement, s, c)
TEST(GoParserTest, ParseBasicLiterals) {
EXPECT_PARSE("(ExprStmt (BasicLit 0 ) ) ", "0");
EXPECT_PARSE("(ExprStmt (BasicLit 42 ) ) ", "42");
EXPECT_PARSE("(ExprStmt (BasicLit 0600 ) ) ", "0600");
EXPECT_PARSE("(ExprStmt (BasicLit 0xBadFace ) ) ", "0xBadFace");
EXPECT_PARSE(
"(ExprStmt (BasicLit 170141183460469231731687303715884105727 ) ) ",
"170141183460469231731687303715884105727");
EXPECT_PARSE("(ExprStmt (BasicLit 0. ) ) ", "0.");
EXPECT_PARSE("(ExprStmt (BasicLit 72.40 ) ) ", "72.40");
EXPECT_PARSE("(ExprStmt (BasicLit 072.40 ) ) ", "072.40");
EXPECT_PARSE("(ExprStmt (BasicLit 2.71828 ) ) ", "2.71828");
EXPECT_PARSE("(ExprStmt (BasicLit 1.e+0 ) ) ", "1.e+0");
EXPECT_PARSE("(ExprStmt (BasicLit 6.67428e-11 ) ) ", "6.67428e-11");
EXPECT_PARSE("(ExprStmt (BasicLit 1E6 ) ) ", "1E6");
EXPECT_PARSE("(ExprStmt (BasicLit .12345E+6 ) ) ", ".12345E+6");
EXPECT_PARSE("(ExprStmt (BasicLit 0i ) ) ", "0i");
EXPECT_PARSE("(ExprStmt (BasicLit 011i ) ) ", "011i");
EXPECT_PARSE("(ExprStmt (BasicLit 0.i ) ) ", "0.i");
EXPECT_PARSE("(ExprStmt (BasicLit 2.71828i ) ) ", "2.71828i");
EXPECT_PARSE("(ExprStmt (BasicLit 6.67428e-11i ) ) ", "6.67428e-11i");
EXPECT_PARSE("(ExprStmt (BasicLit 1E6i ) ) ", "1E6i");
EXPECT_PARSE("(ExprStmt (BasicLit .12345E+6i ) ) ", ".12345E+6i");
EXPECT_PARSE("(ExprStmt (BasicLit 'a' ) ) ", "'a'");
EXPECT_PARSE("(ExprStmt (BasicLit '本' ) ) ", "'本'");
EXPECT_PARSE("(ExprStmt (BasicLit \"abc\" ) ) ", "\"abc\"");
EXPECT_PARSE("(ExprStmt (BasicLit `abc` ) ) ", "`abc`");
EXPECT_PARSE("(ExprStmt (BasicLit `ab\nc` ) ) ", "`ab\nc`");
}
TEST(GoParserTest, ParseOperand) {
EXPECT_PARSE("(ExprStmt (Ident a ) ) ", "a");
EXPECT_PARSE("(ExprStmt (Ident _x9 ) ) ", "_x9");
EXPECT_PARSE("(ExprStmt (Ident ThisVariableIsExported ) ) ",
"ThisVariableIsExported");
EXPECT_PARSE("(ExprStmt (Ident αβ ) ) ", "αβ");
EXPECT_PARSE("(ExprStmt (SelectorExpr (Ident math ) (Ident Sin ) ) ) ",
"math.Sin");
}
TEST(GoParserTest, ParseCompositeLiterals) {
EXPECT_PARSE("(ExprStmt (CompositeLit (Ident Point3D ) ) ) ", "Point3D{}");
EXPECT_PARSE("(ExprStmt (CompositeLit (Ident Line ) (Ident origin ) "
"(CompositeLit (Ident Point3D ) (KeyValueExpr "
"(Ident y ) (UnaryExpr (BasicLit 4 ) - ) ) (KeyValueExpr (Ident "
"z ) (BasicLit 12.3 ) ) ) ) ) ",
"Line{origin, Point3D{y: -4, z: 12.3}}");
EXPECT_PARSE("(ExprStmt (CompositeLit (ArrayType (BasicLit 10 ) (Ident "
"string ) ) ) ) ",
"[10]string{}");
EXPECT_PARSE("(ExprStmt (CompositeLit (ArrayType (BasicLit 6 ) (Ident int ) "
") (BasicLit 1 ) (BasicLit 2 ) "
"(BasicLit 3 ) (BasicLit 5 ) ) ) ",
"[6]int {1, 2, 3, 5}");
EXPECT_PARSE("(ExprStmt (CompositeLit (ArrayType nil (Ident int ) ) "
"(BasicLit 2 ) (BasicLit 3 ) (BasicLit 5 ) "
"(BasicLit 7 ) (BasicLit 9 ) (BasicLit 2147483647 ) ) ) ",
"[]int{2, 3, 5, 7, 9, 2147483647}");
EXPECT_PARSE("(ExprStmt (CompositeLit (ArrayType (BasicLit 128 ) (Ident bool "
") ) (KeyValueExpr (BasicLit 'a' ) "
"(Ident true ) ) (KeyValueExpr (BasicLit 'e' ) (Ident true ) ) "
"(KeyValueExpr (BasicLit 'i' ) (Ident "
"true ) ) (KeyValueExpr (BasicLit 'o' ) (Ident true ) ) "
"(KeyValueExpr (BasicLit 'u' ) (Ident true ) ) "
"(KeyValueExpr (BasicLit 'y' ) (Ident true ) ) ) ) ",
"[128]bool{'a': true, 'e': true, 'i': true, 'o': true, 'u': "
"true, 'y': true}");
EXPECT_PARSE(
"(ExprStmt (CompositeLit (ArrayType (BasicLit 10 ) (Ident float32 ) ) "
"(UnaryExpr (BasicLit 1 ) - ) "
"(KeyValueExpr (BasicLit 4 ) (UnaryExpr (BasicLit 0.1 ) - ) ) (UnaryExpr "
"(BasicLit 0.1 ) - ) "
"(KeyValueExpr (BasicLit 9 ) (UnaryExpr (BasicLit 1 ) - ) ) ) ) ",
"[10]float32{-1, 4: -0.1, -0.1, 9: -1}");
}
TEST(GoParserTest, ParseEllipsisArray) {
EXPECT_PARSE("(ExprStmt (CompositeLit (ArrayType (Ellipsis nil ) (Ident "
"string ) ) (BasicLit `Sat` ) (BasicLit `Sun` ) ) ) ",
"[...]string {`Sat`, `Sun`}");
EXPECT_PARSE("(ExprStmt (CompositeLit (ArrayType (Ellipsis nil ) (Ident "
"Point ) ) (CompositeLit nil (BasicLit 1.5 "
") (UnaryExpr (BasicLit 3.5 ) - ) ) (CompositeLit nil (BasicLit "
"0 ) (BasicLit 0 ) ) ) ) ",
"[...]Point{{1.5, -3.5}, {0, 0}}");
}
TEST(GoParserTest, ParseMap) {
EXPECT_PARSE("(ExprStmt (CompositeLit (MapType (Ident string ) (Ident "
"float32 ) ) (KeyValueExpr (BasicLit `C0` ) "
"(BasicLit 16.35 ) ) (KeyValueExpr (BasicLit `D0` ) (BasicLit "
"18.35 ) ) ) ) ",
"map[string]float32{`C0`: 16.35, `D0`: 18.35, }");
}
TEST(GoParserTest, UnaryExpr) {
EXPECT_PARSE("(ExprStmt (UnaryExpr (Ident x ) + ) ) ", "+x");
EXPECT_PARSE("(ExprStmt (UnaryExpr (Ident x ) - ) ) ", "-x");
EXPECT_PARSE("(ExprStmt (UnaryExpr (Ident x ) ! ) ) ", "!x");
EXPECT_PARSE("(ExprStmt (UnaryExpr (Ident x ) ^ ) ) ", "^x");
EXPECT_PARSE("(ExprStmt (UnaryExpr (Ident x ) & ) ) ", "&x");
EXPECT_PARSE("(ExprStmt (UnaryExpr (Ident x ) <- ) ) ", "<-x");
EXPECT_PARSE("(ExprStmt (StarExpr (Ident x ) ) ) ", "*x");
}
TEST(GoParserTest, BinaryExpr) {
EXPECT_PARSE("(ExprStmt (BinaryExpr (Ident a ) (Ident b ) || ) ) ", "a || b");
EXPECT_PARSE("(ExprStmt (BinaryExpr (Ident a ) (Ident b ) && ) ) ", "a && b");
EXPECT_PARSE("(ExprStmt (BinaryExpr (Ident a ) (Ident b ) == ) ) ", "a == b");
EXPECT_PARSE("(ExprStmt (BinaryExpr (Ident a ) (Ident b ) != ) ) ", "a != b");
EXPECT_PARSE("(ExprStmt (BinaryExpr (Ident a ) (Ident b ) < ) ) ", "a < b");
EXPECT_PARSE("(ExprStmt (BinaryExpr (Ident a ) (Ident b ) <= ) ) ", "a <= b");
EXPECT_PARSE("(ExprStmt (BinaryExpr (Ident a ) (Ident b ) > ) ) ", "a > b");
EXPECT_PARSE("(ExprStmt (BinaryExpr (Ident a ) (Ident b ) >= ) ) ", "a >= b");
EXPECT_PARSE("(ExprStmt (BinaryExpr (Ident a ) (Ident b ) + ) ) ", "a + b");
EXPECT_PARSE("(ExprStmt (BinaryExpr (Ident a ) (Ident b ) - ) ) ", "a - b");
EXPECT_PARSE("(ExprStmt (BinaryExpr (Ident a ) (Ident b ) | ) ) ", "a | b");
EXPECT_PARSE("(ExprStmt (BinaryExpr (Ident a ) (Ident b ) ^ ) ) ", "a ^ b");
EXPECT_PARSE("(ExprStmt (BinaryExpr (Ident a ) (Ident b ) * ) ) ", "a * b");
EXPECT_PARSE("(ExprStmt (BinaryExpr (Ident a ) (Ident b ) / ) ) ", "a / b");
EXPECT_PARSE("(ExprStmt (BinaryExpr (Ident a ) (Ident b ) % ) ) ", "a % b");
EXPECT_PARSE("(ExprStmt (BinaryExpr (Ident a ) (Ident b ) << ) ) ", "a << b");
EXPECT_PARSE("(ExprStmt (BinaryExpr (Ident a ) (Ident b ) >> ) ) ", "a >> b");
EXPECT_PARSE("(ExprStmt (BinaryExpr (Ident a ) (Ident b ) & ) ) ", "a & b");
EXPECT_PARSE("(ExprStmt (BinaryExpr (Ident a ) (Ident b ) &^ ) ) ", "a &^ b");
EXPECT_PARSE("(ExprStmt (BinaryExpr (BasicLit 23 ) (BinaryExpr (BasicLit 3 ) "
"(IndexExpr (Ident x ) (Ident i ) ) * ) + ) ) ",
"23 + 3*x[i]");
EXPECT_PARSE("(ExprStmt (BinaryExpr (Ident a ) (UnaryExpr (UnaryExpr (Ident "
"a ) + ) + ) + ) ) ",
"a + + + a");
EXPECT_PARSE(
"(ExprStmt (BinaryExpr (UnaryExpr (Ident a ) ^ ) (Ident b ) >> ) ) ",
"^a >> b");
EXPECT_PARSE("(ExprStmt (BinaryExpr (CallExpr (Ident f ) ) (CallExpr (Ident "
"g ) ) || ) ) ",
"f() || g()");
EXPECT_PARSE(
"(ExprStmt (BinaryExpr (BinaryExpr (Ident x ) (BinaryExpr (Ident y ) "
"(BasicLit 1 ) + ) == ) "
"(BinaryExpr (UnaryExpr (Ident chanPtr ) <- ) (BasicLit 0 ) > ) && ) ) ",
"x == y+1 && <-chanPtr > 0");
}
TEST(GoParserTest, PrimaryExpr) {
EXPECT_PARSE(
"(ExprStmt (BinaryExpr (Ident x ) (CallExpr (Ident f ) ) <= ) ) ",
"x <= f()");
EXPECT_PARSE("(ExprStmt (BinaryExpr (Ident s ) (BasicLit `.txt` ) + ) ) ",
"(s + `.txt`)");
EXPECT_PARSE(
"(ExprStmt (CallExpr (Ident f ) (BasicLit 3.1415 ) (Ident true ) ) ) ",
"f(3.1415, true)");
EXPECT_PARSE(
"(ExprStmt (CallExpr (Ident f ) (BasicLit 3.1415 ) (Ident a ) ... ) ) ",
"f(3.1415, a...)");
EXPECT_PARSE("(ExprStmt (IndexExpr (Ident m ) (BasicLit '1' ) ) ) ",
"m['1']");
EXPECT_PARSE("(ExprStmt (SliceExpr (Ident s ) (Ident i ) (BinaryExpr (Ident "
"j ) (BasicLit 1 ) + ) nil 0 ) ) ",
"s[i : j + 1]");
EXPECT_PARSE("(ExprStmt (SelectorExpr (Ident obj ) (Ident color ) ) ) ",
"obj.color");
EXPECT_PARSE("(ExprStmt (CallExpr (SelectorExpr (IndexExpr (SelectorExpr "
"(Ident f ) (Ident p ) ) (Ident i ) ) "
"(Ident x ) ) ) ) ",
"f.p[i].x()");
}
TEST(GoParserTest, Conversions) {
EXPECT_PARSE(
"(ExprStmt (StarExpr (CallExpr (Ident Point ) (Ident p ) ) ) ) ",
"*Point(p)");
EXPECT_PARSE(
"(ExprStmt (CallExpr (StarExpr (Ident Point ) ) (Ident p ) ) ) ",
"(*Point)(p)");
EXPECT_PARSE("(ExprStmt (UnaryExpr (CallExpr (ChanType (Ident int ) 0 ) "
"(Ident c ) ) <- ) ) ",
"<-chan int(c)");
EXPECT_PARSE("(ExprStmt (TypeAssertExpr (Ident y ) (SelectorExpr (Ident io ) "
"(Ident Reader ) ) ) ) ",
"y.(io.Reader)");
}

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

Some files were not shown because too many files have changed in this diff Show More