#include "catch.hpp" #include #include TEST_CASE("tcp_server ping server", "[tcp_server]") { const std::string client_msg{"Hello from client"}; const std::string server_msg{"Reply from server!"}; coro::io_scheduler scheduler{coro::io_scheduler::options{.pool = coro::thread_pool::options{.thread_count = 1}}}; auto make_client_task = [&]() -> coro::task { co_await scheduler.schedule(); coro::net::tcp_client client{scheduler}; std::cerr << "client connect\n"; auto cstatus = co_await client.connect(); REQUIRE(cstatus == coro::net::connect_status::connected); // Skip polling for write, should really only poll if the write is partial, shouldn't be // required for this test. std::cerr << "client send()\n"; auto [sstatus, remaining] = client.send(client_msg); REQUIRE(sstatus == coro::net::send_status::ok); REQUIRE(remaining.empty()); // Poll for the server's response. std::cerr << "client poll(read)\n"; auto pstatus = co_await client.poll(coro::poll_op::read); REQUIRE(pstatus == coro::poll_status::event); std::string buffer(256, '\0'); std::cerr << "client recv()\n"; auto [rstatus, rspan] = client.recv(buffer); REQUIRE(rstatus == coro::net::recv_status::ok); REQUIRE(rspan.size() == server_msg.length()); buffer.resize(rspan.size()); REQUIRE(buffer == server_msg); std::cerr << "client return\n"; co_return; }; auto make_server_task = [&]() -> coro::task { co_await scheduler.schedule(); coro::net::tcp_server server{scheduler}; // Poll for client connection. std::cerr << "server poll(accept)\n"; auto pstatus = co_await server.poll(); REQUIRE(pstatus == coro::poll_status::event); std::cerr << "server accept()\n"; auto client = server.accept(); REQUIRE(client.socket().is_valid()); // Poll for client request. std::cerr << "server poll(read)\n"; pstatus = co_await client.poll(coro::poll_op::read); REQUIRE(pstatus == coro::poll_status::event); std::string buffer(256, '\0'); std::cerr << "server recv()\n"; auto [rstatus, rspan] = client.recv(buffer); REQUIRE(rstatus == coro::net::recv_status::ok); REQUIRE(rspan.size() == client_msg.size()); buffer.resize(rspan.size()); REQUIRE(buffer == client_msg); // Respond to client. std::cerr << "server send()\n"; auto [sstatus, remaining] = client.send(server_msg); REQUIRE(sstatus == coro::net::send_status::ok); REQUIRE(remaining.empty()); std::cerr << "server return\n"; co_return; }; coro::sync_wait(coro::when_all(make_server_task(), make_client_task())); }