@@ -220,5 +220,133 @@ export namespace CppUtils::UnitTest::Network
220220 if (auto serverResult = serverListening.get(); not serverResult.has_value())
221221 throw serverResult.error();
222222 });
223+
224+ suite.addTest("isReadyForRead: Data available", [&] {
225+ auto serverisReady = std::atomic_bool{false};
226+
227+ auto serverListening = CppUtils::Thread::tryAsync([&] {
228+ auto server = CppUtils::Network::Server{};
229+ server.setReuseAddress(true);
230+ server.bind(8'080);
231+ server.listen();
232+ serverisReady.store(true, std::memory_order_release);
233+ serverisReady.notify_all();
234+
235+ auto clientSocket = server.accept().value();
236+ clientSocket.send(123);
237+ });
238+
239+ auto clientConnecting = CppUtils::Thread::tryAsync([&] {
240+ serverisReady.wait(false);
241+ auto client = CppUtils::Network::Client{};
242+ client.connect("", 8'080);
243+ client.setBlocking(false);
244+
245+ suite.expect(client.isReadyForRead(5s));
246+ auto data = client.receive<int>();
247+ suite.expect(data.has_value());
248+ suite.expectEqual(data.value(), 123);
249+ });
250+
251+ if (auto clientResult = clientConnecting.get(); not clientResult.has_value())
252+ throw clientResult.error();
253+ if (auto serverResult = serverListening.get(); not serverResult.has_value())
254+ throw serverResult.error();
255+ });
256+
257+ suite.addTest("isReadyForRead: No data (timeout)", [&] {
258+ auto serverisReady = std::atomic_bool{false};
259+
260+ auto serverListening = CppUtils::Thread::tryAsync([&] {
261+ auto server = CppUtils::Network::Server{};
262+ server.setReuseAddress(true);
263+ server.bind(8'080);
264+ server.listen();
265+ serverisReady.store(true, std::memory_order_release);
266+ serverisReady.notify_all();
267+
268+ [[maybe_unused]] auto clientSocket = server.accept().value();
269+ std::this_thread::sleep_for(1s);
270+ });
271+
272+ auto clientConnecting = CppUtils::Thread::tryAsync([&] {
273+ serverisReady.wait(false);
274+ auto client = CppUtils::Network::Client{};
275+ client.connect("", 8'080);
276+ client.setBlocking(false);
277+ std::this_thread::sleep_for(50ms);
278+ suite.expect(not client.isReadyForRead(100ms));
279+ });
280+
281+ if (auto clientResult = clientConnecting.get(); not clientResult.has_value())
282+ throw clientResult.error();
283+ if (auto serverResult = serverListening.get(); not serverResult.has_value())
284+ throw serverResult.error();
285+ });
286+
287+ suite.addTest("hasPendingError: No error", [&] {
288+ auto serverisReady = std::atomic_bool{false};
289+
290+ auto serverListening = CppUtils::Thread::tryAsync([&] {
291+ auto server = CppUtils::Network::Server{};
292+ server.setReuseAddress(true);
293+ server.bind(8'080);
294+ server.listen();
295+ serverisReady.store(true, std::memory_order_release);
296+ serverisReady.notify_all();
297+
298+ [[maybe_unused]] auto clientSocket = server.accept().value();
299+ });
300+
301+ auto clientConnecting = CppUtils::Thread::tryAsync([&] {
302+ serverisReady.wait(false);
303+ auto client = CppUtils::Network::Client{};
304+ client.connect("", 8'080);
305+
306+ suite.expect(not client.hasPendingError().has_value());
307+ });
308+
309+ if (auto clientResult = clientConnecting.get(); not clientResult.has_value())
310+ throw clientResult.error();
311+ if (auto serverResult = serverListening.get(); not serverResult.has_value())
312+ throw serverResult.error();
313+ });
314+
315+ suite.addTest("hasPendingError: With error", [&] {
316+ auto serverisReady = std::atomic_bool{false};
317+ auto serverClosedConnection = std::atomic_bool{false};
318+
319+ auto serverListening = CppUtils::Thread::tryAsync([&] {
320+ auto server = CppUtils::Network::Server{};
321+ server.setReuseAddress(true);
322+ server.bind(8'080);
323+ server.listen();
324+ serverisReady.store(true, std::memory_order_release);
325+ serverisReady.notify_all();
326+
327+ [[maybe_unused]] auto clientSocket = server.accept().value();
328+ serverClosedConnection.store(true, std::memory_order_release);
329+ serverClosedConnection.notify_all();
330+ });
331+
332+ auto clientConnecting = CppUtils::Thread::tryAsync([&] {
333+ serverisReady.wait(false);
334+ auto client = CppUtils::Network::Client{};
335+ client.connect("", 8'080);
336+
337+ serverClosedConnection.wait(false);
338+ suite.template expectThrow<std::runtime_error>([&] {
339+ client.send(1);
340+ });
341+
342+ std::this_thread::sleep_for(50ms);
343+ suite.expect(client.hasPendingError().has_value());
344+ });
345+
346+ if (auto clientResult = clientConnecting.get(); not clientResult.has_value())
347+ throw clientResult.error();
348+ if (auto serverResult = serverListening.get(); not serverResult.has_value())
349+ throw serverResult.error();
350+ });
223351 }};
224352}
0 commit comments