[lldb] Gracefully handle sockets being unavailable (#194712)
Gracefully handle sockets being unavailable, for example because the test suite is running in a sandboxed environment where you're not allowed to call bind.
This commit is contained in:
committed by
GitHub
parent
710c297289
commit
f09c938951
@@ -7,6 +7,7 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "lldb/Host/MainLoop.h"
|
||||
#include "TestingSupport/Host/SocketTestUtilities.h"
|
||||
#include "TestingSupport/SubsystemRAII.h"
|
||||
#include "lldb/Host/ConnectionFileDescriptor.h"
|
||||
#include "lldb/Host/FileSystem.h"
|
||||
@@ -28,6 +29,9 @@ public:
|
||||
SubsystemRAII<FileSystem, Socket> subsystems;
|
||||
|
||||
void SetUp() override {
|
||||
if (!HostSupportsIPv4() && !HostSupportsIPv6())
|
||||
GTEST_SKIP() << "TCP sockets unavailable";
|
||||
|
||||
Status error;
|
||||
auto listen_socket_up = std::make_unique<TCPSocket>(true);
|
||||
ASSERT_TRUE(error.Success());
|
||||
|
||||
@@ -80,12 +80,16 @@ TEST_F(SocketTest, DecodeHostAndPort) {
|
||||
TEST_F(SocketTest, CreatePair) {
|
||||
std::vector<std::optional<Socket::SocketProtocol>> functional_protocols = {
|
||||
std::nullopt,
|
||||
Socket::ProtocolTcp,
|
||||
#if LLDB_ENABLE_POSIX
|
||||
Socket::ProtocolUnixDomain,
|
||||
Socket::ProtocolUnixAbstract,
|
||||
#endif
|
||||
};
|
||||
if (HostSupportsIPv4() || HostSupportsIPv6())
|
||||
functional_protocols.push_back(Socket::ProtocolTcp);
|
||||
#if LLDB_ENABLE_POSIX
|
||||
if (HostSupportsDomainSockets()) {
|
||||
functional_protocols.push_back(Socket::ProtocolUnixDomain);
|
||||
functional_protocols.push_back(Socket::ProtocolUnixAbstract);
|
||||
}
|
||||
#endif
|
||||
|
||||
for (auto p : functional_protocols) {
|
||||
auto expected_socket_pair = Socket::CreatePair(p);
|
||||
ASSERT_THAT_EXPECTED(expected_socket_pair, llvm::Succeeded());
|
||||
@@ -114,6 +118,9 @@ TEST_F(SocketTest, CreatePair) {
|
||||
|
||||
#if LLDB_ENABLE_POSIX
|
||||
TEST_F(SocketTest, DomainListenConnectAccept) {
|
||||
if (!HostSupportsDomainSockets())
|
||||
GTEST_SKIP() << "Domain sockets unavailable";
|
||||
|
||||
llvm::SmallString<64> Path;
|
||||
std::error_code EC =
|
||||
llvm::sys::fs::createUniqueDirectory("DomainListenConnectAccept", Path);
|
||||
@@ -130,6 +137,9 @@ TEST_F(SocketTest, DomainListenConnectAccept) {
|
||||
}
|
||||
|
||||
TEST_F(SocketTest, DomainListenGetListeningConnectionURI) {
|
||||
if (!HostSupportsDomainSockets())
|
||||
GTEST_SKIP() << "Domain sockets unavailable";
|
||||
|
||||
llvm::SmallString<64> Path;
|
||||
std::error_code EC =
|
||||
llvm::sys::fs::createUniqueDirectory("DomainListenConnectAccept", Path);
|
||||
@@ -152,6 +162,9 @@ TEST_F(SocketTest, DomainListenGetListeningConnectionURI) {
|
||||
}
|
||||
|
||||
TEST_F(SocketTest, DomainMainLoopAccept) {
|
||||
if (!HostSupportsDomainSockets())
|
||||
GTEST_SKIP() << "Domain sockets unavailable";
|
||||
|
||||
llvm::SmallString<64> Path;
|
||||
std::error_code EC =
|
||||
llvm::sys::fs::createUniqueDirectory("DomainListenConnectAccept", Path);
|
||||
@@ -356,6 +369,9 @@ TEST_P(SocketTest, UDPGetConnectURI) {
|
||||
|
||||
#if LLDB_ENABLE_POSIX
|
||||
TEST_F(SocketTest, DomainGetConnectURI) {
|
||||
if (!HostSupportsDomainSockets())
|
||||
GTEST_SKIP() << "Domain sockets unavailable";
|
||||
|
||||
llvm::SmallString<64> domain_path;
|
||||
std::error_code EC = llvm::sys::fs::createUniqueDirectory(
|
||||
"DomainListenConnectAccept", domain_path);
|
||||
@@ -378,6 +394,9 @@ TEST_F(SocketTest, DomainGetConnectURI) {
|
||||
}
|
||||
|
||||
TEST_F(SocketTest, DomainSocketFromBoundNativeSocket) {
|
||||
if (!HostSupportsDomainSockets())
|
||||
GTEST_SKIP() << "Domain sockets unavailable";
|
||||
|
||||
// Generate a name for the domain socket.
|
||||
llvm::SmallString<64> name;
|
||||
std::error_code EC = llvm::sys::fs::createUniqueDirectory(
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "Plugins/Platform/Android/AdbClient.h"
|
||||
#include "TestingSupport/Host/SocketTestUtilities.h"
|
||||
#include "lldb/Host/Socket.h"
|
||||
#include "lldb/Host/common/TCPSocket.h"
|
||||
#include "gtest/gtest.h"
|
||||
@@ -112,6 +113,9 @@ static uint16_t FindUnusedPort() {
|
||||
// This test is disabled on Windows due to platform-specific socket behavior
|
||||
// that causes assertion failures in TCPSocket::Listen()
|
||||
TEST_F(AdbClientTest, RealTcpConnection) {
|
||||
if (!HostSupportsIPv4() && !HostSupportsIPv6())
|
||||
GTEST_SKIP() << "TCP sockets unavailable";
|
||||
|
||||
uint16_t unused_port = FindUnusedPort();
|
||||
ASSERT_NE(unused_port, 0) << "Failed to find an unused port";
|
||||
|
||||
|
||||
@@ -5,5 +5,6 @@ add_lldb_unittest(AdbClientTests
|
||||
PlatformAndroidTest.cpp
|
||||
|
||||
LINK_LIBS
|
||||
lldbHostHelpers
|
||||
lldbPluginPlatformAndroid
|
||||
)
|
||||
|
||||
@@ -94,7 +94,8 @@ static bool CheckIPSupport(llvm::StringRef Proto, llvm::StringRef Addr) {
|
||||
handleAllErrors(std::move(Err), [&](std::unique_ptr<llvm::ECError> ECErr) {
|
||||
std::error_code ec = ECErr->convertToErrorCode();
|
||||
if (ec == std::make_error_code(std::errc::address_family_not_supported) ||
|
||||
ec == std::make_error_code(std::errc::address_not_available))
|
||||
ec == std::make_error_code(std::errc::address_not_available) ||
|
||||
ec == std::make_error_code(std::errc::operation_not_permitted))
|
||||
HasProtocolError = true;
|
||||
});
|
||||
if (HasProtocolError) {
|
||||
@@ -146,3 +147,17 @@ llvm::Expected<std::string> lldb_private::GetLocalhostIP() {
|
||||
return llvm::createStringError(
|
||||
"Neither IPv4 nor IPv6 appear to be supported");
|
||||
}
|
||||
|
||||
#if LLDB_ENABLE_POSIX
|
||||
bool lldb_private::HostSupportsDomainSockets() {
|
||||
llvm::SmallString<64> Path;
|
||||
if (llvm::sys::fs::createUniqueDirectory("SocketTestCanary", Path))
|
||||
return false;
|
||||
llvm::sys::path::append(Path, "test");
|
||||
DomainSocket sock(true);
|
||||
Status status = sock.Listen(Path, 1);
|
||||
llvm::sys::fs::remove(Path);
|
||||
llvm::sys::fs::remove(Path.str().rsplit('/').first);
|
||||
return status.Success();
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -42,6 +42,9 @@ void CreateDomainConnectedSockets(llvm::StringRef path,
|
||||
|
||||
bool HostSupportsIPv6();
|
||||
bool HostSupportsIPv4();
|
||||
#if LLDB_ENABLE_POSIX
|
||||
bool HostSupportsDomainSockets();
|
||||
#endif
|
||||
|
||||
/// Returns true if the name `localhost` maps to a loopback IPv4 address.
|
||||
bool HostSupportsLocalhostToIPv4();
|
||||
|
||||
@@ -14,6 +14,7 @@ add_lldb_unittest(debugserverTests
|
||||
LINK_LIBS
|
||||
lldbDebugserverCommon
|
||||
lldbHost
|
||||
lldbHostHelpers
|
||||
LLVMTestingSupport
|
||||
)
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#include "RNBDefs.h"
|
||||
#include "RNBSocket.h"
|
||||
#include "TestingSupport/Host/SocketTestUtilities.h"
|
||||
#include "lldb/Host/Socket.h"
|
||||
#include "lldb/Host/common/TCPSocket.h"
|
||||
#include "llvm/Testing/Support/Error.h"
|
||||
@@ -53,6 +54,9 @@ static void ServerCallbackv4(const void *baton, in_port_t port) {
|
||||
}
|
||||
|
||||
void TestSocketListen(const char *addr) {
|
||||
if (!lldb_private::HostSupportsIPv4() && !lldb_private::HostSupportsIPv6())
|
||||
GTEST_SKIP() << "TCP sockets unavailable";
|
||||
|
||||
// Skip IPv6 tests if there isn't a valid interafce
|
||||
auto addresses = lldb_private::SocketAddress::GetAddressInfo(
|
||||
addr, NULL, AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP);
|
||||
@@ -85,6 +89,9 @@ TEST(RNBSocket, LoopBackListenIPv6) { TestSocketListen("::1"); }
|
||||
TEST(RNBSocket, AnyListen) { TestSocketListen("*"); }
|
||||
|
||||
void TestSocketConnect(const char *addr) {
|
||||
if (!lldb_private::HostSupportsIPv4() && !lldb_private::HostSupportsIPv6())
|
||||
GTEST_SKIP() << "TCP sockets unavailable";
|
||||
|
||||
// Skip IPv6 tests if there isn't a valid interafce
|
||||
auto addresses = lldb_private::SocketAddress::GetAddressInfo(
|
||||
addr, NULL, AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP);
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#define LLDB_UNITTESTS_TOOLS_LLDB_SERVER_TESTS_TESTBASE_H
|
||||
|
||||
#include "TestClient.h"
|
||||
#include "TestingSupport/Host/SocketTestUtilities.h"
|
||||
#include "lldb/Host/FileSystem.h"
|
||||
#include "lldb/Host/HostInfo.h"
|
||||
#include "lldb/Host/Socket.h"
|
||||
@@ -33,6 +34,11 @@ public:
|
||||
lldb_private::FileSystem::Terminate();
|
||||
}
|
||||
|
||||
void SetUp() override {
|
||||
if (!lldb_private::HostSupportsIPv4() && !lldb_private::HostSupportsIPv6())
|
||||
GTEST_SKIP() << "TCP sockets unavailable";
|
||||
}
|
||||
|
||||
static std::string getInferiorPath(llvm::StringRef Name) {
|
||||
llvm::SmallString<64> Path(LLDB_TEST_INFERIOR_PATH);
|
||||
llvm::sys::path::append(Path, Name + LLDB_TEST_INFERIOR_SUFFIX);
|
||||
|
||||
Reference in New Issue
Block a user