mirror of
https://gitlab.com/niansa/libcrosscoro.git
synced 2025-03-06 20:53:32 +01:00
* Add coro::mutex example to readme * explicit lock_operation ctor * lock_operation await_ready() uses try_lock This allows for the lock operation to skip await_suspend() entirely if the lock was unlocked.
82 lines
2.8 KiB
C++
82 lines
2.8 KiB
C++
#include "catch.hpp"
|
|
|
|
#include <coro/coro.hpp>
|
|
|
|
#include <iostream>
|
|
|
|
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<void> {
|
|
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<void> {
|
|
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()));
|
|
}
|