1//
2// SocketTest.cpp
3//
4// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
5// and Contributors.
6//
7// SPDX-License-Identifier: BSL-1.0
8//
9
10
11#include "SocketTest.h"
12#include "Poco/CppUnit/TestCaller.h"
13#include "Poco/CppUnit/TestSuite.h"
14#include "EchoServer.h"
15#include "Poco/Net/StreamSocket.h"
16#include "Poco/Net/ServerSocket.h"
17#include "Poco/Net/SocketAddress.h"
18#include "Poco/Net/NetException.h"
19#include "Poco/Timespan.h"
20#include "Poco/Stopwatch.h"
21#include "Poco/Buffer.h"
22#include "Poco/FIFOBuffer.h"
23#include "Poco/Delegate.h"
24#include "Poco/File.h"
25#include <iostream>
26
27
28using Poco::Net::Socket;
29using Poco::Net::StreamSocket;
30using Poco::Net::ServerSocket;
31using Poco::Net::SocketAddress;
32using Poco::Net::ConnectionRefusedException;
33using Poco::Timespan;
34using Poco::Stopwatch;
35using Poco::TimeoutException;
36using Poco::InvalidArgumentException;
37using Poco::Buffer;
38using Poco::FIFOBuffer;
39using Poco::delegate;
40
41
42SocketTest::SocketTest(const std::string& name): CppUnit::TestCase(name)
43{
44}
45
46
47SocketTest::~SocketTest()
48{
49}
50
51
52void SocketTest::testEcho()
53{
54 EchoServer echoServer;
55 StreamSocket ss;
56 ss.connect(SocketAddress("127.0.0.1", echoServer.port()));
57 int n = ss.sendBytes("hello", 5);
58 assertTrue (n == 5);
59 char buffer[256];
60 n = ss.receiveBytes(buffer, sizeof(buffer));
61 assertTrue (n == 5);
62 assertTrue (std::string(buffer, n) == "hello");
63 ss.close();
64}
65
66
67void SocketTest::testPoll()
68{
69 EchoServer echoServer;
70 StreamSocket ss;
71 ss.connect(SocketAddress("127.0.0.1", echoServer.port()));
72 Stopwatch sw;
73 sw.start();
74 Timespan timeout(1000000);
75 assertTrue (!ss.poll(timeout, Socket::SELECT_READ));
76 assertTrue (sw.elapsed() >= 900000);
77 sw.restart();
78 assertTrue (ss.poll(timeout, Socket::SELECT_WRITE));
79 assertTrue (sw.elapsed() < 100000);
80 ss.sendBytes("hello", 5);
81 char buffer[256];
82 sw.restart();
83 assertTrue (ss.poll(timeout, Socket::SELECT_READ));
84 assertTrue (sw.elapsed() < 100000);
85 int n = ss.receiveBytes(buffer, sizeof(buffer));
86 assertTrue (n == 5);
87 assertTrue (std::string(buffer, n) == "hello");
88 ss.close();
89}
90
91
92void SocketTest::testAvailable()
93{
94 EchoServer echoServer;
95 StreamSocket ss;
96 ss.connect(SocketAddress("127.0.0.1", echoServer.port()));
97 Timespan timeout(1000000);
98 ss.sendBytes("hello", 5);
99 char buffer[256];
100 assertTrue (ss.poll(timeout, Socket::SELECT_READ));
101 int av = ss.available();
102 assertTrue (av > 0 && av <= 5);
103 int n = ss.receiveBytes(buffer, sizeof(buffer));
104 assertTrue (n == 5);
105 assertTrue (std::string(buffer, n) == "hello");
106 ss.close();
107}
108
109
110void SocketTest::testFIFOBuffer()
111{
112 Buffer<char> b(5);
113 b[0] = 'h';
114 b[1] = 'e';
115 b[2] = 'l';
116 b[3] = 'l';
117 b[4] = 'o';
118
119 FIFOBuffer f(5, true);
120
121 f.readable += delegate(this, &SocketTest::onReadable);
122 f.writable += delegate(this, &SocketTest::onWritable);
123
124 assertTrue (0 == _notToReadable);
125 assertTrue (0 == _readableToNot);
126 assertTrue (0 == _notToWritable);
127 assertTrue (0 == _writableToNot);
128 f.write(b);
129 assertTrue (1 == _notToReadable);
130 assertTrue (0 == _readableToNot);
131 assertTrue (0 == _notToWritable);
132 assertTrue (1 == _writableToNot);
133
134 EchoServer echoServer;
135 StreamSocket ss;
136 ss.connect(SocketAddress("127.0.0.1", echoServer.port()));
137 int n = ss.sendBytes(f);
138 assertTrue (n == 5);
139 assertTrue (1 == _notToReadable);
140 assertTrue (1 == _readableToNot);
141 assertTrue (1 == _notToWritable);
142 assertTrue (1 == _writableToNot);
143 assertTrue (f.isEmpty());
144
145 n = ss.receiveBytes(f);
146 assertTrue (n == 5);
147
148 assertTrue (2 == _notToReadable);
149 assertTrue (1 == _readableToNot);
150 assertTrue (1 == _notToWritable);
151 assertTrue (2 == _writableToNot);
152
153 assertTrue (f[0] == 'h');
154 assertTrue (f[1] == 'e');
155 assertTrue (f[2] == 'l');
156 assertTrue (f[3] == 'l');
157 assertTrue (f[4] == 'o');
158
159 f.readable -= delegate(this, &SocketTest::onReadable);
160 f.writable -= delegate(this, &SocketTest::onWritable);
161
162 ss.close();
163}
164
165
166void SocketTest::testConnect()
167{
168 ServerSocket serv;
169 serv.bind(SocketAddress());
170 serv.listen();
171 StreamSocket ss;
172 Timespan timeout(250000);
173 ss.connect(SocketAddress("127.0.0.1", serv.address().port()), timeout);
174}
175
176
177void SocketTest::testConnectRefused()
178{
179 ServerSocket serv;
180 serv.bind(SocketAddress());
181 serv.listen();
182 Poco::UInt16 port = serv.address().port();
183 serv.close();
184 StreamSocket ss;
185 Timespan timeout(250000);
186 try
187 {
188 ss.connect(SocketAddress("127.0.0.1", port));
189 fail("connection refused - must throw");
190 }
191 catch (ConnectionRefusedException&)
192 {
193 }
194}
195
196
197void SocketTest::testConnectRefusedNB()
198{
199 ServerSocket serv;
200 serv.bind(SocketAddress());
201 serv.listen();
202 Poco::UInt16 port = serv.address().port();
203 serv.close();
204 StreamSocket ss;
205 Timespan timeout(2, 0);
206 try
207 {
208 ss.connect(SocketAddress("127.0.0.1", port), timeout);
209 fail("connection refused - must throw");
210 }
211 catch (TimeoutException&)
212 {
213 }
214 catch (ConnectionRefusedException&)
215 {
216 }
217}
218
219
220void SocketTest::testNonBlocking()
221{
222 EchoServer echoServer;
223 StreamSocket ss;
224 ss.connect(SocketAddress("127.0.0.1", echoServer.port()));
225 ss.setBlocking(false);
226
227 Timespan timeout(1000000);
228 assertTrue (ss.poll(timeout, Socket::SELECT_WRITE));
229 int n = ss.sendBytes("hello", 5);
230 assertTrue (n == 5);
231
232 char buffer[256];
233 assertTrue (ss.poll(timeout, Socket::SELECT_READ));
234 n = ss.receiveBytes(buffer, sizeof(buffer));
235 assertTrue (n == 5);
236 assertTrue (std::string(buffer, n) == "hello");
237 ss.close();
238}
239
240
241
242void SocketTest::testAddress()
243{
244 ServerSocket serv;
245 serv.bind(SocketAddress());
246 serv.listen();
247 StreamSocket ss;
248 ss.connect(SocketAddress("127.0.0.1", serv.address().port()));
249 StreamSocket css = serv.acceptConnection();
250 assertTrue (css.peerAddress().host() == ss.address().host());
251 assertTrue (css.peerAddress().port() == ss.address().port());
252}
253
254
255void SocketTest::testAssign()
256{
257 ServerSocket serv;
258 StreamSocket ss1;
259 StreamSocket ss2;
260
261 assertTrue (ss1 != ss2);
262 StreamSocket ss3(ss1);
263 assertTrue (ss1 == ss3);
264 ss3 = ss2;
265 assertTrue (ss1 != ss3);
266 assertTrue (ss2 == ss3);
267
268 try
269 {
270 ss1 = serv;
271 fail("incompatible assignment - must throw");
272 }
273 catch (InvalidArgumentException&)
274 {
275 }
276
277 try
278 {
279 StreamSocket ss4(serv);
280 fail("incompatible assignment - must throw");
281 }
282 catch (InvalidArgumentException&)
283 {
284 }
285
286 try
287 {
288 serv = ss1;
289 fail("incompatible assignment - must throw");
290 }
291 catch (InvalidArgumentException&)
292 {
293 }
294
295 try
296 {
297 ServerSocket serv2(ss1);
298 fail("incompatible assignment - must throw");
299 }
300 catch (InvalidArgumentException&)
301 {
302 }
303}
304
305
306void SocketTest::testTimeout()
307{
308 EchoServer echoServer;
309 StreamSocket ss;
310 ss.connect(SocketAddress("127.0.0.1", echoServer.port()));
311
312 Timespan timeout0 = ss.getReceiveTimeout();
313 Timespan timeout(250000);
314 ss.setReceiveTimeout(timeout);
315 Timespan timeout1 = ss.getReceiveTimeout();
316 std::cout << "original receive timeout: " << timeout0.totalMicroseconds() << std::endl;
317 std::cout << "requested receive timeout: " << timeout.totalMicroseconds() << std::endl;
318 std::cout << "actual receive timeout: " << timeout1.totalMicroseconds() << std::endl;
319
320 // some socket implementations adjust the timeout value
321 // assertTrue (ss.getReceiveTimeout() == timeout);
322 Stopwatch sw;
323 try
324 {
325 char buffer[256];
326 sw.start();
327 ss.receiveBytes(buffer, sizeof(buffer));
328 fail("nothing to receive - must timeout");
329 }
330 catch (TimeoutException&)
331 {
332 }
333 assertTrue (sw.elapsed() < 1000000);
334
335 timeout0 = ss.getSendTimeout();
336 ss.setSendTimeout(timeout);
337 timeout1 = ss.getSendTimeout();
338 std::cout << "original send timeout: " << timeout0.totalMicroseconds() << std::endl;
339 std::cout << "requested send timeout: " << timeout.totalMicroseconds() << std::endl;
340 std::cout << "actual send timeout: " << timeout1.totalMicroseconds() << std::endl;
341 // assertTrue (ss.getSendTimeout() == timeout);
342}
343
344
345void SocketTest::testBufferSize()
346{
347 EchoServer echoServer;
348 SocketAddress sa("127.0.0.1", 1234);
349 StreamSocket ss(sa.family());
350
351 int osz = ss.getSendBufferSize();
352 int rsz = 32000;
353 ss.setSendBufferSize(rsz);
354 int asz = ss.getSendBufferSize();
355 std::cout << "original send buffer size: " << osz << std::endl;
356 std::cout << "requested send buffer size: " << rsz << std::endl;
357 std::cout << "actual send buffer size: " << asz << std::endl;
358
359 osz = ss.getReceiveBufferSize();
360 ss.setReceiveBufferSize(rsz);
361 asz = ss.getReceiveBufferSize();
362 std::cout << "original recv buffer size: " << osz << std::endl;
363 std::cout << "requested recv buffer size: " << rsz << std::endl;
364 std::cout << "actual recv buffer size: " << asz << std::endl;
365}
366
367
368void SocketTest::testOptions()
369{
370 EchoServer echoServer;
371 StreamSocket ss;
372 ss.connect(SocketAddress("127.0.0.1", echoServer.port()));
373
374 ss.setLinger(true, 20);
375 bool f;
376 int t;
377 ss.getLinger(f, t);
378 assertTrue (f && t == 20);
379 ss.setLinger(false, 0);
380 ss.getLinger(f, t);
381 assertTrue (!f);
382
383 ss.setNoDelay(true);
384 assertTrue (ss.getNoDelay());
385 ss.setNoDelay(false);
386 assertTrue (!ss.getNoDelay());
387
388 ss.setKeepAlive(true);
389 assertTrue (ss.getKeepAlive());
390 ss.setKeepAlive(false);
391 assertTrue (!ss.getKeepAlive());
392
393 ss.setOOBInline(true);
394 assertTrue (ss.getOOBInline());
395 ss.setOOBInline(false);
396 assertTrue (!ss.getOOBInline());
397}
398
399
400void SocketTest::testSelect()
401{
402 Timespan timeout(250000);
403
404 EchoServer echoServer;
405 StreamSocket ss;
406 ss.connect(SocketAddress("127.0.0.1", echoServer.port()));
407
408 Socket::SocketList readList;
409 Socket::SocketList writeList;
410 Socket::SocketList exceptList;
411
412 readList.push_back(ss);
413 assertTrue (Socket::select(readList, writeList, exceptList, timeout) == 0);
414 assertTrue (readList.empty());
415 assertTrue (writeList.empty());
416 assertTrue (exceptList.empty());
417
418 ss.sendBytes("hello", 5);
419
420 ss.poll(timeout, Socket::SELECT_READ);
421
422 readList.push_back(ss);
423 writeList.push_back(ss);
424 assertTrue (Socket::select(readList, writeList, exceptList, timeout) == 2);
425 assertTrue (!readList.empty());
426 assertTrue (!writeList.empty());
427 assertTrue (exceptList.empty());
428
429 char buffer[256];
430 int n = ss.receiveBytes(buffer, sizeof(buffer));
431 assertTrue (n == 5);
432 assertTrue (std::string(buffer, n) == "hello");
433 ss.close();
434}
435
436
437void SocketTest::testSelect2()
438{
439 Timespan timeout(100000);
440
441 EchoServer echoServer1;
442 EchoServer echoServer2;
443 StreamSocket ss1(SocketAddress("127.0.0.1", echoServer1.port()));
444 StreamSocket ss2(SocketAddress("127.0.0.1", echoServer2.port()));
445
446 Socket::SocketList readList;
447 Socket::SocketList writeList;
448 Socket::SocketList exceptList;
449
450 readList.push_back(ss1);
451 readList.push_back(ss2);
452 assertTrue (Socket::select(readList, writeList, exceptList, timeout) == 0);
453 assertTrue (readList.empty());
454 assertTrue (writeList.empty());
455 assertTrue (exceptList.empty());
456
457 ss1.sendBytes("hello", 5);
458
459 ss1.poll(timeout, Socket::SELECT_READ);
460
461 readList.push_back(ss1);
462 readList.push_back(ss2);
463 assertTrue (Socket::select(readList, writeList, exceptList, timeout) == 1);
464
465 assertTrue (readList.size() == 1);
466 assertTrue (readList[0] == ss1);
467 assertTrue (writeList.empty());
468 assertTrue (exceptList.empty());
469
470 char buffer[256];
471 int n = ss1.receiveBytes(buffer, sizeof(buffer));
472 assertTrue (n == 5);
473
474 readList.clear();
475 writeList.clear();
476 exceptList.clear();
477 writeList.push_back(ss1);
478 writeList.push_back(ss2);
479 assertTrue (Socket::select(readList, writeList, exceptList, timeout) == 2);
480 assertTrue (readList.empty());
481 assertTrue (writeList.size() == 2);
482 assertTrue (writeList[0] == ss1);
483 assertTrue (writeList[1] == ss2);
484 assertTrue (exceptList.empty());
485
486 ss1.close();
487 ss2.close();
488}
489
490
491void SocketTest::testSelect3()
492{
493 Socket::SocketList readList;
494 Socket::SocketList writeList;
495 Socket::SocketList exceptList;
496 Timespan timeout(1000);
497
498 int rc = Socket::select(readList, writeList, exceptList, timeout);
499 assertTrue (rc == 0);
500}
501
502
503void SocketTest::testEchoUnixLocal()
504{
505#if defined(POCO_OS_FAMILY_UNIX)
506#if POCO_OS == POCO_OS_ANDROID
507 Poco::File socketFile("/data/local/tmp/SocketTest.sock");
508#else
509 Poco::File socketFile("/tmp/SocketTest.sock");
510#endif
511 if (socketFile.exists()) socketFile.remove();
512 SocketAddress localAddr(SocketAddress::UNIX_LOCAL, socketFile.path());
513 EchoServer echoServer(localAddr);
514 StreamSocket ss(SocketAddress::UNIX_LOCAL);
515 ss.connect(localAddr);
516 int n = ss.sendBytes("hello", 5);
517 assertTrue (n == 5);
518 char buffer[256];
519 n = ss.receiveBytes(buffer, sizeof(buffer));
520 assertTrue (n == 5);
521 assertTrue (std::string(buffer, n) == "hello");
522 ss.close();
523 socketFile.remove();
524#endif
525}
526
527void SocketTest::testEchoLinuxAbstract()
528{
529#if POCO_OS == POCO_OS_LINUX || POCO_OS == POCO_OS_ANDROID
530 std::string path("sock.pocoproject.org");
531 path.insert(0, 1, '\0');
532 SocketAddress localAddr(SocketAddress::UNIX_LOCAL, path);
533 EchoServer echoServer(localAddr);
534 StreamSocket ss(SocketAddress::UNIX_LOCAL);
535 ss.connect(localAddr);
536 int n = ss.sendBytes("hello", 5);
537 assertTrue(n == 5);
538 char buffer[256];
539 n = ss.receiveBytes(buffer, sizeof(buffer));
540 assertTrue(n == 5);
541 assertTrue(std::string(buffer, n) == "hello");
542 ss.close();
543#endif
544}
545
546void SocketTest::onReadable(bool& b)
547{
548 if (b) ++_notToReadable;
549 else ++_readableToNot;
550};
551
552
553void SocketTest::onWritable(bool& b)
554{
555 if (b) ++_notToWritable;
556 else ++_writableToNot;
557}
558
559
560void SocketTest::setUp()
561{
562 _readableToNot = 0;
563 _notToReadable = 0;
564 _writableToNot = 0;
565 _notToWritable = 0;
566}
567
568
569void SocketTest::tearDown()
570{
571}
572
573
574CppUnit::Test* SocketTest::suite()
575{
576 CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("SocketTest");
577
578 CppUnit_addTest(pSuite, SocketTest, testEcho);
579 CppUnit_addTest(pSuite, SocketTest, testPoll);
580 CppUnit_addTest(pSuite, SocketTest, testAvailable);
581 CppUnit_addTest(pSuite, SocketTest, testFIFOBuffer);
582 CppUnit_addTest(pSuite, SocketTest, testConnect);
583 CppUnit_addTest(pSuite, SocketTest, testConnectRefused);
584 CppUnit_addTest(pSuite, SocketTest, testConnectRefusedNB);
585 CppUnit_addTest(pSuite, SocketTest, testNonBlocking);
586 CppUnit_addTest(pSuite, SocketTest, testAddress);
587 CppUnit_addTest(pSuite, SocketTest, testAssign);
588 CppUnit_addTest(pSuite, SocketTest, testTimeout);
589 CppUnit_addTest(pSuite, SocketTest, testBufferSize);
590 CppUnit_addTest(pSuite, SocketTest, testOptions);
591 CppUnit_addTest(pSuite, SocketTest, testSelect);
592 CppUnit_addTest(pSuite, SocketTest, testSelect2);
593 CppUnit_addTest(pSuite, SocketTest, testSelect3);
594 CppUnit_addTest(pSuite, SocketTest, testEchoUnixLocal);
595 CppUnit_addTest(pSuite, SocketTest, testEchoLinuxAbstract);
596
597 return pSuite;
598}
599