Skip to content

Commit 2abc0c3

Browse files
committed
test: add Sock unit tests
1 parent e82e609 commit 2abc0c3

File tree

2 files changed

+151
-0
lines changed

2 files changed

+151
-0
lines changed

Diff for: src/Makefile.test.include

+1
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ BITCOIN_TESTS =\
114114
test/sighash_tests.cpp \
115115
test/sigopcount_tests.cpp \
116116
test/skiplist_tests.cpp \
117+
test/sock_tests.cpp \
117118
test/streams_tests.cpp \
118119
test/sync_tests.cpp \
119120
test/system_tests.cpp \

Diff for: src/test/sock_tests.cpp

+150
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
// Copyright (c) 2021-2021 The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#include <compat.h>
6+
#include <test/util/setup_common.h>
7+
#include <util/sock.h>
8+
#include <util/system.h>
9+
10+
#include <boost/test/unit_test.hpp>
11+
12+
#include <thread>
13+
14+
using namespace std::chrono_literals;
15+
16+
BOOST_FIXTURE_TEST_SUITE(sock_tests, BasicTestingSetup)
17+
18+
static bool SocketIsClosed(const SOCKET& s)
19+
{
20+
// Notice that if another thread is running and creates its own socket after `s` has been
21+
// closed, it may get assigned the same file descriptor number. In this case our test will
22+
// wronly pretend that the socket is not closed.
23+
int type;
24+
socklen_t len = sizeof(type);
25+
return getsockopt(s, SOL_SOCKET, SO_TYPE, (sockopt_arg_type)&type, &len) == -1 &&
26+
(errno == EBADF || errno == ENOTSOCK);
27+
}
28+
29+
static SOCKET CreateSocket()
30+
{
31+
const int s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
32+
BOOST_REQUIRE(s != -1);
33+
return static_cast<SOCKET>(s);
34+
}
35+
36+
BOOST_AUTO_TEST_CASE(constructor_and_destructor)
37+
{
38+
const SOCKET s = CreateSocket();
39+
Sock* sock = new Sock(s);
40+
BOOST_CHECK_EQUAL(sock->Get(), s);
41+
BOOST_CHECK(!SocketIsClosed(s));
42+
delete sock;
43+
BOOST_CHECK(SocketIsClosed(s));
44+
}
45+
46+
BOOST_AUTO_TEST_CASE(move_constructor)
47+
{
48+
const SOCKET s = CreateSocket();
49+
Sock* sock1 = new Sock(s);
50+
Sock* sock2 = new Sock(std::move(*sock1));
51+
delete sock1;
52+
BOOST_CHECK(!SocketIsClosed(s));
53+
BOOST_CHECK_EQUAL(sock2->Get(), s);
54+
delete sock2;
55+
BOOST_CHECK(SocketIsClosed(s));
56+
}
57+
58+
BOOST_AUTO_TEST_CASE(move_assignment)
59+
{
60+
const SOCKET s = CreateSocket();
61+
Sock* sock1 = new Sock(s);
62+
Sock* sock2 = new Sock();
63+
*sock2 = std::move(*sock1);
64+
delete sock1;
65+
BOOST_CHECK(!SocketIsClosed(s));
66+
BOOST_CHECK_EQUAL(sock2->Get(), s);
67+
delete sock2;
68+
BOOST_CHECK(SocketIsClosed(s));
69+
}
70+
71+
BOOST_AUTO_TEST_CASE(release)
72+
{
73+
SOCKET s = CreateSocket();
74+
Sock* sock = new Sock(s);
75+
BOOST_CHECK_EQUAL(sock->Release(), s);
76+
delete sock;
77+
BOOST_CHECK(!SocketIsClosed(s));
78+
BOOST_REQUIRE(CloseSocket(s));
79+
}
80+
81+
BOOST_AUTO_TEST_CASE(reset)
82+
{
83+
const SOCKET s = CreateSocket();
84+
Sock sock(s);
85+
sock.Reset();
86+
BOOST_CHECK(SocketIsClosed(s));
87+
}
88+
89+
#ifndef WIN32 // Windows does not have socketpair(2).
90+
91+
static void CreateSocketPair(int s[2])
92+
{
93+
BOOST_REQUIRE_EQUAL(socketpair(AF_UNIX, SOCK_STREAM, 0, s), 0);
94+
}
95+
96+
static void SendAndRecvMessage(const Sock& sender, const Sock& receiver)
97+
{
98+
const char* msg = "abcd";
99+
constexpr size_t msg_len = 4;
100+
char recv_buf[10];
101+
102+
BOOST_CHECK_EQUAL(sender.Send(msg, msg_len, 0), msg_len);
103+
BOOST_CHECK_EQUAL(receiver.Recv(recv_buf, sizeof(recv_buf), 0), msg_len);
104+
BOOST_CHECK_EQUAL(strncmp(msg, recv_buf, msg_len), 0);
105+
}
106+
107+
BOOST_AUTO_TEST_CASE(send_and_receive)
108+
{
109+
int s[2];
110+
CreateSocketPair(s);
111+
112+
Sock* sock0 = new Sock(s[0]);
113+
Sock* sock1 = new Sock(s[1]);
114+
115+
SendAndRecvMessage(*sock0, *sock1);
116+
117+
Sock* sock0moved = new Sock(std::move(*sock0));
118+
Sock* sock1moved = new Sock();
119+
*sock1moved = std::move(*sock1);
120+
121+
delete sock0;
122+
delete sock1;
123+
124+
SendAndRecvMessage(*sock1moved, *sock0moved);
125+
126+
delete sock0moved;
127+
delete sock1moved;
128+
129+
BOOST_CHECK(SocketIsClosed(s[0]));
130+
BOOST_CHECK(SocketIsClosed(s[1]));
131+
}
132+
133+
BOOST_AUTO_TEST_CASE(wait)
134+
{
135+
int s[2];
136+
CreateSocketPair(s);
137+
138+
Sock sock0(s[0]);
139+
Sock sock1(s[1]);
140+
141+
std::thread waiter([&sock0]() { sock0.Wait(24h, Sock::RECV); });
142+
143+
BOOST_REQUIRE_EQUAL(sock1.Send("a", 1, 0), 1);
144+
145+
waiter.join();
146+
}
147+
148+
#endif /* WIN32 */
149+
150+
BOOST_AUTO_TEST_SUITE_END()

0 commit comments

Comments
 (0)