Skip to content

Commit 7059e6d

Browse files
committed
test: add a test to ensure RecvUntilTerminator() limit works
1 parent 80a5a8e commit 7059e6d

File tree

1 file changed

+31
-0
lines changed

1 file changed

+31
-0
lines changed

src/test/sock_tests.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@
44

55
#include <compat.h>
66
#include <test/util/setup_common.h>
7+
#include <threadinterrupt.h>
78
#include <util/sock.h>
89
#include <util/system.h>
910

1011
#include <boost/test/unit_test.hpp>
1112

13+
#include <cassert>
1214
#include <thread>
1315

1416
using namespace std::chrono_literals;
@@ -144,6 +146,35 @@ BOOST_AUTO_TEST_CASE(wait)
144146
waiter.join();
145147
}
146148

149+
BOOST_AUTO_TEST_CASE(recv_until_terminator_limit)
150+
{
151+
constexpr auto timeout = 1min; // High enough so that it is never hit.
152+
CThreadInterrupt interrupt;
153+
int s[2];
154+
CreateSocketPair(s);
155+
156+
Sock sock_send(s[0]);
157+
Sock sock_recv(s[1]);
158+
159+
std::thread receiver([&sock_recv, &timeout, &interrupt]() {
160+
constexpr size_t max_data{10};
161+
bool threw_as_expected{false};
162+
// BOOST_CHECK_EXCEPTION() writes to some variables shared with the main thread which
163+
// creates a data race. So mimic it manually.
164+
try {
165+
sock_recv.RecvUntilTerminator('\n', timeout, interrupt, max_data);
166+
} catch (const std::runtime_error& e) {
167+
threw_as_expected = HasReason("too many bytes without a terminator")(e);
168+
}
169+
assert(threw_as_expected);
170+
});
171+
172+
BOOST_REQUIRE_NO_THROW(sock_send.SendComplete("1234567", timeout, interrupt));
173+
BOOST_REQUIRE_NO_THROW(sock_send.SendComplete("89a\n", timeout, interrupt));
174+
175+
receiver.join();
176+
}
177+
147178
#endif /* WIN32 */
148179

149180
BOOST_AUTO_TEST_SUITE_END()

0 commit comments

Comments
 (0)