Serenity Operating System
at master 596 lines 23 kB view raw
1/* 2 * Copyright (c) 2021, sin-ack <sin-ack@protonmail.com> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <AK/Format.h> 8#include <AK/MaybeOwned.h> 9#include <AK/String.h> 10#include <LibCore/EventLoop.h> 11#include <LibCore/File.h> 12#include <LibCore/LocalServer.h> 13#include <LibCore/Socket.h> 14#include <LibCore/TCPServer.h> 15#include <LibCore/Timer.h> 16#include <LibCore/UDPServer.h> 17#include <LibTest/TestCase.h> 18#include <LibThreading/BackgroundAction.h> 19#include <fcntl.h> 20#include <unistd.h> 21 22// File tests 23 24TEST_CASE(file_open) 25{ 26 auto maybe_file = Core::File::open("/tmp/file-open-test.txt"sv, Core::File::OpenMode::Write); 27 if (maybe_file.is_error()) { 28 warnln("Failed to open the file: {}", strerror(maybe_file.error().code())); 29 VERIFY_NOT_REACHED(); 30 } 31 32 // Testing out some basic file properties. 33 auto file = maybe_file.release_value(); 34 EXPECT(file->is_open()); 35 EXPECT(!file->is_eof()); 36 37 auto maybe_size = file->size(); 38 EXPECT(!maybe_size.is_error()); 39 EXPECT_EQ(maybe_size.value(), 0ul); 40} 41 42TEST_CASE(file_write_bytes) 43{ 44 auto maybe_file = Core::File::open("/tmp/file-write-bytes-test.txt"sv, Core::File::OpenMode::Write); 45 auto file = maybe_file.release_value(); 46 47 constexpr auto some_words = "These are some words"sv; 48 ReadonlyBytes buffer { some_words.characters_without_null_termination(), some_words.length() }; 49 auto result = file->write_some(buffer); 50 EXPECT(!result.is_error()); 51} 52 53constexpr auto expected_buffer_contents = "&lt;small&gt;(Please consider translating this message for the benefit of your fellow Wikimedians. Please also consider translating"sv; 54 55TEST_CASE(file_read_bytes) 56{ 57 auto maybe_file = Core::File::open("/usr/Tests/LibCore/long_lines.txt"sv, Core::File::OpenMode::Read); 58 EXPECT(!maybe_file.is_error()); 59 auto file = maybe_file.release_value(); 60 61 auto maybe_buffer = ByteBuffer::create_uninitialized(131); 62 EXPECT(!maybe_buffer.is_error()); 63 auto buffer = maybe_buffer.release_value(); 64 65 auto result = file->read_some(buffer); 66 EXPECT(!result.is_error()); 67 EXPECT_EQ(result.value().size(), 131ul); 68 69 StringView buffer_contents { buffer.bytes() }; 70 EXPECT_EQ(buffer_contents, expected_buffer_contents); 71} 72 73constexpr auto expected_seek_contents1 = "|Lleer esti mens"sv; 74constexpr auto expected_seek_contents2 = "s of advanced ad"sv; 75constexpr auto expected_seek_contents3 = "levels of advanc"sv; 76 77TEST_CASE(file_seeking_around) 78{ 79 auto maybe_file = Core::File::open("/usr/Tests/LibCore/long_lines.txt"sv, Core::File::OpenMode::Read); 80 EXPECT(!maybe_file.is_error()); 81 auto file = maybe_file.release_value(); 82 83 EXPECT_EQ(file->size().release_value(), 8702ul); 84 85 auto maybe_buffer = ByteBuffer::create_uninitialized(16); 86 EXPECT(!maybe_buffer.is_error()); 87 auto buffer = maybe_buffer.release_value(); 88 89 StringView buffer_contents { buffer.bytes() }; 90 91 EXPECT(!file->seek(500, SeekMode::SetPosition).is_error()); 92 EXPECT_EQ(file->tell().release_value(), 500ul); 93 EXPECT(!file->read_until_filled(buffer).is_error()); 94 EXPECT_EQ(buffer_contents, expected_seek_contents1); 95 96 EXPECT(!file->seek(234, SeekMode::FromCurrentPosition).is_error()); 97 EXPECT_EQ(file->tell().release_value(), 750ul); 98 EXPECT(!file->read_until_filled(buffer).is_error()); 99 EXPECT_EQ(buffer_contents, expected_seek_contents2); 100 101 EXPECT(!file->seek(-105, SeekMode::FromEndPosition).is_error()); 102 EXPECT_EQ(file->tell().release_value(), 8597ul); 103 EXPECT(!file->read_until_filled(buffer).is_error()); 104 EXPECT_EQ(buffer_contents, expected_seek_contents3); 105} 106 107TEST_CASE(file_adopt_fd) 108{ 109 int rc = ::open("/usr/Tests/LibCore/long_lines.txt", O_RDONLY); 110 EXPECT(rc >= 0); 111 112 auto maybe_file = Core::File::adopt_fd(rc, Core::File::OpenMode::Read); 113 EXPECT(!maybe_file.is_error()); 114 auto file = maybe_file.release_value(); 115 116 EXPECT_EQ(file->size().release_value(), 8702ul); 117 118 auto maybe_buffer = ByteBuffer::create_uninitialized(16); 119 EXPECT(!maybe_buffer.is_error()); 120 auto buffer = maybe_buffer.release_value(); 121 122 StringView buffer_contents { buffer.bytes() }; 123 124 EXPECT(!file->seek(500, SeekMode::SetPosition).is_error()); 125 EXPECT_EQ(file->tell().release_value(), 500ul); 126 EXPECT(!file->read_until_filled(buffer).is_error()); 127 EXPECT_EQ(buffer_contents, expected_seek_contents1); 128 129 // A single seek & read test should be fine for now. 130} 131 132TEST_CASE(file_adopt_invalid_fd) 133{ 134 auto maybe_file = Core::File::adopt_fd(-1, Core::File::OpenMode::Read); 135 EXPECT(maybe_file.is_error()); 136 EXPECT_EQ(maybe_file.error().code(), EBADF); 137} 138 139TEST_CASE(file_truncate) 140{ 141 auto maybe_file = Core::File::open("/tmp/file-truncate-test.txt"sv, Core::File::OpenMode::Write); 142 auto file = maybe_file.release_value(); 143 144 EXPECT(!file->truncate(999).is_error()); 145 EXPECT_EQ(file->size().release_value(), 999ul); 146 147 EXPECT(!file->truncate(42).is_error()); 148 EXPECT_EQ(file->size().release_value(), 42ul); 149} 150 151// TCPSocket tests 152 153TEST_CASE(should_error_when_connection_fails) 154{ 155 // NOTE: This is required here because Core::TCPSocket requires 156 // Core::EventLoop through Core::Notifier. 157 Core::EventLoop event_loop; 158 159 auto maybe_tcp_socket = Core::TCPSocket::connect({ { 127, 0, 0, 1 }, 1234 }); 160 EXPECT(maybe_tcp_socket.is_error()); 161 EXPECT(maybe_tcp_socket.error().is_syscall()); 162 EXPECT(maybe_tcp_socket.error().code() == ECONNREFUSED); 163} 164 165constexpr auto sent_data = "Mr. Watson, come here. I want to see you."sv; 166 167TEST_CASE(tcp_socket_read) 168{ 169 // NOTE: This is required here because Core::TCPServer requires 170 // Core::EventLoop through Core::Notifier. 171 Core::EventLoop event_loop; 172 173 auto maybe_tcp_server = Core::TCPServer::try_create(); 174 EXPECT(!maybe_tcp_server.is_error()); 175 auto tcp_server = maybe_tcp_server.release_value(); 176 EXPECT(!tcp_server->listen({ 127, 0, 0, 1 }, 9090).is_error()); 177 EXPECT(!tcp_server->set_blocking(true).is_error()); 178 179 auto maybe_client_socket = Core::TCPSocket::connect({ { 127, 0, 0, 1 }, 9090 }); 180 EXPECT(!maybe_client_socket.is_error()); 181 auto client_socket = maybe_client_socket.release_value(); 182 183 EXPECT(client_socket->is_open()); 184 185 auto maybe_server_socket = tcp_server->accept(); 186 EXPECT(!maybe_server_socket.is_error()); 187 auto server_socket = maybe_server_socket.release_value(); 188 EXPECT(!server_socket->write_some({ sent_data.characters_without_null_termination(), sent_data.length() }).is_error()); 189 server_socket->close(); 190 191 EXPECT(client_socket->can_read_without_blocking(100).release_value()); 192 EXPECT_EQ(client_socket->pending_bytes().release_value(), sent_data.length()); 193 194 auto maybe_receive_buffer = ByteBuffer::create_uninitialized(64); 195 EXPECT(!maybe_receive_buffer.is_error()); 196 auto receive_buffer = maybe_receive_buffer.release_value(); 197 auto maybe_read_bytes = client_socket->read_some(receive_buffer); 198 EXPECT(!maybe_read_bytes.is_error()); 199 auto read_bytes = maybe_read_bytes.release_value(); 200 201 StringView received_data { read_bytes }; 202 EXPECT_EQ(sent_data, received_data); 203} 204 205TEST_CASE(tcp_socket_write) 206{ 207 Core::EventLoop event_loop; 208 209 auto maybe_tcp_server = Core::TCPServer::try_create(); 210 EXPECT(!maybe_tcp_server.is_error()); 211 auto tcp_server = maybe_tcp_server.release_value(); 212 EXPECT(!tcp_server->listen({ 127, 0, 0, 1 }, 9090).is_error()); 213 EXPECT(!tcp_server->set_blocking(true).is_error()); 214 215 auto maybe_client_socket = Core::TCPSocket::connect({ { 127, 0, 0, 1 }, 9090 }); 216 EXPECT(!maybe_client_socket.is_error()); 217 auto client_socket = maybe_client_socket.release_value(); 218 219 auto maybe_server_socket = tcp_server->accept(); 220 EXPECT(!maybe_server_socket.is_error()); 221 auto server_socket = maybe_server_socket.release_value(); 222 EXPECT(!server_socket->set_blocking(true).is_error()); 223 224 EXPECT(!client_socket->write_until_depleted({ sent_data.characters_without_null_termination(), sent_data.length() }).is_error()); 225 client_socket->close(); 226 227 auto maybe_receive_buffer = ByteBuffer::create_uninitialized(64); 228 EXPECT(!maybe_receive_buffer.is_error()); 229 auto receive_buffer = maybe_receive_buffer.release_value(); 230 auto maybe_read_bytes = server_socket->read_some(receive_buffer); 231 EXPECT(!maybe_read_bytes.is_error()); 232 auto read_bytes = maybe_read_bytes.release_value(); 233 234 StringView received_data { read_bytes }; 235 EXPECT_EQ(sent_data, received_data); 236} 237 238TEST_CASE(tcp_socket_eof) 239{ 240 Core::EventLoop event_loop; 241 242 auto maybe_tcp_server = Core::TCPServer::try_create(); 243 EXPECT(!maybe_tcp_server.is_error()); 244 auto tcp_server = maybe_tcp_server.release_value(); 245 EXPECT(!tcp_server->listen({ 127, 0, 0, 1 }, 9090).is_error()); 246 EXPECT(!tcp_server->set_blocking(true).is_error()); 247 248 auto maybe_client_socket = Core::TCPSocket::connect({ { 127, 0, 0, 1 }, 9090 }); 249 EXPECT(!maybe_client_socket.is_error()); 250 auto client_socket = maybe_client_socket.release_value(); 251 252 EXPECT(client_socket->is_open()); 253 254 auto server_socket = tcp_server->accept().release_value(); 255 server_socket->close(); 256 257 // NOTE: This may seem unintuitive, but poll will mark a fd which has 258 // reached EOF (i.e. in the case of the other side disconnecting) as 259 // POLLIN. 260 EXPECT(client_socket->can_read_without_blocking(100).release_value()); 261 EXPECT_EQ(client_socket->pending_bytes().release_value(), 0ul); 262 263 auto maybe_receive_buffer = ByteBuffer::create_uninitialized(1); 264 EXPECT(!maybe_receive_buffer.is_error()); 265 auto receive_buffer = maybe_receive_buffer.release_value(); 266 EXPECT(client_socket->read_some(receive_buffer).release_value().is_empty()); 267 EXPECT(client_socket->is_eof()); 268} 269 270// UDPSocket tests 271 272constexpr auto udp_reply_data = "Well hello friends!"sv; 273 274TEST_CASE(udp_socket_read_write) 275{ 276 // NOTE: This is required here because Core::UDPServer requires 277 // Core::EventLoop through Core::Notifier. 278 Core::EventLoop event_loop; 279 280 auto udp_server = Core::UDPServer::construct(); 281 EXPECT(udp_server->bind({ 127, 0, 0, 1 }, 9090)); 282 283 auto maybe_client_socket = Core::UDPSocket::connect({ { 127, 0, 0, 1 }, 9090 }); 284 EXPECT(!maybe_client_socket.is_error()); 285 auto client_socket = maybe_client_socket.release_value(); 286 287 EXPECT(client_socket->is_open()); 288 EXPECT(!client_socket->write_until_depleted({ sent_data.characters_without_null_termination(), sent_data.length() }).is_error()); 289 290 // FIXME: UDPServer::receive sadly doesn't give us a way to block on it, 291 // currently. 292 usleep(100000); 293 294 struct sockaddr_in client_address; 295 auto server_receive_buffer_or_error = udp_server->receive(64, client_address); 296 EXPECT(!server_receive_buffer_or_error.is_error()); 297 auto server_receive_buffer = server_receive_buffer_or_error.release_value(); 298 EXPECT(!server_receive_buffer.is_empty()); 299 300 StringView server_received_data { server_receive_buffer.bytes() }; 301 EXPECT_EQ(server_received_data, sent_data); 302 303 EXPECT(!udp_server->send({ udp_reply_data.characters_without_null_termination(), udp_reply_data.length() }, client_address).is_error()); 304 305 EXPECT(client_socket->can_read_without_blocking(100).release_value()); 306 EXPECT_EQ(client_socket->pending_bytes().release_value(), udp_reply_data.length()); 307 308 // Testing that supplying a smaller buffer than required causes a failure. 309 auto small_buffer = ByteBuffer::create_uninitialized(8).release_value(); 310 EXPECT_EQ(client_socket->read_some(small_buffer).error().code(), EMSGSIZE); 311 312 auto maybe_client_receive_buffer = ByteBuffer::create_uninitialized(64); 313 EXPECT(!maybe_client_receive_buffer.is_error()); 314 auto client_receive_buffer = maybe_client_receive_buffer.release_value(); 315 auto maybe_read_bytes = client_socket->read_some(client_receive_buffer); 316 EXPECT(!maybe_read_bytes.is_error()); 317 auto read_bytes = maybe_read_bytes.release_value(); 318 319 StringView client_received_data { read_bytes }; 320 EXPECT_EQ(udp_reply_data, client_received_data); 321} 322 323// LocalSocket tests 324 325TEST_CASE(local_socket_read) 326{ 327 Core::EventLoop event_loop; 328 329 auto local_server = Core::LocalServer::construct(); 330 EXPECT(local_server->listen("/tmp/test-socket")); 331 332 local_server->on_accept = [&](NonnullOwnPtr<Core::LocalSocket> server_socket) { 333 EXPECT(!server_socket->write_some(sent_data.bytes()).is_error()); 334 335 event_loop.quit(0); 336 event_loop.pump(); 337 }; 338 339 // NOTE: Doing this on another thread, because otherwise we're at an 340 // impasse. LocalSocket::connect blocks because there's nobody to 341 // accept, and LocalServer::accept blocks because there's nobody 342 // connected. 343 auto background_action = Threading::BackgroundAction<int>::construct( 344 [](auto&) { 345 Core::EventLoop event_loop; 346 347 auto maybe_client_socket = Core::LocalSocket::connect("/tmp/test-socket"); 348 EXPECT(!maybe_client_socket.is_error()); 349 auto client_socket = maybe_client_socket.release_value(); 350 351 EXPECT(client_socket->is_open()); 352 353 EXPECT(client_socket->can_read_without_blocking(100).release_value()); 354 EXPECT_EQ(client_socket->pending_bytes().release_value(), sent_data.length()); 355 356 auto maybe_receive_buffer = ByteBuffer::create_uninitialized(64); 357 EXPECT(!maybe_receive_buffer.is_error()); 358 auto receive_buffer = maybe_receive_buffer.release_value(); 359 auto maybe_read_bytes = client_socket->read_some(receive_buffer); 360 EXPECT(!maybe_read_bytes.is_error()); 361 auto read_bytes = maybe_read_bytes.release_value(); 362 363 StringView received_data { read_bytes }; 364 EXPECT_EQ(sent_data, received_data); 365 366 return 0; 367 }, 368 nullptr); 369 370 event_loop.exec(); 371 ::unlink("/tmp/test-socket"); 372} 373 374TEST_CASE(local_socket_write) 375{ 376 Core::EventLoop event_loop; 377 378 auto local_server = Core::LocalServer::construct(); 379 EXPECT(local_server->listen("/tmp/test-socket")); 380 381 local_server->on_accept = [&](NonnullOwnPtr<Core::LocalSocket> server_socket) { 382 // NOTE: For some reason LocalServer gives us a nonblocking socket..? 383 MUST(server_socket->set_blocking(true)); 384 385 EXPECT(MUST(server_socket->can_read_without_blocking(100))); 386 auto pending_bytes = MUST(server_socket->pending_bytes()); 387 auto maybe_receive_buffer = ByteBuffer::create_uninitialized(pending_bytes); 388 EXPECT(!maybe_receive_buffer.is_error()); 389 auto receive_buffer = maybe_receive_buffer.release_value(); 390 auto maybe_read_bytes = server_socket->read_some(receive_buffer); 391 EXPECT(!maybe_read_bytes.is_error()); 392 EXPECT_EQ(maybe_read_bytes.value().size(), sent_data.length()); 393 394 StringView received_data { maybe_read_bytes.value() }; 395 EXPECT_EQ(sent_data, received_data); 396 397 event_loop.quit(0); 398 event_loop.pump(); 399 }; 400 401 // NOTE: Same reason as in the local_socket_read test. 402 auto background_action = Threading::BackgroundAction<int>::construct( 403 [](auto&) { 404 auto maybe_client_socket = Core::LocalSocket::connect("/tmp/test-socket"); 405 EXPECT(!maybe_client_socket.is_error()); 406 auto client_socket = maybe_client_socket.release_value(); 407 408 EXPECT(!client_socket->write_until_depleted({ sent_data.characters_without_null_termination(), sent_data.length() }).is_error()); 409 client_socket->close(); 410 411 return 0; 412 }, 413 nullptr); 414 415 event_loop.exec(); 416 ::unlink("/tmp/test-socket"); 417} 418 419// Buffered stream tests 420 421TEST_CASE(buffered_long_file_read) 422{ 423 auto maybe_file = Core::File::open("/usr/Tests/LibCore/long_lines.txt"sv, Core::File::OpenMode::Read); 424 EXPECT(!maybe_file.is_error()); 425 auto maybe_buffered_file = Core::BufferedFile::create(maybe_file.release_value()); 426 EXPECT(!maybe_buffered_file.is_error()); 427 auto file = maybe_buffered_file.release_value(); 428 429 auto buffer = ByteBuffer::create_uninitialized(4096).release_value(); 430 EXPECT(!file->seek(255, SeekMode::SetPosition).is_error()); 431 EXPECT(file->can_read_line().release_value()); 432 auto maybe_line = file->read_line(buffer); 433 EXPECT(!maybe_line.is_error()); 434 EXPECT_EQ(maybe_line.value().length(), 4095ul); // 4095 bytes on the third line 435 436 // Testing that buffering with seeking works properly 437 EXPECT(!file->seek(365, SeekMode::SetPosition).is_error()); 438 auto maybe_after_seek_line = file->read_line(buffer); 439 EXPECT(!maybe_after_seek_line.is_error()); 440 EXPECT_EQ(maybe_after_seek_line.value().length(), 3985ul); // 4095 - 110 441} 442 443TEST_CASE(buffered_small_file_read) 444{ 445 auto maybe_file = Core::File::open("/usr/Tests/LibCore/small.txt"sv, Core::File::OpenMode::Read); 446 EXPECT(!maybe_file.is_error()); 447 auto maybe_buffered_file = Core::BufferedFile::create(maybe_file.release_value()); 448 EXPECT(!maybe_buffered_file.is_error()); 449 auto file = maybe_buffered_file.release_value(); 450 451 static constexpr StringView expected_lines[] { 452 "Well"sv, 453 "hello"sv, 454 "friends!"sv, 455 ":^)"sv 456 }; 457 458 // Testing that we don't read out of bounds when the entire file fits into the buffer 459 auto buffer = ByteBuffer::create_uninitialized(4096).release_value(); 460 for (auto const& line : expected_lines) { 461 VERIFY(file->can_read_line().release_value()); 462 auto maybe_read_line = file->read_line(buffer); 463 EXPECT(!maybe_read_line.is_error()); 464 EXPECT_EQ(maybe_read_line.value().length(), line.length()); 465 EXPECT_EQ(StringView(buffer.span().trim(maybe_read_line.value().length())), line); 466 } 467 EXPECT(!file->can_read_line().is_error()); 468 EXPECT(!file->can_read_line().value()); 469} 470 471TEST_CASE(buffered_file_tell_and_seek) 472{ 473 // We choose a buffer size of 12 bytes to cover half of the input file. 474 auto file = Core::File::open("/usr/Tests/LibCore/small.txt"sv, Core::File::OpenMode::Read).release_value(); 475 auto buffered_file = Core::BufferedFile::create(move(file), 12).release_value(); 476 477 // Initial state. 478 { 479 auto current_offset = buffered_file->tell().release_value(); 480 EXPECT_EQ(current_offset, 0ul); 481 } 482 483 // Read a character. 484 { 485 auto character = buffered_file->read_value<char>().release_value(); 486 EXPECT_EQ(character, 'W'); 487 auto current_offset = buffered_file->tell().release_value(); 488 EXPECT_EQ(current_offset, 1ul); 489 } 490 491 // Read one more character. 492 { 493 auto character = buffered_file->read_value<char>().release_value(); 494 EXPECT_EQ(character, 'e'); 495 auto current_offset = buffered_file->tell().release_value(); 496 EXPECT_EQ(current_offset, 2ul); 497 } 498 499 // Seek seven characters forward. 500 { 501 auto current_offset = buffered_file->seek(7, SeekMode::FromCurrentPosition).release_value(); 502 EXPECT_EQ(current_offset, 9ul); 503 } 504 505 // Read a character again. 506 { 507 auto character = buffered_file->read_value<char>().release_value(); 508 EXPECT_EQ(character, 'o'); 509 auto current_offset = buffered_file->tell().release_value(); 510 EXPECT_EQ(current_offset, 10ul); 511 } 512 513 // Seek five characters backwards. 514 { 515 auto current_offset = buffered_file->seek(-5, SeekMode::FromCurrentPosition).release_value(); 516 EXPECT_EQ(current_offset, 5ul); 517 } 518 519 // Read a character. 520 { 521 auto character = buffered_file->read_value<char>().release_value(); 522 EXPECT_EQ(character, 'h'); 523 auto current_offset = buffered_file->tell().release_value(); 524 EXPECT_EQ(current_offset, 6ul); 525 } 526 527 // Seek back to the beginning. 528 { 529 auto current_offset = buffered_file->seek(0, SeekMode::SetPosition).release_value(); 530 EXPECT_EQ(current_offset, 0ul); 531 } 532 533 // Read the first character. This should prime the buffer if it hasn't happened already. 534 { 535 auto character = buffered_file->read_value<char>().release_value(); 536 EXPECT_EQ(character, 'W'); 537 auto current_offset = buffered_file->tell().release_value(); 538 EXPECT_EQ(current_offset, 1ul); 539 } 540 541 // Seek beyond the buffer size, which should invalidate the buffer. 542 { 543 auto current_offset = buffered_file->seek(12, SeekMode::SetPosition).release_value(); 544 EXPECT_EQ(current_offset, 12ul); 545 } 546 547 // Ensure that we still read the correct contents from the new offset with a (presumably) freshly filled buffer. 548 { 549 auto character = buffered_file->read_value<char>().release_value(); 550 EXPECT_EQ(character, 'r'); 551 auto current_offset = buffered_file->tell().release_value(); 552 EXPECT_EQ(current_offset, 13ul); 553 } 554} 555 556constexpr auto buffered_sent_data = "Well hello friends!\n:^)\nThis shouldn't be present. :^("sv; 557constexpr auto first_line = "Well hello friends!"sv; 558constexpr auto second_line = ":^)"sv; 559 560TEST_CASE(buffered_tcp_socket_read) 561{ 562 Core::EventLoop event_loop; 563 564 auto maybe_tcp_server = Core::TCPServer::try_create(); 565 EXPECT(!maybe_tcp_server.is_error()); 566 auto tcp_server = maybe_tcp_server.release_value(); 567 EXPECT(!tcp_server->listen({ 127, 0, 0, 1 }, 9090).is_error()); 568 EXPECT(!tcp_server->set_blocking(true).is_error()); 569 570 auto maybe_client_socket = Core::TCPSocket::connect({ { 127, 0, 0, 1 }, 9090 }); 571 EXPECT(!maybe_client_socket.is_error()); 572 auto maybe_buffered_socket = Core::BufferedTCPSocket::create(maybe_client_socket.release_value()); 573 EXPECT(!maybe_buffered_socket.is_error()); 574 auto client_socket = maybe_buffered_socket.release_value(); 575 576 EXPECT(client_socket->is_open()); 577 578 auto maybe_server_socket = tcp_server->accept(); 579 EXPECT(!maybe_server_socket.is_error()); 580 auto server_socket = maybe_server_socket.release_value(); 581 EXPECT(!server_socket->write_some({ buffered_sent_data.characters_without_null_termination(), sent_data.length() }).is_error()); 582 583 EXPECT(client_socket->can_read_without_blocking(100).release_value()); 584 585 auto receive_buffer = ByteBuffer::create_uninitialized(64).release_value(); 586 587 auto maybe_first_received_line = client_socket->read_line(receive_buffer); 588 EXPECT(!maybe_first_received_line.is_error()); 589 auto first_received_line = maybe_first_received_line.value(); 590 EXPECT_EQ(first_received_line, first_line); 591 592 auto maybe_second_received_line = client_socket->read_line(receive_buffer); 593 EXPECT(!maybe_second_received_line.is_error()); 594 auto second_received_line = maybe_second_received_line.value(); 595 EXPECT_EQ(second_received_line, second_line); 596}