diff --git a/nano/core_test/socket.cpp b/nano/core_test/socket.cpp index 339e6ab9d..60d3cfc90 100644 --- a/nano/core_test/socket.cpp +++ b/nano/core_test/socket.cpp @@ -114,10 +114,11 @@ TEST (socket, disconnection_of_silent_connections) // Just to ensure the disconnection wasn't due to the timer timeout. ASSERT_EQ (0, node->stats.count (nano::stat::type::tcp, nano::stat::detail::tcp_io_timeout_drop, nano::stat::dir::in)); // Asserts the silent checker worked. - ASSERT_EQ (1, node->stats.count (nano::stat::type::tcp, nano::stat::detail::tcp_silent_connection_drop, nano::stat::dir::in)); + ASSERT_LE (1, node->stats.count (nano::stat::type::tcp, nano::stat::detail::tcp_silent_connection_drop, nano::stat::dir::in)); } -TEST (socket, drop_policy) +// FIXME: Socket no longer queues writes, so this test is no longer valid +TEST (socket, DISABLED_drop_policy) { nano::test::system system; @@ -180,9 +181,8 @@ TEST (socket, drop_policy) ASSERT_EQ (0, failed_writes); } -// This is abusing the socket class, it's interfering with the normal node lifetimes and as a result deadlocks -// TEST (socket, DISABLED_concurrent_writes) -TEST (socket, concurrent_writes) +// FIXME: Socket no longer queues writes, so this test is no longer valid +TEST (socket, DISABLED_concurrent_writes) { nano::test::system system; @@ -369,16 +369,14 @@ TEST (socket_timeout, read) // check that the callback was called and we got an error ASSERT_TIMELY_EQ (10s, done, true); ASSERT_TRUE (ec); - ASSERT_EQ (1, node->stats.count (nano::stat::type::tcp, nano::stat::detail::tcp_read_error, nano::stat::dir::in)); + ASSERT_EQ (1, node->stats.count (nano::stat::type::tcp, nano::stat::detail::tcp_read_error)); // check that the socket was closed due to tcp_io_timeout timeout - ASSERT_EQ (1, node->stats.count (nano::stat::type::tcp, nano::stat::detail::tcp_io_timeout_drop, nano::stat::dir::out)); + ASSERT_EQ (1, node->stats.count (nano::stat::type::tcp, nano::stat::detail::tcp_io_timeout_drop, nano::stat::dir::in)); } TEST (socket_timeout, write) { - std::atomic done = false; - // create one node and set timeout to 1 second nano::test::system system (1); std::shared_ptr node = system.nodes[0]; @@ -386,13 +384,13 @@ TEST (socket_timeout, write) // create a server socket boost::asio::ip::tcp::endpoint endpoint (boost::asio::ip::address_v6::loopback (), system.get_available_port ()); - boost::asio::ip::tcp::acceptor acceptor (*system.io_ctx); + boost::asio::ip::tcp::acceptor acceptor (node->io_ctx); acceptor.open (endpoint.protocol ()); acceptor.bind (endpoint); acceptor.listen (boost::asio::socket_base::max_listen_connections); // asynchronously accept an incoming connection and create a newsock and do not receive any data - boost::asio::ip::tcp::socket newsock (*system.io_ctx); + boost::asio::ip::tcp::socket newsock (node->io_ctx); acceptor.async_accept (newsock, [] (boost::system::error_code const & ec_a) { EXPECT_FALSE (ec_a); }); @@ -402,24 +400,26 @@ TEST (socket_timeout, write) // and the timeout should kick in and close the socket, which will cause the async_write to return an error auto socket = std::make_shared (*node, nano::transport::socket_endpoint::client); // socket with a max queue size much larger than OS buffers - socket->async_connect (acceptor.local_endpoint (), [&socket, &done] (boost::system::error_code const & ec_a) { - EXPECT_FALSE (ec_a); + auto ec_0 = socket->blocking_connect (acceptor.local_endpoint ()); + ASSERT_FALSE (ec_0); - auto buffer = std::make_shared> (128 * 1024); - for (auto i = 0; i < 1024; ++i) + auto buffer = std::make_shared> (128 * 1024); + + // At some point the write should fail with a timeout + boost::system::error_code ec; + for (auto i = 0; i < 1024; ++i) + { + auto [ec_1, size_1] = socket->blocking_write (buffer, buffer->size ()); + if (ec_1) { - socket->async_write (nano::shared_const_buffer{ buffer }, [&done] (boost::system::error_code const & ec_a, size_t size_a) { - if (ec_a) - { - done = true; - } - }); + ec = ec_1; + break; } - }); + } // check that the callback was called and we got an error - ASSERT_TIMELY (10s, done); - ASSERT_LE (1, node->stats.count (nano::stat::type::tcp, nano::stat::detail::tcp_write_error, nano::stat::dir::in)); + ASSERT_TRUE (ec); + ASSERT_LE (1, node->stats.count (nano::stat::type::tcp, nano::stat::detail::tcp_write_error)); // check that the socket was closed due to tcp_io_timeout timeout ASSERT_LE (1, node->stats.count (nano::stat::type::tcp, nano::stat::detail::tcp_io_timeout_drop, nano::stat::dir::out)); @@ -434,60 +434,48 @@ TEST (socket_timeout, read_overlapped) // create a server socket boost::asio::ip::tcp::endpoint endpoint (boost::asio::ip::address_v6::loopback (), system.get_available_port ()); - boost::asio::ip::tcp::acceptor acceptor (*system.io_ctx); + boost::asio::ip::tcp::acceptor acceptor (node->io_ctx); acceptor.open (endpoint.protocol ()); acceptor.bind (endpoint); acceptor.listen (boost::asio::socket_base::max_listen_connections); // asynchronously accept an incoming connection and send one byte only - boost::asio::ip::tcp::socket newsock (*system.io_ctx); + boost::asio::ip::tcp::socket newsock (node->io_ctx); acceptor.async_accept (newsock, [&newsock] (boost::system::error_code const & ec_a) { EXPECT_FALSE (ec_a); auto buffer = std::make_shared> (1); nano::async_write (newsock, nano::shared_const_buffer (buffer), [] (boost::system::error_code const & ec_a, size_t size_a) { EXPECT_TRUE (!ec_a); - EXPECT_TRUE (size_a == 1); + EXPECT_EQ (size_a, 1); }); }); // create a client socket to connect and call async_read twice, the second call should time out auto socket = std::make_shared (*node); - std::atomic done = false; - boost::system::error_code ec; - socket->async_connect (acceptor.local_endpoint (), [&socket, &ec, &done] (boost::system::error_code const & ec_a) { - EXPECT_FALSE (ec_a); - auto buffer = std::make_shared> (1); + auto ec_0 = socket->blocking_connect (acceptor.local_endpoint ()); + ASSERT_FALSE (ec_0); - socket->async_read (buffer, 1, [] (boost::system::error_code const & ec_a, size_t size_a) { - EXPECT_FALSE (ec_a); - EXPECT_TRUE (size_a == 1); - }); + auto buffer = std::make_shared> (1); - socket->async_read (buffer, 1, [&ec, &done] (boost::system::error_code const & ec_a, size_t size_a) { - EXPECT_EQ (size_a, 0); - if (ec_a) - { - ec = ec_a; - done = true; - } - }); - }); + auto [ec_1, size_1] = socket->blocking_read (buffer, 1); + ASSERT_FALSE (ec_1); + ASSERT_TRUE (size_1 == 1); + + auto [ec_2, size_2] = socket->blocking_read (buffer, 1); + ASSERT_EQ (size_2, 0); + ASSERT_TRUE (ec_2); // check that the callback was called and we got an error - ASSERT_TIMELY_EQ (10s, done, true); - ASSERT_TRUE (ec); - ASSERT_LE (1, node->stats.count (nano::stat::type::tcp, nano::stat::detail::tcp_read_error, nano::stat::dir::in)); + ASSERT_LE (1, node->stats.count (nano::stat::type::tcp, nano::stat::detail::tcp_read_error)); // check that the socket was closed due to tcp_io_timeout timeout - ASSERT_LE (1, node->stats.count (nano::stat::type::tcp, nano::stat::detail::tcp_io_timeout_drop, nano::stat::dir::out)); + ASSERT_LE (1, node->stats.count (nano::stat::type::tcp, nano::stat::detail::tcp_io_timeout_drop, nano::stat::dir::in)); } TEST (socket_timeout, write_overlapped) { - std::atomic done = false; - // create one node and set timeout to 1 second nano::test::system system (1); std::shared_ptr node = system.nodes[0]; @@ -495,13 +483,13 @@ TEST (socket_timeout, write_overlapped) // create a server socket boost::asio::ip::tcp::endpoint endpoint (boost::asio::ip::address_v6::loopback (), system.get_available_port ()); - boost::asio::ip::tcp::acceptor acceptor (*system.io_ctx); + boost::asio::ip::tcp::acceptor acceptor (node->io_ctx); acceptor.open (endpoint.protocol ()); acceptor.bind (endpoint); acceptor.listen (boost::asio::socket_base::max_listen_connections); // asynchronously accept an incoming connection and read 2 bytes only - boost::asio::ip::tcp::socket newsock (*system.io_ctx); + boost::asio::ip::tcp::socket newsock (node->io_ctx); auto buffer = std::make_shared> (1); acceptor.async_accept (newsock, [&newsock, &buffer] (boost::system::error_code const & ec_a) { EXPECT_FALSE (ec_a); @@ -515,30 +503,33 @@ TEST (socket_timeout, write_overlapped) // create a client socket and send lots of data to fill the socket queue on the local and remote side // eventually, the all tcp queues should fill up and async_write will not be able to progress // and the timeout should kick in and close the socket, which will cause the async_write to return an error - auto socket = std::make_shared (*node, nano::transport::socket_endpoint::client); // socket with a max queue size much larger than OS buffers - socket->async_connect (acceptor.local_endpoint (), [&socket, &done] (boost::system::error_code const & ec_a) { - EXPECT_FALSE (ec_a); + auto socket = std::make_shared (*node, nano::transport::socket_endpoint::client); - auto buffer1 = std::make_shared> (1); - auto buffer2 = std::make_shared> (128 * 1024); - socket->async_write (nano::shared_const_buffer{ buffer1 }, [] (boost::system::error_code const & ec_a, size_t size_a) { - EXPECT_FALSE (ec_a); - EXPECT_EQ (size_a, 1); - }); - for (auto i = 0; i < 1024; ++i) + auto ec_0 = socket->blocking_connect (acceptor.local_endpoint ()); + ASSERT_FALSE (ec_0); + + auto buffer1 = std::make_shared> (1); + auto buffer2 = std::make_shared> (128 * 1024); + + auto [ec_1, size_1] = socket->blocking_write (nano::shared_const_buffer{ buffer1 }, 1); + ASSERT_FALSE (ec_1); + ASSERT_EQ (size_1, 1); + + // At some point the write should fail with a timeout + boost::system::error_code ec; + for (auto i = 0; i < 1000; ++i) + { + auto [ec_2, size_2] = socket->blocking_write (nano::shared_const_buffer{ buffer2 }, 128 * 1024); + if (ec_2) { - socket->async_write (nano::shared_const_buffer{ buffer2 }, [&done] (boost::system::error_code const & ec_a, size_t size_a) { - if (ec_a) - { - done = true; - } - }); + ec = ec_2; + break; } - }); + } // check that the callback was called and we got an error - ASSERT_TIMELY_EQ (10s, done, true); - ASSERT_LE (1, node->stats.count (nano::stat::type::tcp, nano::stat::detail::tcp_write_error, nano::stat::dir::in)); + ASSERT_TRUE (ec); + ASSERT_LE (1, node->stats.count (nano::stat::type::tcp, nano::stat::detail::tcp_write_error)); // check that the socket was closed due to tcp_io_timeout timeout ASSERT_LE (1, node->stats.count (nano::stat::type::tcp, nano::stat::detail::tcp_io_timeout_drop, nano::stat::dir::out)); diff --git a/nano/core_test/telemetry.cpp b/nano/core_test/telemetry.cpp index aa213e776..9c3118791 100644 --- a/nano/core_test/telemetry.cpp +++ b/nano/core_test/telemetry.cpp @@ -159,15 +159,8 @@ TEST (telemetry, dos_tcp) ASSERT_TIMELY (5s, (nano::dev::network_params.network.telemetry_request_cooldown + orig) <= std::chrono::steady_clock::now ()); - // Should process no more telemetry_req messages - ASSERT_EQ (1, node_server->stats.count (nano::stat::type::message, nano::stat::detail::telemetry_req, nano::stat::dir::in)); - - // Now spam messages waiting for it to be processed - while (node_server->stats.count (nano::stat::type::message, nano::stat::detail::telemetry_req, nano::stat::dir::in) == 1) - { - channel->send (message, nano::transport::traffic_type::test); - ASSERT_NO_ERROR (system.poll ()); - } + // But not respond to all of them (by default there are 2 broadcasts per second in dev mode) + ASSERT_ALWAYS (1s, node_server->stats.count (nano::stat::type::message, nano::stat::detail::telemetry_ack, nano::stat::dir::out) < 7); } TEST (telemetry, disable_metrics)