diff options
Diffstat (limited to 'unittests/debugserver/RNBSocketTest.cpp')
-rw-r--r-- | unittests/debugserver/RNBSocketTest.cpp | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/unittests/debugserver/RNBSocketTest.cpp b/unittests/debugserver/RNBSocketTest.cpp new file mode 100644 index 000000000000..997041f6154b --- /dev/null +++ b/unittests/debugserver/RNBSocketTest.cpp @@ -0,0 +1,133 @@ +//===-- RNBSocketTest.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 <arpa/inet.h> +#include <sys/sysctl.h> +#include <unistd.h> + +#include "RNBDefs.h" +#include "RNBSocket.h" +#include "lldb/Host/Socket.h" +#include "lldb/Host/StringConvert.h" +#include "lldb/Host/common/TCPSocket.h" + +using namespace lldb_private; + +std::string hello = "Hello, world!"; +std::string goodbye = "Goodbye!"; + +static void ServerCallbackv4(const void *baton, in_port_t port) { + auto child_pid = fork(); + if (child_pid == 0) { + Socket *client_socket; + char addr_buffer[256]; + sprintf(addr_buffer, "%s:%d", baton, port); + Error err = Socket::TcpConnect(addr_buffer, false, client_socket); + if (err.Fail()) + abort(); + char buffer[32]; + size_t read_size = 32; + err = client_socket->Read((void *)&buffer[0], read_size); + if (err.Fail()) + abort(); + std::string Recv(&buffer[0], read_size); + if (Recv != hello) + abort(); + size_t write_size = goodbye.length(); + err = client_socket->Write(goodbye.c_str(), write_size); + if (err.Fail()) + abort(); + if (write_size != goodbye.length()) + abort(); + delete client_socket; + exit(0); + } +} + +void TestSocketListen(const char *addr) { + RNBSocket server_socket; + auto result = + server_socket.Listen(addr, 0, ServerCallbackv4, (const void *)addr); + ASSERT_TRUE(result == rnb_success); + result = server_socket.Write(hello.c_str(), hello.length()); + ASSERT_TRUE(result == rnb_success); + std::string bye; + result = server_socket.Read(bye); + ASSERT_TRUE(result == rnb_success); + ASSERT_EQ(bye, goodbye); + + int exit_status; + wait(&exit_status); + ASSERT_EQ(exit_status, 0); +} + +TEST(RNBSocket, LoopBackListenIPv4) { TestSocketListen("127.0.0.1"); } + +void TestSocketConnect(const char *addr) { + char addr_wrap[256]; + sprintf(addr_wrap, "%s:0", addr); + + Socket *server_socket; + Predicate<uint16_t> port_predicate; + port_predicate.SetValue(0, eBroadcastNever); + Error err = + Socket::TcpListen(addr_wrap, false, server_socket, &port_predicate); + ASSERT_FALSE(err.Fail()); + + auto port = ((TCPSocket *)server_socket)->GetLocalPortNumber(); + auto child_pid = fork(); + if (child_pid != 0) { + RNBSocket client_socket; + auto result = client_socket.Connect(addr, port); + ASSERT_TRUE(result == rnb_success); + result = client_socket.Write(hello.c_str(), hello.length()); + ASSERT_TRUE(result == rnb_success); + std::string bye; + result = client_socket.Read(bye); + ASSERT_TRUE(result == rnb_success); + ASSERT_EQ(bye, goodbye); + } else { + Socket *connected_socket; + err = server_socket->Accept(addr_wrap, false, connected_socket); + if (err.Fail()) { + llvm::errs() << err.AsCString(); + abort(); + } + char buffer[32]; + size_t read_size = 32; + err = connected_socket->Read((void *)&buffer[0], read_size); + if (err.Fail()) { + llvm::errs() << err.AsCString(); + abort(); + } + std::string Recv(&buffer[0], read_size); + if (Recv != hello) { + llvm::errs() << err.AsCString(); + abort(); + } + size_t write_size = goodbye.length(); + err = connected_socket->Write(goodbye.c_str(), write_size); + if (err.Fail()) { + llvm::errs() << err.AsCString(); + abort(); + } + if (write_size != goodbye.length()) { + llvm::errs() << err.AsCString(); + abort(); + } + exit(0); + } + int exit_status; + wait(&exit_status); + ASSERT_EQ(exit_status, 0); +} + +TEST(RNBSocket, LoopBackConnectIPv4) { TestSocketConnect("127.0.0.1"); } |