TestLibCoreStream.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498
  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 <LibCore/EventLoop.h>
  8. #include <LibCore/LocalServer.h>
  9. #include <LibCore/Stream.h>
  10. #include <LibCore/TCPServer.h>
  11. #include <LibCore/TCPSocket.h>
  12. #include <LibCore/Timer.h>
  13. #include <LibCore/UDPServer.h>
  14. #include <LibCore/UDPSocket.h>
  15. #include <LibTest/TestCase.h>
  16. #include <LibThreading/BackgroundAction.h>
  17. #include <fcntl.h>
  18. #include <unistd.h>
  19. // File tests
  20. TEST_CASE(file_open)
  21. {
  22. auto maybe_file = Core::Stream::File::open("/tmp/file-open-test.txt", Core::Stream::OpenMode::Write);
  23. if (maybe_file.is_error()) {
  24. warnln("Failed to open the file: {}", strerror(maybe_file.error().code()));
  25. VERIFY_NOT_REACHED();
  26. }
  27. // Testing out some basic file properties.
  28. auto file = maybe_file.release_value();
  29. EXPECT(file->is_open());
  30. EXPECT(!file->is_readable());
  31. EXPECT(file->is_writable());
  32. EXPECT(!file->is_eof());
  33. auto maybe_size = file->size();
  34. EXPECT(!maybe_size.is_error());
  35. EXPECT_EQ(maybe_size.value(), 0);
  36. }
  37. TEST_CASE(file_write_bytes)
  38. {
  39. auto maybe_file = Core::Stream::File::open("/tmp/file-write-bytes-test.txt", Core::Stream::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::Stream::File::open("/usr/Tests/LibCore/long_lines.txt", Core::Stream::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(), 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::Stream::File::open("/usr/Tests/LibCore/long_lines.txt", Core::Stream::OpenMode::Read);
  67. EXPECT(!maybe_file.is_error());
  68. auto file = maybe_file.release_value();
  69. EXPECT_EQ(file->size().release_value(), 8702);
  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, Core::Stream::SeekMode::SetPosition).is_error());
  75. EXPECT_EQ(file->tell().release_value(), 500);
  76. EXPECT(file->read_or_error(buffer));
  77. EXPECT_EQ(buffer_contents, expected_seek_contents1);
  78. EXPECT(!file->seek(234, Core::Stream::SeekMode::FromCurrentPosition).is_error());
  79. EXPECT_EQ(file->tell().release_value(), 750);
  80. EXPECT(file->read_or_error(buffer));
  81. EXPECT_EQ(buffer_contents, expected_seek_contents2);
  82. EXPECT(!file->seek(-105, Core::Stream::SeekMode::FromEndPosition).is_error());
  83. EXPECT_EQ(file->tell().release_value(), 8597);
  84. EXPECT(file->read_or_error(buffer));
  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::Stream::File::adopt_fd(rc, Core::Stream::OpenMode::Read);
  92. EXPECT(!maybe_file.is_error());
  93. auto file = maybe_file.release_value();
  94. EXPECT_EQ(file->size().release_value(), 8702);
  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, Core::Stream::SeekMode::SetPosition).is_error());
  100. EXPECT_EQ(file->tell().release_value(), 500);
  101. EXPECT(file->read_or_error(buffer));
  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::Stream::File::adopt_fd(-1, Core::Stream::OpenMode::Read);
  108. EXPECT(maybe_file.is_error());
  109. EXPECT_EQ(maybe_file.error().code(), EBADF);
  110. }
  111. // TCPSocket tests
  112. TEST_CASE(should_error_when_connection_fails)
  113. {
  114. // NOTE: This is required here because Core::TCPSocket requires
  115. // Core::EventLoop through Core::Notifier.
  116. Core::EventLoop event_loop;
  117. auto maybe_tcp_socket = Core::Stream::TCPSocket::connect({ { 127, 0, 0, 1 }, 1234 });
  118. EXPECT(maybe_tcp_socket.is_error());
  119. EXPECT(maybe_tcp_socket.error().is_syscall());
  120. EXPECT(maybe_tcp_socket.error().code() == ECONNREFUSED);
  121. }
  122. constexpr auto sent_data = "Mr. Watson, come here. I want to see you."sv;
  123. TEST_CASE(tcp_socket_read)
  124. {
  125. // NOTE: This is required here because Core::TCPServer requires
  126. // Core::EventLoop through Core::Notifier.
  127. Core::EventLoop event_loop;
  128. auto maybe_tcp_server = Core::TCPServer::try_create();
  129. EXPECT(!maybe_tcp_server.is_error());
  130. auto tcp_server = maybe_tcp_server.release_value();
  131. EXPECT(!tcp_server->listen({ 127, 0, 0, 1 }, 9090).is_error());
  132. EXPECT(!tcp_server->set_blocking(true).is_error());
  133. auto maybe_client_socket = Core::Stream::TCPSocket::connect({ { 127, 0, 0, 1 }, 9090 });
  134. EXPECT(!maybe_client_socket.is_error());
  135. auto client_socket = maybe_client_socket.release_value();
  136. EXPECT(client_socket->is_open());
  137. auto maybe_server_socket = tcp_server->accept();
  138. EXPECT(!maybe_server_socket.is_error());
  139. auto server_socket = maybe_server_socket.release_value();
  140. EXPECT(!server_socket->write({ sent_data.characters_without_null_termination(), sent_data.length() }).is_error());
  141. server_socket->close();
  142. EXPECT(client_socket->can_read_without_blocking(100).release_value());
  143. EXPECT_EQ(client_socket->pending_bytes().release_value(), sent_data.length());
  144. auto maybe_receive_buffer = ByteBuffer::create_uninitialized(64);
  145. EXPECT(!maybe_receive_buffer.is_error());
  146. auto receive_buffer = maybe_receive_buffer.release_value();
  147. auto maybe_nread = client_socket->read(receive_buffer);
  148. EXPECT(!maybe_nread.is_error());
  149. auto nread = maybe_nread.release_value();
  150. StringView received_data { receive_buffer.data(), nread };
  151. EXPECT_EQ(sent_data, received_data);
  152. }
  153. TEST_CASE(tcp_socket_write)
  154. {
  155. Core::EventLoop event_loop;
  156. auto maybe_tcp_server = Core::TCPServer::try_create();
  157. EXPECT(!maybe_tcp_server.is_error());
  158. auto tcp_server = maybe_tcp_server.release_value();
  159. EXPECT(!tcp_server->listen({ 127, 0, 0, 1 }, 9090).is_error());
  160. EXPECT(!tcp_server->set_blocking(true).is_error());
  161. auto maybe_client_socket = Core::Stream::TCPSocket::connect({ { 127, 0, 0, 1 }, 9090 });
  162. EXPECT(!maybe_client_socket.is_error());
  163. auto client_socket = maybe_client_socket.release_value();
  164. auto maybe_server_socket = tcp_server->accept();
  165. EXPECT(!maybe_server_socket.is_error());
  166. auto server_socket = maybe_server_socket.release_value();
  167. EXPECT(!server_socket->set_blocking(true).is_error());
  168. EXPECT(client_socket->write_or_error({ sent_data.characters_without_null_termination(), sent_data.length() }));
  169. client_socket->close();
  170. auto maybe_receive_buffer = ByteBuffer::create_uninitialized(64);
  171. EXPECT(!maybe_receive_buffer.is_error());
  172. auto receive_buffer = maybe_receive_buffer.release_value();
  173. auto maybe_nread = server_socket->read(receive_buffer);
  174. EXPECT(!maybe_nread.is_error());
  175. auto nread = maybe_nread.release_value();
  176. StringView received_data { receive_buffer.data(), nread };
  177. EXPECT_EQ(sent_data, received_data);
  178. }
  179. TEST_CASE(tcp_socket_eof)
  180. {
  181. Core::EventLoop event_loop;
  182. auto maybe_tcp_server = Core::TCPServer::try_create();
  183. EXPECT(!maybe_tcp_server.is_error());
  184. auto tcp_server = maybe_tcp_server.release_value();
  185. EXPECT(!tcp_server->listen({ 127, 0, 0, 1 }, 9090).is_error());
  186. EXPECT(!tcp_server->set_blocking(true).is_error());
  187. auto maybe_client_socket = Core::Stream::TCPSocket::connect({ { 127, 0, 0, 1 }, 9090 });
  188. EXPECT(!maybe_client_socket.is_error());
  189. auto client_socket = maybe_client_socket.release_value();
  190. EXPECT(client_socket->is_open());
  191. auto server_socket = tcp_server->accept().release_value();
  192. server_socket->close();
  193. // NOTE: This may seem unintuitive, but poll will mark a fd which has
  194. // reached EOF (i.e. in the case of the other side disconnecting) as
  195. // POLLIN.
  196. EXPECT(client_socket->can_read_without_blocking(100).release_value());
  197. EXPECT_EQ(client_socket->pending_bytes().release_value(), 0ul);
  198. auto maybe_receive_buffer = ByteBuffer::create_uninitialized(1);
  199. EXPECT(!maybe_receive_buffer.is_error());
  200. auto receive_buffer = maybe_receive_buffer.release_value();
  201. EXPECT_EQ(client_socket->read(receive_buffer).release_value(), 0ul);
  202. EXPECT(client_socket->is_eof());
  203. }
  204. // UDPSocket tests
  205. constexpr auto udp_reply_data = "Well hello friends!"sv;
  206. TEST_CASE(udp_socket_read_write)
  207. {
  208. // NOTE: This is required here because Core::UDPServer requires
  209. // Core::EventLoop through Core::Notifier.
  210. Core::EventLoop event_loop;
  211. auto udp_server = Core::UDPServer::construct();
  212. EXPECT(udp_server->bind({ 127, 0, 0, 1 }, 9090));
  213. auto maybe_client_socket = Core::Stream::UDPSocket::connect({ { 127, 0, 0, 1 }, 9090 });
  214. EXPECT(!maybe_client_socket.is_error());
  215. auto client_socket = maybe_client_socket.release_value();
  216. EXPECT(client_socket->is_open());
  217. EXPECT(client_socket->write_or_error({ sent_data.characters_without_null_termination(), sent_data.length() }));
  218. // FIXME: UDPServer::receive sadly doesn't give us a way to block on it,
  219. // currently.
  220. usleep(100000);
  221. struct sockaddr_in client_address;
  222. auto server_receive_buffer = udp_server->receive(64, client_address);
  223. EXPECT(!server_receive_buffer.is_empty());
  224. StringView server_received_data { server_receive_buffer.bytes() };
  225. EXPECT_EQ(server_received_data, sent_data);
  226. EXPECT(!udp_server->send({ udp_reply_data.characters_without_null_termination(), udp_reply_data.length() }, client_address).is_error());
  227. EXPECT(client_socket->can_read_without_blocking(100).release_value());
  228. EXPECT_EQ(client_socket->pending_bytes().release_value(), udp_reply_data.length());
  229. // Testing that supplying a smaller buffer than required causes a failure.
  230. auto small_buffer = ByteBuffer::create_uninitialized(8).release_value();
  231. EXPECT_EQ(client_socket->read(small_buffer).error().code(), EMSGSIZE);
  232. auto maybe_client_receive_buffer = ByteBuffer::create_uninitialized(64);
  233. EXPECT(!maybe_client_receive_buffer.is_error());
  234. auto client_receive_buffer = maybe_client_receive_buffer.release_value();
  235. auto maybe_nread = client_socket->read(client_receive_buffer);
  236. EXPECT(!maybe_nread.is_error());
  237. auto nread = maybe_nread.release_value();
  238. StringView client_received_data { client_receive_buffer.data(), nread };
  239. EXPECT_EQ(udp_reply_data, client_received_data);
  240. }
  241. // LocalSocket tests
  242. TEST_CASE(local_socket_read)
  243. {
  244. Core::EventLoop event_loop;
  245. auto local_server = Core::LocalServer::construct();
  246. EXPECT(local_server->listen("/tmp/test-socket"));
  247. local_server->on_accept = [&](NonnullOwnPtr<Core::Stream::LocalSocket> server_socket) {
  248. EXPECT(!server_socket->write(sent_data.bytes()).is_error());
  249. event_loop.quit(0);
  250. event_loop.pump();
  251. };
  252. // NOTE: Doing this on another thread, because otherwise we're at an
  253. // impasse. LocalSocket::connect blocks because there's nobody to
  254. // accept, and LocalServer::accept blocks because there's nobody
  255. // connected.
  256. auto background_action = Threading::BackgroundAction<int>::construct(
  257. [](auto&) {
  258. Core::EventLoop event_loop;
  259. auto maybe_client_socket = Core::Stream::LocalSocket::connect("/tmp/test-socket");
  260. EXPECT(!maybe_client_socket.is_error());
  261. auto client_socket = maybe_client_socket.release_value();
  262. EXPECT(client_socket->is_open());
  263. EXPECT(client_socket->can_read_without_blocking(100).release_value());
  264. EXPECT_EQ(client_socket->pending_bytes().release_value(), sent_data.length());
  265. auto maybe_receive_buffer = ByteBuffer::create_uninitialized(64);
  266. EXPECT(!maybe_receive_buffer.is_error());
  267. auto receive_buffer = maybe_receive_buffer.release_value();
  268. auto maybe_nread = client_socket->read(receive_buffer);
  269. EXPECT(!maybe_nread.is_error());
  270. auto nread = maybe_nread.release_value();
  271. StringView received_data { receive_buffer.data(), nread };
  272. EXPECT_EQ(sent_data, received_data);
  273. return 0;
  274. },
  275. nullptr);
  276. event_loop.exec();
  277. ::unlink("/tmp/test-socket");
  278. }
  279. TEST_CASE(local_socket_write)
  280. {
  281. Core::EventLoop event_loop;
  282. auto local_server = Core::LocalServer::construct();
  283. EXPECT(local_server->listen("/tmp/test-socket"));
  284. local_server->on_accept = [&](NonnullOwnPtr<Core::Stream::LocalSocket> server_socket) {
  285. // NOTE: For some reason LocalServer gives us a nonblocking socket..?
  286. MUST(server_socket->set_blocking(true));
  287. EXPECT(MUST(server_socket->can_read_without_blocking(100)));
  288. auto pending_bytes = MUST(server_socket->pending_bytes());
  289. auto maybe_receive_buffer = ByteBuffer::create_uninitialized(pending_bytes);
  290. EXPECT(!maybe_receive_buffer.is_error());
  291. auto receive_buffer = maybe_receive_buffer.release_value();
  292. auto maybe_nread = server_socket->read(receive_buffer);
  293. EXPECT(!maybe_nread.is_error());
  294. EXPECT_EQ(maybe_nread.value(), sent_data.length());
  295. StringView received_data { receive_buffer.data(), maybe_nread.value() };
  296. EXPECT_EQ(sent_data, received_data);
  297. event_loop.quit(0);
  298. event_loop.pump();
  299. };
  300. // NOTE: Same reason as in the local_socket_read test.
  301. auto background_action = Threading::BackgroundAction<int>::construct(
  302. [](auto&) {
  303. auto maybe_client_socket = Core::Stream::LocalSocket::connect("/tmp/test-socket");
  304. EXPECT(!maybe_client_socket.is_error());
  305. auto client_socket = maybe_client_socket.release_value();
  306. EXPECT(client_socket->write_or_error({ sent_data.characters_without_null_termination(), sent_data.length() }));
  307. client_socket->close();
  308. return 0;
  309. },
  310. nullptr);
  311. event_loop.exec();
  312. ::unlink("/tmp/test-socket");
  313. }
  314. // Buffered stream tests
  315. TEST_CASE(buffered_long_file_read)
  316. {
  317. auto maybe_file = Core::Stream::File::open("/usr/Tests/LibCore/long_lines.txt", Core::Stream::OpenMode::Read);
  318. EXPECT(!maybe_file.is_error());
  319. auto maybe_buffered_file = Core::Stream::BufferedFile::create(maybe_file.release_value());
  320. EXPECT(!maybe_buffered_file.is_error());
  321. auto file = maybe_buffered_file.release_value();
  322. auto buffer = ByteBuffer::create_uninitialized(4096).release_value();
  323. EXPECT(!file->seek(255, Core::Stream::SeekMode::SetPosition).is_error());
  324. EXPECT(file->can_read_line().release_value());
  325. auto maybe_nread = file->read_line(buffer);
  326. EXPECT(!maybe_nread.is_error());
  327. EXPECT_EQ(maybe_nread.value(), 4095ul); // 4095 bytes on the third line
  328. // Testing that buffering with seeking works properly
  329. EXPECT(!file->seek(365, Core::Stream::SeekMode::SetPosition).is_error());
  330. auto maybe_after_seek_nread = file->read_line(buffer);
  331. EXPECT(!maybe_after_seek_nread.is_error());
  332. EXPECT_EQ(maybe_after_seek_nread.value(), 3985ul); // 4095 - 110
  333. }
  334. TEST_CASE(buffered_small_file_read)
  335. {
  336. auto maybe_file = Core::Stream::File::open("/usr/Tests/LibCore/small.txt", Core::Stream::OpenMode::Read);
  337. EXPECT(!maybe_file.is_error());
  338. auto maybe_buffered_file = Core::Stream::BufferedFile::create(maybe_file.release_value());
  339. EXPECT(!maybe_buffered_file.is_error());
  340. auto file = maybe_buffered_file.release_value();
  341. static constexpr StringView expected_lines[] {
  342. "Well"sv,
  343. "hello"sv,
  344. "friends!"sv,
  345. ":^)"sv
  346. };
  347. // Testing that we don't read out of bounds when the entire file fits into the buffer
  348. auto buffer = ByteBuffer::create_uninitialized(4096).release_value();
  349. for (auto const& line : expected_lines) {
  350. VERIFY(file->can_read_line().release_value());
  351. auto maybe_nread = file->read_line(buffer);
  352. EXPECT(!maybe_nread.is_error());
  353. EXPECT_EQ(maybe_nread.value(), line.length());
  354. EXPECT_EQ(StringView(buffer.span().trim(maybe_nread.value())), line);
  355. }
  356. EXPECT(!file->can_read_line().is_error());
  357. EXPECT(!file->can_read_line().value());
  358. }
  359. constexpr auto buffered_sent_data = "Well hello friends!\n:^)\nThis shouldn't be present. :^("sv;
  360. constexpr auto first_line = "Well hello friends!"sv;
  361. constexpr auto second_line = ":^)"sv;
  362. TEST_CASE(buffered_tcp_socket_read)
  363. {
  364. Core::EventLoop event_loop;
  365. auto maybe_tcp_server = Core::TCPServer::try_create();
  366. EXPECT(!maybe_tcp_server.is_error());
  367. auto tcp_server = maybe_tcp_server.release_value();
  368. EXPECT(!tcp_server->listen({ 127, 0, 0, 1 }, 9090).is_error());
  369. EXPECT(!tcp_server->set_blocking(true).is_error());
  370. auto maybe_client_socket = Core::Stream::TCPSocket::connect({ { 127, 0, 0, 1 }, 9090 });
  371. EXPECT(!maybe_client_socket.is_error());
  372. auto maybe_buffered_socket = Core::Stream::BufferedTCPSocket::create(maybe_client_socket.release_value());
  373. EXPECT(!maybe_buffered_socket.is_error());
  374. auto client_socket = maybe_buffered_socket.release_value();
  375. EXPECT(client_socket->is_open());
  376. auto maybe_server_socket = tcp_server->accept();
  377. EXPECT(!maybe_server_socket.is_error());
  378. auto server_socket = maybe_server_socket.release_value();
  379. EXPECT(!server_socket->write({ buffered_sent_data.characters_without_null_termination(), sent_data.length() }).is_error());
  380. EXPECT(client_socket->can_read_without_blocking(100).release_value());
  381. auto receive_buffer = ByteBuffer::create_uninitialized(64).release_value();
  382. auto maybe_first_nread = client_socket->read_line(receive_buffer);
  383. EXPECT(!maybe_first_nread.is_error());
  384. StringView first_received_line { receive_buffer.data(), maybe_first_nread.value() };
  385. EXPECT_EQ(first_received_line, first_line);
  386. auto maybe_second_nread = client_socket->read_line(receive_buffer);
  387. EXPECT(!maybe_second_nread.is_error());
  388. StringView second_received_line { receive_buffer.data(), maybe_second_nread.value() };
  389. EXPECT_EQ(second_received_line, second_line);
  390. }