#include "util/WithTimeout.hpp" #include "util/AsioContextTestFixture.hpp" #include #include #include #include #include #include #include #include #include #include struct WithTimeoutTests : SyncAsioContextTest { using CYieldType = boost::asio::cancellation_slot_binder< boost::asio::basic_yield_context, boost::asio::cancellation_slot>; testing::StrictMock> operationMock; }; TEST_F(WithTimeoutTests, CallsOperation) { EXPECT_CALL(operationMock, Call); runSpawn([&](boost::asio::yield_context yield) { auto const error = util::withTimeout(operationMock.AsStdFunction(), yield, std::chrono::seconds{1}); EXPECT_EQ(error, boost::system::error_code{}); }); } TEST_F(WithTimeoutTests, TimesOut) { EXPECT_CALL(operationMock, Call).WillOnce([](auto cyield) { boost::asio::steady_timer timer{boost::asio::get_associated_executor(cyield)}; timer.expires_after(std::chrono::milliseconds{10}); timer.async_wait(cyield); }); runSpawn([&](boost::asio::yield_context yield) { auto error = util::withTimeout(operationMock.AsStdFunction(), yield, std::chrono::milliseconds{1}); EXPECT_EQ(error.value(), boost::system::errc::timed_out); }); } TEST_F(WithTimeoutTests, OperationFailed) { EXPECT_CALL(operationMock, Call).WillOnce([](auto cyield) { boost::asio::ip::tcp::socket socket{boost::asio::get_associated_executor(cyield)}; socket.async_send(boost::asio::buffer("test"), cyield); }); runSpawn([&](boost::asio::yield_context yield) { auto error = util::withTimeout(operationMock.AsStdFunction(), yield, std::chrono::seconds{1}); EXPECT_EQ(error.value(), boost::system::errc::bad_file_descriptor); }); }