|
6 | 6 |
|
7 | 7 | #include <iostream>
|
8 | 8 |
|
| 9 | +TEST_CASE("tcp_server", "[tcp_server]") |
| 10 | +{ |
| 11 | + std::cerr << "[tcp_server]\n\n"; |
| 12 | +} |
| 13 | + |
9 | 14 | TEST_CASE("tcp_server ping server", "[tcp_server]")
|
10 | 15 | {
|
| 16 | + std::cerr << "BEGIN tcp_server ping server\n"; |
11 | 17 | const std::string client_msg{"Hello from client"};
|
12 | 18 | const std::string server_msg{"Reply from server!"};
|
13 | 19 |
|
@@ -89,10 +95,12 @@ TEST_CASE("tcp_server ping server", "[tcp_server]")
|
89 | 95 |
|
90 | 96 | coro::sync_wait(coro::when_all(
|
91 | 97 | make_server_task(scheduler, client_msg, server_msg), make_client_task(scheduler, client_msg, server_msg)));
|
| 98 | + std::cerr << "END tcp_server ping server\n"; |
92 | 99 | }
|
93 | 100 |
|
94 | 101 | TEST_CASE("tcp_server concurrent polling on the same socket", "[tcp_server]")
|
95 | 102 | {
|
| 103 | + std::cerr << "BEGIN tcp_server concurrent polling on the same socket\n"; |
96 | 104 | // Issue 224: This test duplicates a client and issues two different poll operations per coroutine.
|
97 | 105 |
|
98 | 106 | using namespace std::chrono_literals;
|
@@ -173,6 +181,51 @@ TEST_CASE("tcp_server concurrent polling on the same socket", "[tcp_server]")
|
173 | 181 | auto response = std::move(std::get<1>(result).return_value());
|
174 | 182 |
|
175 | 183 | REQUIRE(request == response);
|
| 184 | + std::cerr << "END tcp_server concurrent polling on the same socket\n"; |
176 | 185 | }
|
177 | 186 |
|
| 187 | +#ifndef __APPLE__ |
| 188 | +// This test is known to not work on kqueue style systems (e.g. apple) because the socket shutdown() |
| 189 | +// call does not properly trigger an EV_EOF flag on the accept socket. |
| 190 | + |
| 191 | +TEST_CASE("tcp_server graceful shutdown via socket", "[tcp_server]") |
| 192 | +{ |
| 193 | + std::cerr << "BEGIN tcp_server graceful shutdown via socket\n"; |
| 194 | + auto scheduler = coro::io_scheduler::make_shared(coro::io_scheduler::options{ |
| 195 | + .execution_strategy = coro::io_scheduler::execution_strategy_t::process_tasks_inline}); |
| 196 | + coro::net::tcp::server server{scheduler}; |
| 197 | + coro::event started{}; |
| 198 | + |
| 199 | + auto make_accept_task = [](coro::net::tcp::server& server, coro::event& started) -> coro::task<void> |
| 200 | + { |
| 201 | + std::cerr << "make accept task start\n"; |
| 202 | + started.set(); |
| 203 | + auto poll_result = co_await server.poll(); |
| 204 | + REQUIRE(poll_result == coro::poll_status::closed); |
| 205 | + auto client = server.accept(); |
| 206 | + REQUIRE_FALSE(client.socket().is_valid()); |
| 207 | + std::cerr << "make accept task completed\n"; |
| 208 | + }; |
| 209 | + |
| 210 | + scheduler->spawn(make_accept_task(server, started)); |
| 211 | + |
| 212 | + coro::sync_wait(started); |
| 213 | + // we'll wait a bit to make sure the server.poll() is fully registered. |
| 214 | + std::this_thread::sleep_for(std::chrono::milliseconds(500)); |
| 215 | + |
| 216 | + server.accept_socket().shutdown(coro::poll_op::read_write); |
| 217 | + |
| 218 | + scheduler->shutdown(); |
| 219 | + std::cerr << "END tcp_server graceful shutdown via socket\n"; |
| 220 | +} |
| 221 | + |
| 222 | +#endif |
| 223 | + |
| 224 | +TEST_CASE("~tcp_server", "[tcp_server]") |
| 225 | +{ |
| 226 | + std::cerr << "[~tcp_server]\n\n"; |
| 227 | +} |
| 228 | + |
| 229 | + |
178 | 230 | #endif // LIBCORO_FEATURE_NETWORKING
|
| 231 | + |
0 commit comments