1 //===-- RNBSocketTest.cpp ---------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "gtest/gtest.h"
12 #include <arpa/inet.h>
13 #include <sys/sysctl.h>
17 #include "RNBSocket.h"
18 #include "lldb/Host/Socket.h"
19 #include "lldb/Host/StringConvert.h"
20 #include "lldb/Host/common/TCPSocket.h"
22 using namespace lldb_private;
24 std::string hello = "Hello, world!";
25 std::string goodbye = "Goodbye!";
27 static void ServerCallbackv4(const void *baton, in_port_t port) {
28 auto child_pid = fork();
30 Socket *client_socket;
31 char addr_buffer[256];
32 sprintf(addr_buffer, "%s:%d", baton, port);
33 Status err = Socket::TcpConnect(addr_buffer, false, client_socket);
37 size_t read_size = 32;
38 err = client_socket->Read((void *)&buffer[0], read_size);
41 std::string Recv(&buffer[0], read_size);
44 size_t write_size = goodbye.length();
45 err = client_socket->Write(goodbye.c_str(), write_size);
48 if (write_size != goodbye.length())
55 void TestSocketListen(const char *addr) {
56 // Skip IPv6 tests if there isn't a valid interafce
57 auto addresses = lldb_private::SocketAddress::GetAddressInfo(
58 addr, NULL, AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP);
59 if (addresses.size() == 0)
63 if (addresses.front().GetFamily() == AF_INET6)
64 sprintf(addr_wrap, "[%s]", addr);
66 sprintf(addr_wrap, "%s", addr);
68 RNBSocket server_socket;
70 server_socket.Listen(addr, 0, ServerCallbackv4, (const void *)addr_wrap);
71 ASSERT_TRUE(result == rnb_success);
72 result = server_socket.Write(hello.c_str(), hello.length());
73 ASSERT_TRUE(result == rnb_success);
75 result = server_socket.Read(bye);
76 ASSERT_TRUE(result == rnb_success);
77 ASSERT_EQ(bye, goodbye);
81 ASSERT_EQ(exit_status, 0);
84 TEST(RNBSocket, LoopBackListenIPv4) { TestSocketListen("127.0.0.1"); }
86 TEST(RNBSocket, LoopBackListenIPv6) { TestSocketListen("::1"); }
88 TEST(RNBSocket, AnyListen) { TestSocketListen("*"); }
90 void TestSocketConnect(const char *addr) {
91 // Skip IPv6 tests if there isn't a valid interafce
92 auto addresses = lldb_private::SocketAddress::GetAddressInfo(
93 addr, NULL, AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP);
94 if (addresses.size() == 0)
98 if (addresses.front().GetFamily() == AF_INET6)
99 sprintf(addr_wrap, "[%s]:0", addr);
101 sprintf(addr_wrap, "%s:0", addr);
103 Socket *server_socket;
104 Predicate<uint16_t> port_predicate;
105 port_predicate.SetValue(0, eBroadcastNever);
107 Socket::TcpListen(addr_wrap, false, server_socket, &port_predicate);
108 ASSERT_FALSE(err.Fail());
110 auto port = ((TCPSocket *)server_socket)->GetLocalPortNumber();
111 auto child_pid = fork();
112 if (child_pid != 0) {
113 RNBSocket client_socket;
114 auto result = client_socket.Connect(addr, port);
115 ASSERT_TRUE(result == rnb_success);
116 result = client_socket.Write(hello.c_str(), hello.length());
117 ASSERT_TRUE(result == rnb_success);
119 result = client_socket.Read(bye);
120 ASSERT_TRUE(result == rnb_success);
121 ASSERT_EQ(bye, goodbye);
123 Socket *connected_socket;
124 err = server_socket->Accept(connected_socket);
126 llvm::errs() << err.AsCString();
130 size_t read_size = 32;
131 err = connected_socket->Read((void *)&buffer[0], read_size);
133 llvm::errs() << err.AsCString();
136 std::string Recv(&buffer[0], read_size);
138 llvm::errs() << err.AsCString();
141 size_t write_size = goodbye.length();
142 err = connected_socket->Write(goodbye.c_str(), write_size);
144 llvm::errs() << err.AsCString();
147 if (write_size != goodbye.length()) {
148 llvm::errs() << err.AsCString();
155 ASSERT_EQ(exit_status, 0);
158 TEST(RNBSocket, LoopBackConnectIPv4) { TestSocketConnect("127.0.0.1"); }
160 TEST(RNBSocket, LoopBackConnectIPv6) { TestSocketConnect("::1"); }