]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - unittests/Host/SocketTest.cpp
Vendor import of lldb release_50 branch r312293:
[FreeBSD/FreeBSD.git] / unittests / Host / SocketTest.cpp
1 //===-- SocketTest.cpp ------------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include <cstdio>
11 #include <functional>
12 #include <thread>
13
14 #include "gtest/gtest.h"
15
16 #include "lldb/Host/Config.h"
17 #include "lldb/Host/Socket.h"
18 #include "lldb/Host/common/TCPSocket.h"
19 #include "lldb/Host/common/UDPSocket.h"
20
21 #ifndef LLDB_DISABLE_POSIX
22 #include "lldb/Host/posix/DomainSocket.h"
23 #endif
24
25 using namespace lldb_private;
26
27 class SocketTest : public testing::Test {
28 public:
29   void SetUp() override {
30 #if defined(_MSC_VER)
31     WSADATA data;
32     ::WSAStartup(MAKEWORD(2, 2), &data);
33 #endif
34   }
35
36   void TearDown() override {
37 #if defined(_MSC_VER)
38     ::WSACleanup();
39 #endif
40   }
41
42 protected:
43   static void AcceptThread(Socket *listen_socket,
44                            const char *listen_remote_address,
45                            bool child_processes_inherit, Socket **accept_socket,
46                            Status *error) {
47     *error = listen_socket->Accept(*accept_socket);
48   }
49
50   template <typename SocketType>
51   void CreateConnectedSockets(
52       const char *listen_remote_address,
53       const std::function<std::string(const SocketType &)> &get_connect_addr,
54       std::unique_ptr<SocketType> *a_up, std::unique_ptr<SocketType> *b_up) {
55     bool child_processes_inherit = false;
56     Status error;
57     std::unique_ptr<SocketType> listen_socket_up(
58         new SocketType(true, child_processes_inherit));
59     EXPECT_FALSE(error.Fail());
60     error = listen_socket_up->Listen(listen_remote_address, 5);
61     EXPECT_FALSE(error.Fail());
62     EXPECT_TRUE(listen_socket_up->IsValid());
63
64     Status accept_error;
65     Socket *accept_socket;
66     std::thread accept_thread(AcceptThread, listen_socket_up.get(),
67                               listen_remote_address, child_processes_inherit,
68                               &accept_socket, &accept_error);
69
70     std::string connect_remote_address = get_connect_addr(*listen_socket_up);
71     std::unique_ptr<SocketType> connect_socket_up(
72         new SocketType(true, child_processes_inherit));
73     EXPECT_FALSE(error.Fail());
74     error = connect_socket_up->Connect(connect_remote_address);
75     EXPECT_FALSE(error.Fail());
76     EXPECT_TRUE(connect_socket_up->IsValid());
77
78     a_up->swap(connect_socket_up);
79     EXPECT_TRUE(error.Success());
80     EXPECT_NE(nullptr, a_up->get());
81     EXPECT_TRUE((*a_up)->IsValid());
82
83     accept_thread.join();
84     b_up->reset(static_cast<SocketType *>(accept_socket));
85     EXPECT_TRUE(accept_error.Success());
86     EXPECT_NE(nullptr, b_up->get());
87     EXPECT_TRUE((*b_up)->IsValid());
88
89     listen_socket_up.reset();
90   }
91 };
92
93 TEST_F(SocketTest, DecodeHostAndPort) {
94   std::string host_str;
95   std::string port_str;
96   int32_t port;
97   Status error;
98   EXPECT_TRUE(Socket::DecodeHostAndPort("localhost:1138", host_str, port_str,
99                                         port, &error));
100   EXPECT_STREQ("localhost", host_str.c_str());
101   EXPECT_STREQ("1138", port_str.c_str());
102   EXPECT_EQ(1138, port);
103   EXPECT_TRUE(error.Success());
104
105   EXPECT_FALSE(Socket::DecodeHostAndPort("google.com:65536", host_str, port_str,
106                                          port, &error));
107   EXPECT_TRUE(error.Fail());
108   EXPECT_STREQ("invalid host:port specification: 'google.com:65536'",
109                error.AsCString());
110
111   EXPECT_FALSE(Socket::DecodeHostAndPort("google.com:-1138", host_str, port_str,
112                                          port, &error));
113   EXPECT_TRUE(error.Fail());
114   EXPECT_STREQ("invalid host:port specification: 'google.com:-1138'",
115                error.AsCString());
116
117   EXPECT_FALSE(Socket::DecodeHostAndPort("google.com:65536", host_str, port_str,
118                                          port, &error));
119   EXPECT_TRUE(error.Fail());
120   EXPECT_STREQ("invalid host:port specification: 'google.com:65536'",
121                error.AsCString());
122
123   EXPECT_TRUE(
124       Socket::DecodeHostAndPort("12345", host_str, port_str, port, &error));
125   EXPECT_STREQ("", host_str.c_str());
126   EXPECT_STREQ("12345", port_str.c_str());
127   EXPECT_EQ(12345, port);
128   EXPECT_TRUE(error.Success());
129
130   EXPECT_TRUE(
131       Socket::DecodeHostAndPort("*:0", host_str, port_str, port, &error));
132   EXPECT_STREQ("*", host_str.c_str());
133   EXPECT_STREQ("0", port_str.c_str());
134   EXPECT_EQ(0, port);
135   EXPECT_TRUE(error.Success());
136
137   EXPECT_TRUE(
138       Socket::DecodeHostAndPort("*:65535", host_str, port_str, port, &error));
139   EXPECT_STREQ("*", host_str.c_str());
140   EXPECT_STREQ("65535", port_str.c_str());
141   EXPECT_EQ(65535, port);
142   EXPECT_TRUE(error.Success());
143
144   EXPECT_TRUE(
145       Socket::DecodeHostAndPort("[::1]:12345", host_str, port_str, port, &error));
146   EXPECT_STREQ("::1", host_str.c_str());
147   EXPECT_STREQ("12345", port_str.c_str());
148   EXPECT_EQ(12345, port);
149   EXPECT_TRUE(error.Success());
150
151   EXPECT_TRUE(
152       Socket::DecodeHostAndPort("[abcd:12fg:AF58::1]:12345", host_str, port_str, port, &error));
153   EXPECT_STREQ("abcd:12fg:AF58::1", host_str.c_str());
154   EXPECT_STREQ("12345", port_str.c_str());
155   EXPECT_EQ(12345, port);
156   EXPECT_TRUE(error.Success());
157 }
158
159 #ifndef LLDB_DISABLE_POSIX
160 TEST_F(SocketTest, DomainListenConnectAccept) {
161   char *file_name_str = tempnam(nullptr, nullptr);
162   EXPECT_NE(nullptr, file_name_str);
163   const std::string file_name(file_name_str);
164   free(file_name_str);
165
166   std::unique_ptr<DomainSocket> socket_a_up;
167   std::unique_ptr<DomainSocket> socket_b_up;
168   CreateConnectedSockets<DomainSocket>(
169       file_name.c_str(), [=](const DomainSocket &) { return file_name; },
170       &socket_a_up, &socket_b_up);
171 }
172 #endif
173
174 TEST_F(SocketTest, TCPListen0ConnectAccept) {
175   std::unique_ptr<TCPSocket> socket_a_up;
176   std::unique_ptr<TCPSocket> socket_b_up;
177   CreateConnectedSockets<TCPSocket>(
178       "127.0.0.1:0",
179       [=](const TCPSocket &s) {
180         char connect_remote_address[64];
181         snprintf(connect_remote_address, sizeof(connect_remote_address),
182                  "localhost:%u", s.GetLocalPortNumber());
183         return std::string(connect_remote_address);
184       },
185       &socket_a_up, &socket_b_up);
186 }
187
188 TEST_F(SocketTest, TCPGetAddress) {
189   std::unique_ptr<TCPSocket> socket_a_up;
190   std::unique_ptr<TCPSocket> socket_b_up;
191   CreateConnectedSockets<TCPSocket>(
192       "127.0.0.1:0",
193       [=](const TCPSocket &s) {
194         char connect_remote_address[64];
195         snprintf(connect_remote_address, sizeof(connect_remote_address),
196                  "localhost:%u", s.GetLocalPortNumber());
197         return std::string(connect_remote_address);
198       },
199       &socket_a_up, &socket_b_up);
200
201   EXPECT_EQ(socket_a_up->GetLocalPortNumber(),
202             socket_b_up->GetRemotePortNumber());
203   EXPECT_EQ(socket_b_up->GetLocalPortNumber(),
204             socket_a_up->GetRemotePortNumber());
205   EXPECT_NE(socket_a_up->GetLocalPortNumber(),
206             socket_b_up->GetLocalPortNumber());
207   EXPECT_STREQ("127.0.0.1", socket_a_up->GetRemoteIPAddress().c_str());
208   EXPECT_STREQ("127.0.0.1", socket_b_up->GetRemoteIPAddress().c_str());
209 }
210
211 TEST_F(SocketTest, UDPConnect) {
212   Socket *socket;
213
214   bool child_processes_inherit = false;
215   auto error = UDPSocket::Connect("127.0.0.1:0", child_processes_inherit,
216                                   socket);
217
218   std::unique_ptr<Socket> socket_up(socket);
219
220   EXPECT_TRUE(error.Success());
221   EXPECT_TRUE(socket_up->IsValid());
222 }
223
224 TEST_F(SocketTest, TCPListen0GetPort) {
225   Socket *server_socket;
226   Predicate<uint16_t> port_predicate;
227   port_predicate.SetValue(0, eBroadcastNever);
228   Status err =
229       Socket::TcpListen("10.10.12.3:0", false, server_socket, &port_predicate);
230   std::unique_ptr<TCPSocket> socket_up((TCPSocket*)server_socket);
231   EXPECT_TRUE(socket_up->IsValid());
232   EXPECT_NE(socket_up->GetLocalPortNumber(), 0);
233 }