brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.8 KiB · 48f747b Raw
156 lines · cpp
1//===-- RNBSocketTest.cpp -------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "gtest/gtest.h"10 11#include <arpa/inet.h>12#include <sys/sysctl.h>13#include <unistd.h>14 15#include "RNBDefs.h"16#include "RNBSocket.h"17#include "lldb/Host/Socket.h"18#include "lldb/Host/common/TCPSocket.h"19#include "llvm/Testing/Support/Error.h"20 21using namespace lldb_private;22 23std::string hello = "Hello, world!";24std::string goodbye = "Goodbye!";25 26static void ServerCallbackv4(const void *baton, in_port_t port) {27  auto child_pid = fork();28  if (child_pid == 0) {29    std::string addr_buffer =30        llvm::formatv("{0}:{1}", (const char *)baton, port).str();31    llvm::Expected<std::unique_ptr<Socket>> socket_or_err =32        Socket::TcpConnect(addr_buffer);33    ASSERT_THAT_EXPECTED(socket_or_err, llvm::Succeeded());34    Socket *client_socket = socket_or_err->get();35 36    char buffer[32];37    size_t read_size = 32;38    Status err = client_socket->Read((void *)&buffer[0], read_size);39    if (err.Fail())40      abort();41    std::string Recv(&buffer[0], read_size);42    if (Recv != hello)43      abort();44    size_t write_size = goodbye.length();45    err = client_socket->Write(goodbye.c_str(), write_size);46    if (err.Fail())47      abort();48    if (write_size != goodbye.length())49      abort();50    delete client_socket;51    exit(0);52  }53}54 55void TestSocketListen(const char *addr) {56  // Skip IPv6 tests if there isn't a valid interafce57  auto addresses = lldb_private::SocketAddress::GetAddressInfo(58      addr, NULL, AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP);59  if (addresses.size() == 0)60    return;61 62  const char *fmt = addresses.front().GetFamily() == AF_INET6 ? "[{0}]" : "{0}";63  std::string addr_wrap = llvm::formatv(fmt, addr).str();64 65  RNBSocket server_socket;66  auto result = server_socket.Listen(addr, 0, ServerCallbackv4,67                                     (const void *)addr_wrap.c_str());68  ASSERT_TRUE(result == rnb_success);69  result = server_socket.Write(hello.c_str(), hello.length());70  ASSERT_TRUE(result == rnb_success);71  std::string bye;72  result = server_socket.Read(bye);73  ASSERT_TRUE(result == rnb_success);74  ASSERT_EQ(bye, goodbye);75 76  int exit_status;77  wait(&exit_status);78  ASSERT_EQ(exit_status, 0);79}80 81TEST(RNBSocket, LoopBackListenIPv4) { TestSocketListen("127.0.0.1"); }82 83TEST(RNBSocket, LoopBackListenIPv6) { TestSocketListen("::1"); }84 85TEST(RNBSocket, AnyListen) { TestSocketListen("*"); }86 87void TestSocketConnect(const char *addr) {88  // Skip IPv6 tests if there isn't a valid interafce89  auto addresses = lldb_private::SocketAddress::GetAddressInfo(90      addr, NULL, AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP);91  if (addresses.size() == 0)92    return;93 94  const char *fmt =95      addresses.front().GetFamily() == AF_INET6 ? "[{0}]:0" : "{0}:0";96  std::string addr_wrap = llvm::formatv(fmt, addr).str();97 98  Socket *server_socket;99  llvm::Expected<std::unique_ptr<Socket>> socket_or_err =100      Socket::TcpListen(addr_wrap, false);101  ASSERT_THAT_EXPECTED(socket_or_err, llvm::Succeeded());102  server_socket = socket_or_err->get();103 104  auto port = ((TCPSocket *)server_socket)->GetLocalPortNumber();105  auto child_pid = fork();106  if (child_pid != 0) {107    RNBSocket client_socket;108    auto result = client_socket.Connect(addr, port);109    ASSERT_TRUE(result == rnb_success);110    result = client_socket.Write(hello.c_str(), hello.length());111    ASSERT_TRUE(result == rnb_success);112    std::string bye;113    result = client_socket.Read(bye);114    ASSERT_TRUE(result == rnb_success);115    ASSERT_EQ(bye, goodbye);116  } else {117    Socket *connected_socket;118    Status err =119        server_socket->Accept(std::chrono::seconds(10), connected_socket);120    if (err.Fail()) {121      llvm::errs() << err.AsCString();122      abort();123    }124    char buffer[32];125    size_t read_size = 32;126    err = connected_socket->Read((void *)&buffer[0], read_size);127    if (err.Fail()) {128      llvm::errs() << err.AsCString();129      abort();130    }131    std::string Recv(&buffer[0], read_size);132    if (Recv != hello) {133      llvm::errs() << err.AsCString();134      abort();135    }136    size_t write_size = goodbye.length();137    err = connected_socket->Write(goodbye.c_str(), write_size);138    if (err.Fail()) {139      llvm::errs() << err.AsCString();140      abort();141    }142    if (write_size != goodbye.length()) {143      llvm::errs() << err.AsCString();144      abort();145    }146    exit(0);147  }148  int exit_status;149  wait(&exit_status);150  ASSERT_EQ(exit_status, 0);151}152 153TEST(RNBSocket, LoopBackConnectIPv4) { TestSocketConnect("127.0.0.1"); }154 155TEST(RNBSocket, LoopBackConnectIPv6) { TestSocketConnect("::1"); }156