Mercurial > code
annotate C++/Tests/Sockets/main.cpp @ 293:9b3270513f40
Socket: accept() can also block
author | David Demelier <markand@malikania.fr> |
---|---|
date | Thu, 13 Nov 2014 21:03:12 +0100 |
parents | ea55a3886da0 |
children | 836903141476 |
rev | line source |
---|---|
276 | 1 /* |
2 * main.cpp -- test sockets | |
3 * | |
4 * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr> | |
5 * | |
6 * Permission to use, copy, modify, and/or distribute this software for any | |
7 * purpose with or without fee is hereby granted, provided that the above | |
8 * copyright notice and this permission notice appear in all copies. | |
9 * | |
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
17 */ | |
18 | |
258 | 19 #include <chrono> |
276 | 20 #include <iostream> |
258 | 21 #include <sstream> |
22 #include <string> | |
23 #include <thread> | |
24 | |
25 #include <gtest/gtest.h> | |
26 | |
27 #include <Socket.h> | |
28 #include <SocketListener.h> | |
29 #include <SocketAddress.h> | |
30 | |
31 using namespace std::literals::chrono_literals; | |
32 | |
280 | 33 using namespace error; |
258 | 34 using namespace address; |
35 | |
36 /* -------------------------------------------------------- | |
37 * Miscellaneous | |
38 * -------------------------------------------------------- */ | |
39 | |
40 TEST(Misc, set) | |
41 { | |
276 | 42 Socket s; |
43 | |
258 | 44 try { |
276 | 45 s = { AF_INET6, SOCK_STREAM, 0 }; |
46 | |
47 s.set(IPPROTO_IPV6, IPV6_V6ONLY, 0); | |
48 ASSERT_EQ(0, s.get<int>(IPPROTO_IPV6, IPV6_V6ONLY)); | |
258 | 49 |
276 | 50 s.set(IPPROTO_IPV6, IPV6_V6ONLY, 1); |
51 ASSERT_EQ(1, s.get<int>(IPPROTO_IPV6, IPV6_V6ONLY)); | |
52 } catch (const std::exception &ex) { | |
53 std::cerr << "warning: " << ex.what() << std::endl; | |
54 } | |
258 | 55 |
276 | 56 s.close(); |
258 | 57 } |
58 | |
278
adcae2bde2f0
Socket: listener now have initializer list constructor
David Demelier <markand@malikania.fr>
parents:
277
diff
changeset
|
59 TEST(Misc, initializer) |
adcae2bde2f0
Socket: listener now have initializer list constructor
David Demelier <markand@malikania.fr>
parents:
277
diff
changeset
|
60 { |
adcae2bde2f0
Socket: listener now have initializer list constructor
David Demelier <markand@malikania.fr>
parents:
277
diff
changeset
|
61 Socket s1, s2; |
adcae2bde2f0
Socket: listener now have initializer list constructor
David Demelier <markand@malikania.fr>
parents:
277
diff
changeset
|
62 |
adcae2bde2f0
Socket: listener now have initializer list constructor
David Demelier <markand@malikania.fr>
parents:
277
diff
changeset
|
63 try { |
adcae2bde2f0
Socket: listener now have initializer list constructor
David Demelier <markand@malikania.fr>
parents:
277
diff
changeset
|
64 s1 = { AF_INET6, SOCK_STREAM, 0 }; |
adcae2bde2f0
Socket: listener now have initializer list constructor
David Demelier <markand@malikania.fr>
parents:
277
diff
changeset
|
65 s2 = { AF_INET6, SOCK_STREAM, 0 }; |
adcae2bde2f0
Socket: listener now have initializer list constructor
David Demelier <markand@malikania.fr>
parents:
277
diff
changeset
|
66 |
adcae2bde2f0
Socket: listener now have initializer list constructor
David Demelier <markand@malikania.fr>
parents:
277
diff
changeset
|
67 SocketListener listener { |
adcae2bde2f0
Socket: listener now have initializer list constructor
David Demelier <markand@malikania.fr>
parents:
277
diff
changeset
|
68 { s1, Read }, |
adcae2bde2f0
Socket: listener now have initializer list constructor
David Demelier <markand@malikania.fr>
parents:
277
diff
changeset
|
69 { s2, Read }, |
adcae2bde2f0
Socket: listener now have initializer list constructor
David Demelier <markand@malikania.fr>
parents:
277
diff
changeset
|
70 }; |
adcae2bde2f0
Socket: listener now have initializer list constructor
David Demelier <markand@malikania.fr>
parents:
277
diff
changeset
|
71 |
adcae2bde2f0
Socket: listener now have initializer list constructor
David Demelier <markand@malikania.fr>
parents:
277
diff
changeset
|
72 ASSERT_EQ(2UL, listener.size()); |
adcae2bde2f0
Socket: listener now have initializer list constructor
David Demelier <markand@malikania.fr>
parents:
277
diff
changeset
|
73 |
adcae2bde2f0
Socket: listener now have initializer list constructor
David Demelier <markand@malikania.fr>
parents:
277
diff
changeset
|
74 listener.list([&] (const auto &so, auto direction) { |
adcae2bde2f0
Socket: listener now have initializer list constructor
David Demelier <markand@malikania.fr>
parents:
277
diff
changeset
|
75 ASSERT_TRUE(so == s1 || so == s2); |
adcae2bde2f0
Socket: listener now have initializer list constructor
David Demelier <markand@malikania.fr>
parents:
277
diff
changeset
|
76 ASSERT_EQ(Read, direction); |
adcae2bde2f0
Socket: listener now have initializer list constructor
David Demelier <markand@malikania.fr>
parents:
277
diff
changeset
|
77 }); |
adcae2bde2f0
Socket: listener now have initializer list constructor
David Demelier <markand@malikania.fr>
parents:
277
diff
changeset
|
78 } catch (const std::exception &ex) { |
adcae2bde2f0
Socket: listener now have initializer list constructor
David Demelier <markand@malikania.fr>
parents:
277
diff
changeset
|
79 std::cerr << "warning: " << ex.what() << std::endl; |
adcae2bde2f0
Socket: listener now have initializer list constructor
David Demelier <markand@malikania.fr>
parents:
277
diff
changeset
|
80 } |
adcae2bde2f0
Socket: listener now have initializer list constructor
David Demelier <markand@malikania.fr>
parents:
277
diff
changeset
|
81 |
adcae2bde2f0
Socket: listener now have initializer list constructor
David Demelier <markand@malikania.fr>
parents:
277
diff
changeset
|
82 s1.close(); |
adcae2bde2f0
Socket: listener now have initializer list constructor
David Demelier <markand@malikania.fr>
parents:
277
diff
changeset
|
83 s2.close(); |
adcae2bde2f0
Socket: listener now have initializer list constructor
David Demelier <markand@malikania.fr>
parents:
277
diff
changeset
|
84 } |
adcae2bde2f0
Socket: listener now have initializer list constructor
David Demelier <markand@malikania.fr>
parents:
277
diff
changeset
|
85 |
258 | 86 /* -------------------------------------------------------- |
87 * Select tests | |
88 * -------------------------------------------------------- */ | |
89 | |
280 | 90 TEST(ListenerMethodSelect, timeout) |
91 { | |
92 std::thread server([] () { | |
93 Socket s, client; | |
94 SocketListener listener(Select); | |
95 bool running = true; | |
96 int tries = 0; | |
97 | |
98 try { | |
99 s = { AF_INET, SOCK_STREAM, 0 }; | |
100 s.set(SOL_SOCKET, SO_REUSEADDR, 1); | |
101 s.bind(Internet{"*", 10000, AF_INET}); | |
102 s.listen(10); | |
103 | |
104 listener.add(s, Read); | |
105 | |
106 while (running) { | |
107 try { | |
108 listener.select(500ms); | |
109 client = s.accept(); | |
110 running = false; | |
111 | |
112 // Abort if no client connected | |
113 if (tries >= 10) | |
114 running = false; | |
115 } catch (const Timeout &) { | |
116 } | |
117 } | |
118 } catch (const std::exception &ex) { | |
119 std::cerr << "warning: " << ex.what() << std::endl; | |
120 } | |
121 | |
122 s.close(); | |
123 client.close(); | |
124 }); | |
125 | |
126 std::thread client([] () { | |
127 std::this_thread::sleep_for(2s); | |
128 | |
129 Socket s; | |
130 | |
131 try { | |
132 s = { AF_INET, SOCK_STREAM, 0 }; | |
133 s.connect(Internet{"localhost", 10000, AF_INET}); | |
134 } catch (const std::exception &ex) { | |
135 std::cerr << "warning: " << ex.what() << std::endl; | |
136 } | |
137 | |
138 s.close(); | |
139 }); | |
140 | |
141 server.join(); | |
142 client.join(); | |
143 } | |
144 | |
275 | 145 TEST(ListenerMethodSelect, add) |
258 | 146 { |
276 | 147 Socket s, s2; |
148 | |
258 | 149 try { |
276 | 150 s = { AF_INET, SOCK_STREAM, 0 }; |
151 s2 = { AF_INET, SOCK_STREAM, 0 }; | |
280 | 152 SocketListener listener(Select); |
258 | 153 |
277
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
154 listener.add(s, Read); |
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
155 listener.add(s2, Read); |
258 | 156 |
275 | 157 ASSERT_EQ(2UL, listener.size()); |
258 | 158 } catch (const std::exception &ex) { |
276 | 159 std::cerr << "warning: " << ex.what() << std::endl; |
258 | 160 } |
276 | 161 |
162 s.close(); | |
163 s2.close(); | |
258 | 164 } |
165 | |
275 | 166 TEST(ListenerMethodSelect, remove) |
258 | 167 { |
276 | 168 Socket s, s2; |
169 | |
258 | 170 try { |
276 | 171 s = { AF_INET, SOCK_STREAM, 0 }; |
172 s2 = { AF_INET, SOCK_STREAM, 0 }; | |
280 | 173 SocketListener listener(Select); |
258 | 174 |
277
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
175 listener.add(s, Read); |
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
176 listener.add(s2, Read); |
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
177 listener.remove(s, Read); |
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
178 listener.remove(s2, Read); |
258 | 179 |
275 | 180 ASSERT_EQ(0UL, listener.size()); |
258 | 181 } catch (const std::exception &ex) { |
276 | 182 std::cerr << "warning: " << ex.what() << std::endl; |
258 | 183 } |
276 | 184 |
185 s.close(); | |
186 s2.close(); | |
258 | 187 } |
188 | |
189 /* | |
190 * Add two sockets for both reading and writing, them remove only reading and then | |
191 * move only writing. | |
192 */ | |
275 | 193 TEST(ListenerMethodSelect, inOut) |
258 | 194 { |
276 | 195 Socket s, s2; |
196 | |
258 | 197 try { |
276 | 198 s = { AF_INET, SOCK_STREAM, 0 }; |
199 s2 = { AF_INET, SOCK_STREAM, 0 }; | |
280 | 200 SocketListener listener(Select); |
258 | 201 |
277
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
202 listener.add(s, Read | Write); |
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
203 listener.add(s2, Read | Write); |
258 | 204 |
277
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
205 listener.list([&] (Socket &si, int dir) { |
258 | 206 ASSERT_TRUE(si == s || si == s2); |
207 ASSERT_EQ(0x03, static_cast<int>(dir)); | |
208 }); | |
209 | |
277
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
210 listener.remove(s, Write); |
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
211 listener.remove(s2, Write); |
258 | 212 |
275 | 213 ASSERT_EQ(2UL, listener.size()); |
258 | 214 |
277
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
215 listener.list([&] (Socket &si, int dir) { |
258 | 216 ASSERT_TRUE(si == s || si == s2); |
277
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
217 ASSERT_EQ(Read, dir); |
258 | 218 }); |
219 | |
277
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
220 listener.remove(s, Read); |
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
221 listener.remove(s2, Read); |
258 | 222 |
275 | 223 ASSERT_EQ(0UL, listener.size()); |
224 } catch (const std::exception &ex) { | |
276 | 225 std::cerr << "warning: " << ex.what() << std::endl; |
275 | 226 } |
276 | 227 |
228 s.close(); | |
229 s2.close(); | |
275 | 230 } |
231 | |
232 TEST(ListenerMethodSelect, addSame) | |
233 { | |
276 | 234 Socket s; |
235 | |
275 | 236 try { |
276 | 237 s = { AF_INET, SOCK_STREAM, 0 }; |
280 | 238 SocketListener listener(Select); |
275 | 239 |
277
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
240 listener.add(s, Read); |
275 | 241 ASSERT_EQ(1UL, listener.size()); |
277
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
242 listener.list([&] (const Socket &si, int dir) { |
275 | 243 ASSERT_TRUE(si == s); |
277
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
244 ASSERT_EQ(Read, dir); |
275 | 245 }); |
246 | |
277
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
247 listener.add(s, Write); |
275 | 248 ASSERT_EQ(1UL, listener.size()); |
277
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
249 listener.list([&] (const Socket &si, int dir) { |
275 | 250 ASSERT_TRUE(si == s); |
251 ASSERT_EQ(0x03, static_cast<int>(dir)); | |
252 }); | |
253 | |
254 // Oops, added the same | |
277
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
255 listener.add(s, Read); |
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
256 listener.add(s, Write); |
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
257 listener.add(s, Read | Write); |
275 | 258 |
259 ASSERT_EQ(1UL, listener.size()); | |
277
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
260 listener.list([&] (const Socket &si, int dir) { |
275 | 261 ASSERT_TRUE(si == s); |
262 ASSERT_EQ(0x03, static_cast<int>(dir)); | |
263 }); | |
258 | 264 } catch (const std::exception &ex) { |
276 | 265 std::cerr << "warning: " << ex.what() << std::endl; |
258 | 266 } |
276 | 267 |
268 s.close(); | |
258 | 269 } |
270 | |
271 /* -------------------------------------------------------- | |
272 * Poll tests | |
273 * -------------------------------------------------------- */ | |
274 | |
280 | 275 TEST(ListenerMethodPoll, timeout) |
276 { | |
277 std::thread server([] () { | |
278 Socket s, client; | |
279 SocketListener listener(Poll); | |
280 bool running = true; | |
281 int tries = 0; | |
282 | |
283 try { | |
284 s = { AF_INET, SOCK_STREAM, 0 }; | |
285 s.set(SOL_SOCKET, SO_REUSEADDR, 1); | |
286 s.bind(Internet{"*", 10000, AF_INET}); | |
287 s.listen(10); | |
288 | |
289 listener.add(s, Read); | |
290 | |
291 while (running) { | |
292 try { | |
293 listener.select(500ms); | |
294 client = s.accept(); | |
295 running = false; | |
296 | |
297 // Abort if no client connected | |
298 if (tries >= 10) | |
299 running = false; | |
300 } catch (const Timeout &) { | |
301 } | |
302 } | |
303 } catch (const std::exception &ex) { | |
304 std::cerr << "warning: " << ex.what() << std::endl; | |
305 } | |
306 | |
307 s.close(); | |
308 client.close(); | |
309 }); | |
310 | |
311 std::thread client([] () { | |
312 std::this_thread::sleep_for(2s); | |
313 | |
314 Socket s; | |
315 | |
316 try { | |
317 s = { AF_INET, SOCK_STREAM, 0 }; | |
318 s.connect(Internet{"localhost", 10000, AF_INET}); | |
319 } catch (const std::exception &ex) { | |
320 std::cerr << "warning: " << ex.what() << std::endl; | |
321 } | |
322 | |
323 s.close(); | |
324 }); | |
325 | |
326 server.join(); | |
327 client.join(); | |
328 } | |
329 | |
275 | 330 TEST(ListenerMethodPoll, add) |
258 | 331 { |
276 | 332 Socket s, s2; |
333 | |
258 | 334 try { |
276 | 335 s = { AF_INET, SOCK_STREAM, 0 }; |
336 s2 = { AF_INET, SOCK_STREAM, 0 }; | |
280 | 337 SocketListener listener(Poll); |
258 | 338 |
277
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
339 listener.add(s, Read); |
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
340 listener.add(s2, Read); |
258 | 341 |
275 | 342 ASSERT_EQ(2UL, listener.size()); |
258 | 343 } catch (const std::exception &ex) { |
276 | 344 std::cerr << "warning: " << ex.what() << std::endl; |
258 | 345 } |
276 | 346 |
347 s.close(); | |
348 s2.close(); | |
258 | 349 } |
350 | |
275 | 351 TEST(ListenerMethodPoll, remove) |
258 | 352 { |
276 | 353 Socket s, s2; |
354 | |
258 | 355 try { |
276 | 356 s = { AF_INET, SOCK_STREAM, 0 }; |
357 s2 = { AF_INET, SOCK_STREAM, 0 }; | |
280 | 358 SocketListener listener(Poll); |
258 | 359 |
277
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
360 listener.add(s, Read); |
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
361 listener.add(s2, Read); |
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
362 listener.remove(s, Read); |
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
363 listener.remove(s2, Read); |
258 | 364 |
275 | 365 ASSERT_EQ(0UL, listener.size()); |
258 | 366 } catch (const std::exception &ex) { |
276 | 367 std::cerr << "warning: " << ex.what() << std::endl; |
258 | 368 } |
276 | 369 |
370 s.close(); | |
371 s2.close(); | |
258 | 372 } |
373 | |
275 | 374 TEST(ListenerMethodPoll, inOut) |
258 | 375 { |
276 | 376 Socket s, s2; |
377 | |
258 | 378 try { |
276 | 379 s = { AF_INET, SOCK_STREAM, 0 }; |
380 s2 = { AF_INET, SOCK_STREAM, 0 }; | |
280 | 381 SocketListener listener(Poll); |
258 | 382 |
277
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
383 listener.add(s, Read | Write); |
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
384 listener.add(s2, Read | Write); |
258 | 385 |
277
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
386 listener.list([&] (Socket &si, int dir) { |
258 | 387 ASSERT_TRUE(si == s || si == s2); |
388 ASSERT_EQ(0x03, static_cast<int>(dir)); | |
389 }); | |
390 | |
277
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
391 listener.remove(s, Write); |
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
392 listener.remove(s2, Write); |
258 | 393 |
275 | 394 ASSERT_EQ(2UL, listener.size()); |
258 | 395 |
277
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
396 listener.list([&] (Socket &si, int dir) { |
258 | 397 ASSERT_TRUE(si == s || si == s2); |
277
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
398 ASSERT_EQ(Read, dir); |
258 | 399 }); |
400 | |
277
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
401 listener.remove(s, Read); |
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
402 listener.remove(s2, Read); |
258 | 403 |
275 | 404 ASSERT_EQ(0UL, listener.size()); |
405 } catch (const std::exception &ex) { | |
276 | 406 std::cerr << "warning: " << ex.what() << std::endl; |
275 | 407 } |
276 | 408 |
409 s.close(); | |
410 s2.close(); | |
275 | 411 } |
412 | |
413 TEST(ListenerMethodPoll, addSame) | |
414 { | |
276 | 415 Socket s; |
416 | |
275 | 417 try { |
276 | 418 s = { AF_INET, SOCK_STREAM, 0 }; |
280 | 419 SocketListener listener(Poll); |
275 | 420 |
277
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
421 listener.add(s, Read); |
275 | 422 ASSERT_EQ(1UL, listener.size()); |
277
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
423 listener.list([&] (const Socket &si, int dir) { |
275 | 424 ASSERT_TRUE(si == s); |
277
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
425 ASSERT_EQ(Read, dir); |
275 | 426 }); |
427 | |
277
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
428 listener.add(s, Write); |
275 | 429 ASSERT_EQ(1UL, listener.size()); |
277
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
430 listener.list([&] (const Socket &si, int dir) { |
275 | 431 ASSERT_TRUE(si == s); |
432 ASSERT_EQ(0x03, static_cast<int>(dir)); | |
433 }); | |
434 | |
435 // Oops, added the same | |
277
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
436 listener.add(s, Read); |
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
437 listener.add(s, Write); |
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
438 listener.add(s, Read | Write); |
275 | 439 |
440 ASSERT_EQ(1UL, listener.size()); | |
277
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
441 listener.list([&] (const Socket &si, int dir) { |
275 | 442 ASSERT_TRUE(si == s); |
443 ASSERT_EQ(0x03, static_cast<int>(dir)); | |
444 }); | |
258 | 445 } catch (const std::exception &ex) { |
276 | 446 std::cerr << "warning: " << ex.what() << std::endl; |
258 | 447 } |
276 | 448 |
449 s.close(); | |
258 | 450 } |
451 | |
452 /* -------------------------------------------------------- | |
453 * Socket listener class | |
454 * -------------------------------------------------------- */ | |
455 | |
456 TEST(Listener, connection) | |
457 { | |
276 | 458 std::thread server([] () { |
459 Socket s; | |
460 SocketListener listener; | |
461 | |
462 try { | |
463 s = { AF_INET, SOCK_STREAM, 0 }; | |
464 | |
465 s.set(SOL_SOCKET, SO_REUSEADDR, 1); | |
466 s.bind(Internet{"*", 10000, AF_INET}); | |
467 s.listen(8); | |
468 | |
277
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
469 listener.add(s, Read); |
276 | 470 |
471 auto client = listener.select(10s); | |
472 | |
277
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
473 ASSERT_TRUE(client.direction == Read); |
276 | 474 ASSERT_TRUE(client.socket == s); |
475 } catch (const std::exception &ex) { | |
476 std::cerr << "warning: " << ex.what() << std::endl; | |
477 } | |
478 | |
479 s.close(); | |
480 }); | |
481 | |
258 | 482 std::thread client([] () { |
483 Socket client; | |
484 | |
276 | 485 std::this_thread::sleep_for(500ms); |
258 | 486 |
487 try { | |
276 | 488 client = { AF_INET, SOCK_STREAM, 0 }; |
489 client.connect(Internet{"localhost", 10000, AF_INET}); | |
258 | 490 } catch (const std::exception &ex) { |
276 | 491 std::cerr << "warning: " << ex.what() << std::endl; |
258 | 492 } |
493 | |
494 client.close(); | |
495 }); | |
496 | |
276 | 497 server.join(); |
258 | 498 client.join(); |
499 } | |
500 | |
501 TEST(Listener, connectionAndRead) | |
502 { | |
276 | 503 std::thread server([] () { |
504 Socket s; | |
505 SocketListener listener; | |
506 | |
507 try { | |
508 s = { AF_INET, SOCK_STREAM, 0 }; | |
509 | |
510 s.set(SOL_SOCKET, SO_REUSEADDR, 1); | |
511 s.bind(Internet("*", 10000, AF_INET)); | |
512 s.listen(8); | |
513 | |
514 // Read for master | |
277
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
515 listener.add(s, Read); |
276 | 516 |
517 auto result = listener.select(10s); | |
518 | |
277
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
519 ASSERT_TRUE(result.direction == Read); |
276 | 520 ASSERT_TRUE(result.socket == s); |
521 | |
522 // Wait for client | |
523 auto client = s.accept(); | |
277
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
524 listener.add(client, Read); |
276 | 525 |
526 result = listener.select(10s); | |
527 | |
277
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
528 ASSERT_TRUE(result.direction == Read); |
276 | 529 ASSERT_TRUE(result.socket == client); |
530 | |
531 char data[512]; | |
532 auto nb = client.recv(data, sizeof (data) - 1); | |
533 | |
534 data[nb] = '\0'; | |
535 | |
536 client.close(); | |
537 ASSERT_STREQ("hello world", data); | |
538 } catch (const std::exception &ex) { | |
539 std::cerr << "warning: " << ex.what() << std::endl; | |
540 } | |
541 | |
542 s.close(); | |
543 }); | |
544 | |
545 std::thread client([] () { | |
258 | 546 Socket client; |
547 | |
276 | 548 std::this_thread::sleep_for(500ms); |
258 | 549 |
550 try { | |
551 client = Socket(AF_INET, SOCK_STREAM, 0); | |
552 client.connect(Internet("localhost", 10000, AF_INET)); | |
553 client.send("hello world"); | |
554 } catch (const std::exception &ex) { | |
276 | 555 std::cerr << "warning: " << ex.what() << std::endl; |
258 | 556 } |
557 | |
558 client.close(); | |
559 }); | |
560 | |
276 | 561 server.join(); |
562 client.join(); | |
258 | 563 } |
564 | |
565 TEST(Listener, bigData) | |
566 { | |
276 | 567 std::thread server([] () { |
258 | 568 std::ostringstream out; |
569 | |
570 Socket server; | |
571 SocketListener listener; | |
572 bool finished(false); | |
573 | |
574 try { | |
276 | 575 server = { AF_INET, SOCK_STREAM, 0 }; |
258 | 576 |
276 | 577 server.set(SOL_SOCKET, SO_REUSEADDR, 1); |
578 server.bind(Internet{"*", 10000, AF_INET}); | |
258 | 579 server.listen(10); |
277
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
580 listener.add(server, Read); |
258 | 581 |
582 while (!finished) { | |
583 auto s = listener.select(60s).socket; | |
584 | |
585 if (s == server) { | |
277
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
586 listener.add(s.accept(), Read); |
258 | 587 } else { |
588 char data[512]; | |
589 auto nb = s.recv(data, sizeof (data) - 1); | |
590 | |
591 if (nb == 0) | |
592 finished = true; | |
593 else { | |
594 data[nb] = '\0'; | |
595 out << data; | |
596 } | |
597 } | |
598 } | |
599 | |
275 | 600 ASSERT_EQ(9000002UL, out.str().size()); |
258 | 601 } catch (const std::exception &ex) { |
276 | 602 std::cerr << "warning: " << ex.what() << std::endl; |
258 | 603 } |
604 | |
605 server.close(); | |
276 | 606 }); |
607 | |
608 std::thread client([] () { | |
609 std::string data; | |
610 | |
611 data.reserve(9000000); | |
612 for (int i = 0; i < 9000000; ++i) | |
613 data.push_back('a'); | |
614 | |
615 data.push_back('\r'); | |
616 data.push_back('\n'); | |
617 | |
618 std::this_thread::sleep_for(500ms); | |
619 | |
620 Socket client; | |
621 SocketListener listener; | |
258 | 622 |
276 | 623 try { |
624 client = { AF_INET, SOCK_STREAM, 0 }; | |
625 | |
626 client.connect(Internet{"localhost", 10000, AF_INET}); | |
627 client.blockMode(false); | |
277
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
628 listener.add(client, Write); |
258 | 629 |
276 | 630 while (data.size() > 0) { |
631 auto s = listener.select(30s).socket; | |
632 auto nb = s.send(data.data(), data.size()); | |
633 data.erase(0, nb); | |
634 } | |
635 } catch (const std::exception &ex) { | |
636 std::cerr << "warning: " << ex.what() << std::endl; | |
637 } | |
638 | |
639 client.close(); | |
640 }); | |
641 | |
642 server.join(); | |
643 client.join(); | |
258 | 644 } |
645 | |
646 /* -------------------------------------------------------- | |
270 | 647 * Multiple selection tests |
648 * -------------------------------------------------------- */ | |
649 | |
650 TEST(MultipleSelection, select) | |
651 { | |
652 /* | |
653 * Normally, 3 sockets added for writing should be marked ready immediately | |
654 * as there are no data being currently queued to be sent. | |
655 */ | |
276 | 656 std::thread server([] () { |
657 Socket master; | |
658 | |
270 | 659 try { |
660 SocketListener masterListener, clientListener; | |
276 | 661 master = { AF_INET, SOCK_STREAM, 0 }; |
270 | 662 |
276 | 663 master.set(SOL_SOCKET, SO_REUSEADDR, 1); |
664 master.bind(Internet{"*", 10000, AF_INET}); | |
270 | 665 master.listen(8); |
666 | |
277
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
667 masterListener.add(master, Read); |
270 | 668 |
669 while (clientListener.size() != 3) { | |
277
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
670 masterListener.select(3s); |
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
671 clientListener.add(master.accept(), Write); |
270 | 672 } |
673 | |
674 // Now do the test of writing | |
277
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
675 auto result = clientListener.selectMultiple(3s); |
275 | 676 ASSERT_EQ(3UL, result.size()); |
270 | 677 |
275 | 678 clientListener.list([] (auto s, auto) { |
270 | 679 s.close(); |
680 }); | |
681 } catch (const std::exception &ex) { | |
276 | 682 std::cerr << "warning: " << ex.what() << std::endl; |
270 | 683 } |
276 | 684 |
685 master.close(); | |
270 | 686 }); |
276 | 687 |
688 std::thread client([] () { | |
689 Socket s1, s2, s3; | |
270 | 690 |
276 | 691 try { |
692 s1 = { AF_INET, SOCK_STREAM, 0 }; | |
693 s2 = { AF_INET, SOCK_STREAM, 0 }; | |
694 s3 = { AF_INET, SOCK_STREAM, 0 }; | |
695 | |
277
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
696 std::this_thread::sleep_for(1s); |
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
697 |
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
698 s1.connect(Internet{"localhost", 10000, AF_INET}); |
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
699 s2.connect(Internet{"localhost", 10000, AF_INET}); |
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
700 s3.connect(Internet{"localhost", 10000, AF_INET}); |
276 | 701 } catch (const std::exception &ex) { |
702 std::cerr << "warning: " << ex.what() << std::endl; | |
703 } | |
275 | 704 |
705 s1.close(); | |
706 s2.close(); | |
707 s3.close(); | |
276 | 708 }); |
270 | 709 |
276 | 710 server.join(); |
711 client.join(); | |
270 | 712 } |
713 | |
714 #if defined(SOCKET_LISTENER_HAVE_POLL) | |
715 | |
716 TEST(MultipleSelection, poll) | |
717 { | |
718 /* | |
719 * Normally, 3 sockets added for writing should be marked ready immediately | |
720 * as there are no data being currently queued to be sent. | |
721 */ | |
276 | 722 std::thread server([] () { |
723 Socket master; | |
724 | |
270 | 725 try { |
280 | 726 SocketListener masterListener(Poll), clientListener(Poll); |
276 | 727 master = { AF_INET, SOCK_STREAM, 0 }; |
270 | 728 |
276 | 729 master.set(SOL_SOCKET, SO_REUSEADDR, 1); |
730 master.bind(Internet{"*", 10000, AF_INET}); | |
270 | 731 master.listen(8); |
732 | |
277
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
733 masterListener.add(master, Read); |
270 | 734 |
735 while (clientListener.size() != 3) { | |
277
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
736 masterListener.select(3s); |
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
737 clientListener.add(master.accept(), Write); |
270 | 738 } |
739 | |
740 // Now do the test of writing | |
277
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
741 auto result = clientListener.selectMultiple(3s); |
275 | 742 ASSERT_EQ(3UL, result.size()); |
270 | 743 |
275 | 744 clientListener.list([] (auto s, auto) { |
270 | 745 s.close(); |
746 }); | |
747 } catch (const std::exception &ex) { | |
276 | 748 std::cerr << "warning: " << ex.what() << std::endl; |
270 | 749 } |
276 | 750 |
751 master.close(); | |
270 | 752 }); |
275 | 753 |
276 | 754 std::thread client([] () { |
755 Socket s1, s2, s3; | |
270 | 756 |
276 | 757 try { |
758 s1 = { AF_INET, SOCK_STREAM, 0 }; | |
759 s2 = { AF_INET, SOCK_STREAM, 0 }; | |
760 s3 = { AF_INET, SOCK_STREAM, 0 }; | |
761 | |
277
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
762 std::this_thread::sleep_for(1s); |
b544a599e08e
Socket: remove enum class
David Demelier <markand@malikania.fr>
parents:
276
diff
changeset
|
763 |
276 | 764 s1.connect(Internet("localhost", 10000, AF_INET)); |
765 s2.connect(Internet("localhost", 10000, AF_INET)); | |
766 s3.connect(Internet("localhost", 10000, AF_INET)); | |
767 } catch (const std::exception &ex) { | |
768 std::cerr << "warning: " << ex.what() << std::endl; | |
769 } | |
275 | 770 |
771 s1.close(); | |
772 s2.close(); | |
773 s3.close(); | |
276 | 774 }); |
270 | 775 |
276 | 776 server.join(); |
777 client.join(); | |
270 | 778 } |
779 | |
780 #endif | |
781 | |
782 /* -------------------------------------------------------- | |
258 | 783 * Basic TCP tests |
784 * -------------------------------------------------------- */ | |
785 | |
786 TEST(BasicTcp, sendipv4) { | |
276 | 787 std::thread server([] () { |
788 Socket server, client; | |
789 | |
790 try { | |
791 server = { AF_INET, SOCK_STREAM, 0 }; | |
792 | |
793 server.set(SOL_SOCKET, SO_REUSEADDR, 1); | |
794 server.bind(Internet{"*", 10000, AF_INET}); | |
795 server.listen(8); | |
796 | |
797 client = server.accept(); | |
798 | |
799 char data[512]; | |
800 auto nb = client.recv(data, sizeof (data) - 1); | |
801 | |
802 data[nb] = '\0'; | |
803 | |
804 ASSERT_STREQ("hello", data); | |
805 } catch (const std::exception &ex) { | |
806 std::cerr << "warning: " << ex.what() << std::endl; | |
807 } | |
808 | |
809 server.close(); | |
810 client.close(); | |
811 }); | |
812 | |
258 | 813 std::thread client([] () { |
814 Socket s; | |
815 | |
276 | 816 std::this_thread::sleep_for(500ms); |
258 | 817 try { |
276 | 818 s = { AF_INET, SOCK_STREAM, 0 }; |
258 | 819 |
276 | 820 s.connect(Internet{"localhost", 10000, AF_INET}); |
258 | 821 s.send("hello"); |
822 } catch (const std::exception &ex) { | |
276 | 823 std::cerr << "warning: " << ex.what() << std::endl; |
258 | 824 } |
825 | |
826 s.close(); | |
827 }); | |
828 | |
276 | 829 server.join(); |
258 | 830 client.join(); |
831 } | |
832 | |
833 TEST(BasicTcp, sendipv6) { | |
276 | 834 std::thread server([] () { |
835 Socket server, client; | |
836 | |
837 try { | |
838 server = { AF_INET6, SOCK_STREAM, 0 }; | |
839 | |
840 server.set(SOL_SOCKET, SO_REUSEADDR, 1); | |
841 server.bind(Internet("*", 10000, AF_INET6)); | |
842 server.listen(8); | |
843 | |
844 client = server.accept(); | |
845 | |
846 char data[512]; | |
847 auto nb = client.recv(data, sizeof (data) - 1); | |
848 | |
849 data[nb] = '\0'; | |
850 | |
851 ASSERT_STREQ("hello", data); | |
852 } catch (const std::exception &ex) { | |
853 std::cerr << "warning: " << ex.what() << std::endl; | |
854 } | |
855 | |
856 server.close(); | |
857 client.close(); | |
858 }); | |
859 | |
258 | 860 std::thread client([] () { |
861 Socket s; | |
862 | |
276 | 863 std::this_thread::sleep_for(500ms); |
258 | 864 try { |
276 | 865 s = { AF_INET6, SOCK_STREAM, 0 }; |
258 | 866 |
276 | 867 s.connect(Internet{"ip6-localhost", 10000, AF_INET6}); |
258 | 868 s.send("hello"); |
869 } catch (const std::exception &ex) { | |
276 | 870 std::cerr << "warning: " << ex.what() << std::endl; |
258 | 871 } |
872 | |
873 s.close(); | |
874 }); | |
875 | |
276 | 876 server.join(); |
258 | 877 client.join(); |
878 } | |
879 | |
880 #if !defined(_WIN32) | |
881 | |
882 TEST(BasicTcp, sendunix) { | |
276 | 883 std::thread server([] () { |
884 Socket server, client; | |
885 | |
886 try { | |
887 server = { AF_UNIX, SOCK_STREAM, 0 }; | |
888 | |
889 server.set(SOL_SOCKET, SO_REUSEADDR, 1); | |
890 server.bind(Unix("/tmp/gtest-send-tcp-unix.sock", true)); | |
891 server.listen(8); | |
892 | |
893 client = server.accept(); | |
894 | |
895 char data[512]; | |
896 auto nb = client.recv(data, sizeof (data) - 1); | |
897 | |
898 data[nb] = '\0'; | |
899 | |
900 ASSERT_STREQ("hello", data); | |
901 } catch (const std::exception &ex) { | |
902 std::cerr << "warning: " << ex.what() << std::endl; | |
903 } | |
904 | |
905 server.close(); | |
906 client.close(); | |
907 }); | |
908 | |
258 | 909 std::thread client([] () { |
910 Socket s; | |
911 | |
276 | 912 std::this_thread::sleep_for(500ms); |
258 | 913 try { |
276 | 914 s = { AF_UNIX, SOCK_STREAM, 0 }; |
258 | 915 |
276 | 916 s.connect(Unix{"/tmp/gtest-send-tcp-unix.sock"}); |
258 | 917 s.send("hello"); |
918 } catch (const std::exception &ex) { | |
276 | 919 std::cerr << "warning: " << ex.what() << std::endl; |
258 | 920 } |
921 | |
922 s.close(); | |
923 }); | |
924 | |
276 | 925 server.join(); |
258 | 926 client.join(); |
927 } | |
928 | |
929 #endif | |
930 | |
276 | 931 /* -------------------------------------------------------- |
932 * Basic UDP tests | |
933 * -------------------------------------------------------- */ | |
934 | |
258 | 935 TEST(BasicUdp, sendipv4) { |
276 | 936 std::thread server([] () { |
937 Socket server; | |
938 | |
939 try { | |
940 server = { AF_INET, SOCK_DGRAM, 0 }; | |
941 | |
942 server.set(SOL_SOCKET, SO_REUSEADDR, 1); | |
943 server.bind(Internet("*", 10000, AF_INET)); | |
944 | |
945 char data[512]; | |
946 auto nb = server.recvfrom(data, sizeof (data) - 1); | |
947 | |
948 data[nb] = '\0'; | |
949 | |
950 ASSERT_STREQ("hello", data); | |
951 } catch (const std::exception &ex) { | |
952 std::cerr << "warning: " << ex.what() << std::endl; | |
953 } | |
954 | |
955 server.close(); | |
956 }); | |
957 | |
258 | 958 std::thread client([] () { |
959 Socket s; | |
960 | |
276 | 961 std::this_thread::sleep_for(500ms); |
258 | 962 try { |
276 | 963 s = { AF_INET, SOCK_DGRAM, 0 }; |
258 | 964 |
276 | 965 s.sendto("hello", Internet{"localhost", 10000, AF_INET}); |
258 | 966 } catch (const std::exception &ex) { |
276 | 967 std::cerr << "warning: " << ex.what() << std::endl; |
258 | 968 } |
969 | |
970 s.close(); | |
971 }); | |
972 | |
276 | 973 server.join(); |
258 | 974 client.join(); |
975 } | |
976 | |
977 TEST(BasicUdp, sendipv6) { | |
276 | 978 std::thread server([] () { |
979 Socket server; | |
980 | |
981 try { | |
982 server = { AF_INET6, SOCK_DGRAM, 0 }; | |
983 | |
984 server.set(SOL_SOCKET, SO_REUSEADDR, 1); | |
985 server.set(IPPROTO_IPV6, IPV6_V6ONLY, 1); | |
986 server.bind(Internet{"*", 10000, AF_INET6}); | |
987 | |
988 char data[512]; | |
989 auto nb = server.recvfrom(data, sizeof (data) - 1); | |
990 | |
991 data[nb] = '\0'; | |
992 | |
993 ASSERT_STREQ("hello", data); | |
994 } catch (const std::exception &ex) { | |
995 std::cerr << "warning: " << ex.what() << std::endl; | |
996 } | |
997 | |
998 server.close(); | |
999 }); | |
1000 | |
258 | 1001 std::thread client([] () { |
1002 Socket s; | |
1003 | |
276 | 1004 std::this_thread::sleep_for(500ms); |
258 | 1005 try { |
276 | 1006 s = { AF_INET6, SOCK_DGRAM, 0 }; |
258 | 1007 |
276 | 1008 s.sendto("hello", Internet{"ip6-localhost", 10000, AF_INET6}); |
258 | 1009 } catch (const std::exception &ex) { |
276 | 1010 std::cerr << "warning: " << ex.what() << std::endl; |
258 | 1011 } |
1012 | |
1013 s.close(); | |
1014 }); | |
1015 | |
276 | 1016 server.join(); |
258 | 1017 client.join(); |
1018 } | |
1019 | |
1020 #if !defined(_WIN32) | |
1021 | |
1022 TEST(BasicUdp, sendunix) { | |
276 | 1023 std::thread server([] () { |
1024 Socket server; | |
1025 | |
1026 try { | |
1027 server = { AF_UNIX, SOCK_DGRAM, 0 }; | |
1028 | |
1029 server.set(SOL_SOCKET, SO_REUSEADDR, 1); | |
1030 server.bind(Unix{"/tmp/gtest-send-udp-unix.sock", true}); | |
1031 | |
1032 char data[512]; | |
1033 auto nb = server.recvfrom(data, sizeof (data) - 1); | |
1034 | |
1035 data[nb] = '\0'; | |
1036 | |
1037 ASSERT_STREQ("hello", data); | |
1038 } catch (const std::exception &ex) { | |
1039 std::cerr << "warning: " << ex.what() << std::endl; | |
1040 } | |
1041 | |
1042 server.close(); | |
1043 }); | |
1044 | |
258 | 1045 std::thread client([] () { |
1046 Socket s; | |
1047 | |
276 | 1048 std::this_thread::sleep_for(500ms); |
258 | 1049 try { |
276 | 1050 s = { AF_UNIX, SOCK_DGRAM, 0 }; |
258 | 1051 |
276 | 1052 s.sendto("hello", Unix{"/tmp/gtest-send-udp-unix.sock"}); |
258 | 1053 } catch (const std::exception &ex) { |
276 | 1054 std::cerr << "warning: " << ex.what() << std::endl; |
258 | 1055 } |
1056 | |
1057 s.close(); | |
1058 }); | |
1059 | |
276 | 1060 server.join(); |
258 | 1061 client.join(); |
1062 } | |
1063 | |
1064 #endif | |
1065 | |
1066 int main(int argc, char **argv) | |
1067 { | |
1068 Socket::init(); | |
260 | 1069 |
258 | 1070 testing::InitGoogleTest(&argc, argv); |
260 | 1071 |
1072 auto ret = RUN_ALL_TESTS(); | |
1073 | |
258 | 1074 Socket::finish(); |
1075 | |
260 | 1076 return ret; |
258 | 1077 } |