aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVasil Dimov <vd@FreeBSD.org>2021-03-11 15:09:39 +0100
committerVasil Dimov <vd@FreeBSD.org>2021-03-16 11:00:57 +0100
commit7059e6d82275b44efc41675ee10760145b6c1073 (patch)
treeef4fb60f4df2f9845277e8880e568ca46b4f4d2d
parent80a5a8ea2b7ad512c74c29df5b504e9be6cf23a0 (diff)
downloadbitcoin-7059e6d82275b44efc41675ee10760145b6c1073.tar.xz
test: add a test to ensure RecvUntilTerminator() limit works
-rw-r--r--src/test/sock_tests.cpp31
1 files changed, 31 insertions, 0 deletions
diff --git a/src/test/sock_tests.cpp b/src/test/sock_tests.cpp
index ed9780dfb5..400de875b7 100644
--- a/src/test/sock_tests.cpp
+++ b/src/test/sock_tests.cpp
@@ -4,11 +4,13 @@
#include <compat.h>
#include <test/util/setup_common.h>
+#include <threadinterrupt.h>
#include <util/sock.h>
#include <util/system.h>
#include <boost/test/unit_test.hpp>
+#include <cassert>
#include <thread>
using namespace std::chrono_literals;
@@ -144,6 +146,35 @@ BOOST_AUTO_TEST_CASE(wait)
waiter.join();
}
+BOOST_AUTO_TEST_CASE(recv_until_terminator_limit)
+{
+ constexpr auto timeout = 1min; // High enough so that it is never hit.
+ CThreadInterrupt interrupt;
+ int s[2];
+ CreateSocketPair(s);
+
+ Sock sock_send(s[0]);
+ Sock sock_recv(s[1]);
+
+ std::thread receiver([&sock_recv, &timeout, &interrupt]() {
+ constexpr size_t max_data{10};
+ bool threw_as_expected{false};
+ // BOOST_CHECK_EXCEPTION() writes to some variables shared with the main thread which
+ // creates a data race. So mimic it manually.
+ try {
+ sock_recv.RecvUntilTerminator('\n', timeout, interrupt, max_data);
+ } catch (const std::runtime_error& e) {
+ threw_as_expected = HasReason("too many bytes without a terminator")(e);
+ }
+ assert(threw_as_expected);
+ });
+
+ BOOST_REQUIRE_NO_THROW(sock_send.SendComplete("1234567", timeout, interrupt));
+ BOOST_REQUIRE_NO_THROW(sock_send.SendComplete("89a\n", timeout, interrupt));
+
+ receiver.join();
+}
+
#endif /* WIN32 */
BOOST_AUTO_TEST_SUITE_END()