]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - unittests/Host/SocketTest.cpp
Vendor import of lldb release_39 branch r276489:
[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 #if defined(_MSC_VER) && (_HAS_EXCEPTIONS == 0)
11 // Workaround for MSVC standard library bug, which fails to include <thread> when
12 // exceptions are disabled.
13 #include <eh.h>
14 #endif
15
16 #include <cstdio>
17 #include <functional>
18 #include <thread>
19
20 #include "gtest/gtest.h"
21
22 #include "lldb/Host/Config.h"
23 #include "lldb/Host/Socket.h"
24 #include "lldb/Host/common/TCPSocket.h"
25 #include "lldb/Host/common/UDPSocket.h"
26
27 #ifndef LLDB_DISABLE_POSIX
28 #include "lldb/Host/posix/DomainSocket.h"
29 #endif
30
31 using namespace lldb_private;
32
33 class SocketTest : public testing::Test
34 {
35   public:
36     void
37     SetUp() override
38     {
39 #if defined(_MSC_VER)
40         WSADATA data;
41         ::WSAStartup(MAKEWORD(2, 2), &data);
42 #endif
43     }
44
45     void
46     TearDown() override
47     {
48 #if defined(_MSC_VER)
49         ::WSACleanup();
50 #endif
51     }
52
53   protected:
54     static void
55     AcceptThread(Socket *listen_socket, const char *listen_remote_address, bool child_processes_inherit,
56                  Socket **accept_socket, Error *error)
57     {
58         *error = listen_socket->Accept(listen_remote_address, child_processes_inherit, *accept_socket);
59     }
60
61     template<typename SocketType>
62     void
63     CreateConnectedSockets(const char *listen_remote_address, const std::function<std::string(const SocketType&)> &get_connect_addr, std::unique_ptr<SocketType> *a_up, std::unique_ptr<SocketType> *b_up)
64     {
65         bool child_processes_inherit = false;
66         Error error;
67         std::unique_ptr<SocketType> listen_socket_up(new SocketType(child_processes_inherit, error));
68         EXPECT_FALSE(error.Fail());
69         error = listen_socket_up->Listen(listen_remote_address, 5);
70         EXPECT_FALSE(error.Fail());
71         EXPECT_TRUE(listen_socket_up->IsValid());
72
73         Error accept_error;
74         Socket *accept_socket;
75         std::thread accept_thread(AcceptThread, listen_socket_up.get(), listen_remote_address, child_processes_inherit,
76                                   &accept_socket, &accept_error);
77
78         std::string connect_remote_address = get_connect_addr(*listen_socket_up);
79         std::unique_ptr<SocketType> connect_socket_up(new SocketType(child_processes_inherit, error));
80         EXPECT_FALSE(error.Fail());
81         error = connect_socket_up->Connect(connect_remote_address.c_str());
82         EXPECT_FALSE(error.Fail());
83         EXPECT_TRUE(connect_socket_up->IsValid());
84
85         a_up->swap(connect_socket_up);
86         EXPECT_TRUE(error.Success());
87         EXPECT_NE(nullptr, a_up->get());
88         EXPECT_TRUE((*a_up)->IsValid());
89
90         accept_thread.join();
91         b_up->reset(static_cast<SocketType*>(accept_socket));
92         EXPECT_TRUE(accept_error.Success());
93         EXPECT_NE(nullptr, b_up->get());
94         EXPECT_TRUE((*b_up)->IsValid());
95
96         listen_socket_up.reset();
97     }
98 };
99
100 TEST_F (SocketTest, DecodeHostAndPort)
101 {
102     std::string host_str;
103     std::string port_str;
104     int32_t port;
105     Error error;
106     EXPECT_TRUE (Socket::DecodeHostAndPort ("localhost:1138", host_str, port_str, port, &error));
107     EXPECT_STREQ ("localhost", host_str.c_str ());
108     EXPECT_STREQ ("1138", port_str.c_str ());
109     EXPECT_EQ (1138, port);
110     EXPECT_TRUE (error.Success ());
111     
112     EXPECT_FALSE (Socket::DecodeHostAndPort ("google.com:65536", host_str, port_str, port, &error));
113     EXPECT_TRUE (error.Fail ());
114     EXPECT_STREQ ("invalid host:port specification: 'google.com:65536'", error.AsCString ());
115     
116     EXPECT_FALSE (Socket::DecodeHostAndPort ("google.com:-1138", host_str, port_str, port, &error));
117     EXPECT_TRUE (error.Fail ());
118     EXPECT_STREQ ("invalid host:port specification: 'google.com:-1138'", error.AsCString ());
119
120     EXPECT_FALSE(Socket::DecodeHostAndPort("google.com:65536", host_str, port_str, port, &error));
121     EXPECT_TRUE(error.Fail());
122     EXPECT_STREQ("invalid host:port specification: 'google.com:65536'", error.AsCString());
123
124     EXPECT_TRUE (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 (Socket::DecodeHostAndPort ("*:0", host_str, port_str, port, &error));
131     EXPECT_STREQ ("*", host_str.c_str ());
132     EXPECT_STREQ ("0", port_str.c_str ());
133     EXPECT_EQ (0, port);
134     EXPECT_TRUE (error.Success ());
135
136     EXPECT_TRUE(Socket::DecodeHostAndPort("*:65535", host_str, port_str, port, &error));
137     EXPECT_STREQ("*", host_str.c_str());
138     EXPECT_STREQ("65535", port_str.c_str());
139     EXPECT_EQ(65535, port);
140     EXPECT_TRUE(error.Success());
141 }
142
143 #ifndef LLDB_DISABLE_POSIX
144 TEST_F (SocketTest, DomainListenConnectAccept)
145 {
146     char* file_name_str = tempnam(nullptr, nullptr);
147     EXPECT_NE (nullptr, file_name_str);
148     const std::string file_name(file_name_str);
149     free(file_name_str);
150
151     std::unique_ptr<DomainSocket> socket_a_up;
152     std::unique_ptr<DomainSocket> socket_b_up;
153     CreateConnectedSockets<DomainSocket>(file_name.c_str(),
154                                       [=](const DomainSocket &)
155                                       {
156                                           return file_name;
157                                       },
158                                       &socket_a_up, &socket_b_up);
159 }
160 #endif
161
162 TEST_F (SocketTest, TCPListen0ConnectAccept)
163 {
164     std::unique_ptr<TCPSocket> socket_a_up;
165     std::unique_ptr<TCPSocket> socket_b_up;
166     CreateConnectedSockets<TCPSocket>("127.0.0.1:0",
167                                       [=](const TCPSocket &s)
168                                       {
169                                           char connect_remote_address[64];
170                                           snprintf(connect_remote_address, sizeof(connect_remote_address), "localhost:%u", s.GetLocalPortNumber());
171                                           return std::string(connect_remote_address);
172                                       },
173                                       &socket_a_up, &socket_b_up);
174 }
175
176 TEST_F (SocketTest, TCPGetAddress)
177 {
178     std::unique_ptr<TCPSocket> socket_a_up;
179     std::unique_ptr<TCPSocket> socket_b_up;
180     CreateConnectedSockets<TCPSocket>("127.0.0.1:0",
181                                       [=](const TCPSocket &s)
182                                       {
183                                           char connect_remote_address[64];
184                                           snprintf(connect_remote_address, sizeof(connect_remote_address), "localhost:%u", s.GetLocalPortNumber());
185                                           return std::string(connect_remote_address);
186                                       },
187                                       &socket_a_up,
188                                       &socket_b_up);
189
190     EXPECT_EQ (socket_a_up->GetLocalPortNumber (), socket_b_up->GetRemotePortNumber ());
191     EXPECT_EQ (socket_b_up->GetLocalPortNumber (), socket_a_up->GetRemotePortNumber ());
192     EXPECT_NE (socket_a_up->GetLocalPortNumber (), socket_b_up->GetLocalPortNumber ());
193     EXPECT_STREQ ("127.0.0.1", socket_a_up->GetRemoteIPAddress ().c_str ());
194     EXPECT_STREQ ("127.0.0.1", socket_b_up->GetRemoteIPAddress ().c_str ());
195 }
196
197 TEST_F (SocketTest, UDPConnect)
198 {
199     Socket* socket_a;
200     Socket* socket_b;
201
202     bool child_processes_inherit = false;    
203     auto error = UDPSocket::Connect("127.0.0.1:0", child_processes_inherit, socket_a, socket_b);
204    
205     std::unique_ptr<Socket> a_up(socket_a);
206     std::unique_ptr<Socket> b_up(socket_b);
207
208     EXPECT_TRUE(error.Success ());
209     EXPECT_TRUE(a_up->IsValid());
210     EXPECT_TRUE(b_up->IsValid());
211 }