TestLibCoreStream.cpp 22 KB

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