stream_test.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532
  1. #include <furi.h>
  2. #include <toolbox/stream/stream.h>
  3. #include <toolbox/stream/string_stream.h>
  4. #include <toolbox/stream/file_stream.h>
  5. #include <toolbox/stream/buffered_file_stream.h>
  6. #include <storage/storage.h>
  7. #include "../minunit.h"
  8. static const char* stream_test_data = "I write differently from what I speak, "
  9. "I speak differently from what I think, "
  10. "I think differently from the way I ought to think, "
  11. "and so it all proceeds into deepest darkness.";
  12. static const char* stream_test_left_data = "There are two cardinal human sins ";
  13. static const char* stream_test_right_data =
  14. "from which all others derive: impatience and indolence.";
  15. MU_TEST_1(stream_composite_subtest, Stream* stream) {
  16. const size_t data_size = 128;
  17. uint8_t data[data_size];
  18. FuriString* string_lee;
  19. string_lee = furi_string_alloc_set("lee");
  20. // test that stream is empty
  21. // "" -> ""
  22. mu_check(stream_size(stream) == 0);
  23. mu_check(stream_eof(stream));
  24. mu_check(stream_tell(stream) == 0);
  25. mu_check(stream_read(stream, data, data_size) == 0);
  26. mu_check(stream_eof(stream));
  27. mu_check(stream_tell(stream) == 0);
  28. // write char
  29. // "" -> "2"
  30. mu_check(stream_write_char(stream, '2') == 1);
  31. mu_check(stream_size(stream) == 1);
  32. mu_check(stream_tell(stream) == 1);
  33. mu_check(stream_eof(stream));
  34. // test rewind and eof
  35. stream_rewind(stream);
  36. mu_check(stream_size(stream) == 1);
  37. mu_check(stream_tell(stream) == 0);
  38. mu_check(!stream_eof(stream));
  39. // add another char with replacement
  40. // "2" -> "1"
  41. mu_check(stream_write_char(stream, '1') == 1);
  42. mu_check(stream_size(stream) == 1);
  43. mu_check(stream_tell(stream) == 1);
  44. mu_check(stream_eof(stream));
  45. // write string
  46. // "1" -> "1337_69"
  47. mu_check(stream_write_cstring(stream, "337_69") == 6);
  48. mu_check(stream_size(stream) == 7);
  49. mu_check(stream_tell(stream) == 7);
  50. mu_check(stream_eof(stream));
  51. // read data
  52. memset(data, 0, data_size);
  53. stream_rewind(stream);
  54. mu_check(stream_read(stream, data, data_size) == 7);
  55. mu_check(strcmp((char*)data, "1337_69") == 0);
  56. // test misc seeks
  57. mu_check(stream_seek(stream, 2, StreamOffsetFromStart));
  58. mu_check(stream_tell(stream) == 2);
  59. mu_check(!stream_seek(stream, 9000, StreamOffsetFromStart));
  60. mu_check(stream_tell(stream) == 7);
  61. mu_check(stream_eof(stream));
  62. mu_check(stream_seek(stream, -3, StreamOffsetFromEnd));
  63. mu_check(stream_tell(stream) == 4);
  64. // test seeks to char. content: '1337_69'
  65. stream_rewind(stream);
  66. mu_check(stream_seek_to_char(stream, '3', StreamDirectionForward));
  67. mu_check(stream_tell(stream) == 1);
  68. mu_check(stream_seek_to_char(stream, '3', StreamDirectionForward));
  69. mu_check(stream_tell(stream) == 2);
  70. mu_check(stream_seek_to_char(stream, '_', StreamDirectionForward));
  71. mu_check(stream_tell(stream) == 4);
  72. mu_check(stream_seek_to_char(stream, '9', StreamDirectionForward));
  73. mu_check(stream_tell(stream) == 6);
  74. mu_check(!stream_seek_to_char(stream, '9', StreamDirectionForward));
  75. mu_check(stream_tell(stream) == 6);
  76. mu_check(stream_seek_to_char(stream, '_', StreamDirectionBackward));
  77. mu_check(stream_tell(stream) == 4);
  78. mu_check(stream_seek_to_char(stream, '3', StreamDirectionBackward));
  79. mu_check(stream_tell(stream) == 2);
  80. mu_check(stream_seek_to_char(stream, '3', StreamDirectionBackward));
  81. mu_check(stream_tell(stream) == 1);
  82. mu_check(!stream_seek_to_char(stream, '3', StreamDirectionBackward));
  83. mu_check(stream_tell(stream) == 1);
  84. mu_check(stream_seek_to_char(stream, '1', StreamDirectionBackward));
  85. mu_check(stream_tell(stream) == 0);
  86. // write string with replacement
  87. // "1337_69" -> "1337lee"
  88. mu_check(stream_seek(stream, 4, StreamOffsetFromStart));
  89. mu_check(stream_write_string(stream, string_lee) == 3);
  90. mu_check(stream_size(stream) == 7);
  91. mu_check(stream_tell(stream) == 7);
  92. mu_check(stream_eof(stream));
  93. // append char
  94. // "1337lee" -> "1337leet"
  95. mu_check(stream_write(stream, (uint8_t*)"t", 1) == 1);
  96. mu_check(stream_size(stream) == 8);
  97. mu_check(stream_tell(stream) == 8);
  98. mu_check(stream_eof(stream));
  99. // read data
  100. memset(data, 0, data_size);
  101. stream_rewind(stream);
  102. mu_check(stream_read(stream, data, data_size) == 8);
  103. mu_check(strcmp((char*)data, "1337leet") == 0);
  104. mu_check(stream_tell(stream) == 8);
  105. mu_check(stream_eof(stream));
  106. // negative seek from current position -> clamp to 0
  107. mu_check(!stream_seek(stream, -9000, StreamOffsetFromCurrent));
  108. mu_check(stream_tell(stream) == 0);
  109. // negative seek from start position -> clamp to 0
  110. stream_rewind(stream);
  111. mu_check(!stream_seek(stream, -3, StreamOffsetFromStart));
  112. mu_check(stream_tell(stream) == 0);
  113. // zero seek from current position -> clamp to stream size
  114. mu_check(stream_seek(stream, 0, StreamOffsetFromEnd));
  115. mu_check(stream_tell(stream) == 8);
  116. // negative seek from end position -> clamp to 0
  117. mu_check(!stream_seek(stream, -9000, StreamOffsetFromEnd));
  118. mu_check(stream_tell(stream) == 0);
  119. // clean stream
  120. stream_clean(stream);
  121. mu_check(stream_size(stream) == 0);
  122. mu_check(stream_eof(stream));
  123. mu_check(stream_tell(stream) == 0);
  124. // write format
  125. // "" -> "dio666"
  126. mu_check(stream_write_format(stream, "%s%d", "dio", 666) == 6);
  127. mu_check(stream_size(stream) == 6);
  128. mu_check(stream_eof(stream));
  129. mu_check(stream_tell(stream) == 6);
  130. // read data
  131. memset(data, 0, data_size);
  132. stream_rewind(stream);
  133. mu_check(stream_read(stream, data, data_size) == 6);
  134. mu_check(strcmp((char*)data, "dio666") == 0);
  135. // clean and write cstring
  136. // "dio666" -> "" -> "1234567890"
  137. stream_clean(stream);
  138. mu_check(stream_write_cstring(stream, "1234567890") == 10);
  139. // delete 4 bytes from 1 pos
  140. // "1xxxx67890" -> "167890"
  141. mu_check(stream_seek(stream, 1, StreamOffsetFromStart));
  142. mu_check(stream_delete(stream, 4));
  143. mu_assert_int_eq(6, stream_size(stream));
  144. // read data
  145. memset(data, 0, data_size);
  146. stream_rewind(stream);
  147. mu_assert_int_eq(6, stream_read(stream, data, data_size));
  148. mu_check(strcmp((char*)data, "167890") == 0);
  149. // write cstring
  150. // "167890" -> "167890It Was Me, Dio!"
  151. mu_check(stream_write_cstring(stream, "It Was Me, Dio!") == 15);
  152. // delete 1337 bytes from 1 pos
  153. // and check that we can delete only 20 bytes
  154. // "1xxxxxxxxxxxxxxxxxxxx" -> "1"
  155. mu_check(stream_seek(stream, 1, StreamOffsetFromStart));
  156. mu_check(stream_delete(stream, 1337));
  157. mu_assert_int_eq(1, stream_size(stream));
  158. // read data
  159. memset(data, 0, data_size);
  160. stream_rewind(stream);
  161. mu_check(stream_read(stream, data, data_size) == 1);
  162. mu_check(strcmp((char*)data, "1") == 0);
  163. // write cstring from 0 pos, replacing 1 byte
  164. // "1" -> "Oh? You're roaching me?"
  165. mu_check(stream_rewind(stream));
  166. mu_assert_int_eq(23, stream_write_cstring(stream, "Oh? You're roaching me?"));
  167. // insert 11 bytes to 0 pos
  168. // "Oh? You're roaching me?" -> "Za Warudo! Oh? You're roaching me?"
  169. mu_check(stream_rewind(stream));
  170. mu_check(stream_insert(stream, (uint8_t*)"Za Warudo! ", 11));
  171. mu_assert_int_eq(34, stream_size(stream));
  172. // read data
  173. memset(data, 0, data_size);
  174. stream_rewind(stream);
  175. mu_assert_int_eq(34, stream_read(stream, data, data_size));
  176. mu_assert_string_eq("Za Warudo! Oh? You're roaching me?", (char*)data);
  177. // insert cstring to 22 pos
  178. // "Za Warudo! Oh? You're roaching me?" -> "Za Warudo! Oh? You're approaching me?"
  179. mu_check(stream_seek(stream, 22, StreamOffsetFromStart));
  180. mu_check(stream_insert_cstring(stream, "app"));
  181. mu_assert_int_eq(37, stream_size(stream));
  182. // read data
  183. memset(data, 0, data_size);
  184. stream_rewind(stream);
  185. mu_assert_int_eq(37, stream_read(stream, data, data_size));
  186. mu_assert_string_eq("Za Warudo! Oh? You're approaching me?", (char*)data);
  187. // insert cstring to the end of the stream
  188. // "Za Warudo! Oh? You're approaching me?" -> "Za Warudo! Oh? You're approaching me? It was me, Dio!"
  189. mu_check(stream_seek(stream, 0, StreamOffsetFromEnd));
  190. mu_check(stream_insert_cstring(stream, " It was me, Dio!"));
  191. mu_assert_int_eq(53, stream_size(stream));
  192. // read data
  193. memset(data, 0, data_size);
  194. stream_rewind(stream);
  195. mu_assert_int_eq(53, stream_read(stream, data, data_size));
  196. mu_assert_string_eq("Za Warudo! Oh? You're approaching me? It was me, Dio!", (char*)data);
  197. // delete 168430090 bytes from stream
  198. // and test that we can delete only 53
  199. mu_check(stream_rewind(stream));
  200. mu_check(stream_delete(stream, 0x0A0A0A0A));
  201. mu_assert_int_eq(0, stream_size(stream));
  202. mu_check(stream_eof(stream));
  203. mu_assert_int_eq(0, stream_tell(stream));
  204. // clean stream
  205. stream_clean(stream);
  206. mu_assert_int_eq(0, stream_size(stream));
  207. mu_check(stream_eof(stream));
  208. mu_assert_int_eq(0, stream_tell(stream));
  209. // insert formatted string at the end of stream
  210. // "" -> "dio666"
  211. mu_check(stream_insert_format(stream, "%s%d", "dio", 666));
  212. mu_assert_int_eq(6, stream_size(stream));
  213. mu_check(stream_eof(stream));
  214. mu_assert_int_eq(6, stream_tell(stream));
  215. // insert formatted string at the end of stream
  216. // "dio666" -> "dio666zlo555"
  217. mu_check(stream_insert_format(stream, "%s%d", "zlo", 555));
  218. mu_assert_int_eq(12, stream_size(stream));
  219. mu_check(stream_eof(stream));
  220. mu_assert_int_eq(12, stream_tell(stream));
  221. // insert formatted string at the 6 pos
  222. // "dio666" -> "dio666baba13zlo555"
  223. mu_check(stream_seek(stream, 6, StreamOffsetFromStart));
  224. mu_check(stream_insert_format(stream, "%s%d", "baba", 13));
  225. mu_assert_int_eq(18, stream_size(stream));
  226. mu_assert_int_eq(12, stream_tell(stream));
  227. // read data
  228. memset(data, 0, data_size);
  229. stream_rewind(stream);
  230. mu_assert_int_eq(18, stream_read(stream, data, data_size));
  231. mu_assert_string_eq("dio666baba13zlo555", (char*)data);
  232. // delete 6 chars from pos 6 and insert 1 chars
  233. // "dio666baba13zlo555" -> "dio666xzlo555"
  234. mu_check(stream_seek(stream, 6, StreamOffsetFromStart));
  235. mu_check(stream_delete_and_insert_char(stream, 6, 'x'));
  236. mu_assert_int_eq(13, stream_size(stream));
  237. mu_assert_int_eq(7, stream_tell(stream));
  238. // read data
  239. memset(data, 0, data_size);
  240. stream_rewind(stream);
  241. mu_check(stream_read(stream, data, data_size) == 13);
  242. mu_assert_string_eq("dio666xzlo555", (char*)data);
  243. // delete 9000 chars from pos 6 and insert 3 chars from string
  244. // "dio666xzlo555" -> "dio666777"
  245. mu_check(stream_seek(stream, 6, StreamOffsetFromStart));
  246. mu_check(stream_delete_and_insert_cstring(stream, 9000, "777"));
  247. mu_assert_int_eq(9, stream_size(stream));
  248. mu_assert_int_eq(9, stream_tell(stream));
  249. mu_check(stream_eof(stream));
  250. furi_string_free(string_lee);
  251. }
  252. MU_TEST(stream_composite_test) {
  253. // test string stream
  254. Stream* stream;
  255. stream = string_stream_alloc();
  256. MU_RUN_TEST_1(stream_composite_subtest, stream);
  257. stream_free(stream);
  258. // test file stream
  259. Storage* storage = furi_record_open(RECORD_STORAGE);
  260. stream = file_stream_alloc(storage);
  261. mu_check(
  262. file_stream_open(stream, EXT_PATH("filestream.str"), FSAM_READ_WRITE, FSOM_CREATE_ALWAYS));
  263. MU_RUN_TEST_1(stream_composite_subtest, stream);
  264. stream_free(stream);
  265. // test buffered file stream
  266. stream = buffered_file_stream_alloc(storage);
  267. mu_check(buffered_file_stream_open(
  268. stream, EXT_PATH("filestream.str"), FSAM_READ_WRITE, FSOM_CREATE_ALWAYS));
  269. MU_RUN_TEST_1(stream_composite_subtest, stream);
  270. stream_free(stream);
  271. furi_record_close(RECORD_STORAGE);
  272. }
  273. MU_TEST_1(stream_write_subtest, Stream* stream) {
  274. mu_assert_int_eq(strlen(stream_test_data), stream_write_cstring(stream, stream_test_data));
  275. }
  276. MU_TEST_1(stream_read_subtest, Stream* stream) {
  277. uint8_t data[256] = {0};
  278. mu_check(stream_rewind(stream));
  279. mu_assert_int_eq(strlen(stream_test_data), stream_read(stream, data, 256));
  280. mu_assert_string_eq(stream_test_data, (const char*)data);
  281. }
  282. MU_TEST(stream_write_read_save_load_test) {
  283. Stream* stream_orig = string_stream_alloc();
  284. Stream* stream_copy = string_stream_alloc();
  285. Storage* storage = furi_record_open(RECORD_STORAGE);
  286. // write, read
  287. MU_RUN_TEST_1(stream_write_subtest, stream_orig);
  288. MU_RUN_TEST_1(stream_read_subtest, stream_orig);
  289. // copy, read
  290. mu_assert_int_eq(strlen(stream_test_data), stream_copy_full(stream_orig, stream_copy));
  291. MU_RUN_TEST_1(stream_read_subtest, stream_orig);
  292. // save to file
  293. mu_check(stream_seek(stream_orig, 0, StreamOffsetFromStart));
  294. mu_assert_int_eq(
  295. strlen(stream_test_data),
  296. stream_save_to_file(stream_orig, storage, EXT_PATH("filestream.str"), FSOM_CREATE_ALWAYS));
  297. stream_free(stream_copy);
  298. stream_free(stream_orig);
  299. // load from file, read
  300. Stream* stream_new = string_stream_alloc();
  301. mu_assert_int_eq(
  302. strlen(stream_test_data),
  303. stream_load_from_file(stream_new, storage, EXT_PATH("filestream.str")));
  304. MU_RUN_TEST_1(stream_read_subtest, stream_new);
  305. stream_free(stream_new);
  306. furi_record_close(RECORD_STORAGE);
  307. }
  308. MU_TEST_1(stream_split_subtest, Stream* stream) {
  309. stream_clean(stream);
  310. stream_write_cstring(stream, stream_test_left_data);
  311. stream_write_cstring(stream, stream_test_right_data);
  312. Stream* stream_left = string_stream_alloc();
  313. Stream* stream_right = string_stream_alloc();
  314. mu_check(stream_seek(stream, strlen(stream_test_left_data), StreamOffsetFromStart));
  315. mu_check(stream_split(stream, stream_left, stream_right));
  316. uint8_t data[256] = {0};
  317. mu_check(stream_rewind(stream_left));
  318. mu_assert_int_eq(strlen(stream_test_left_data), stream_read(stream_left, data, 256));
  319. mu_assert_string_eq(stream_test_left_data, (const char*)data);
  320. mu_check(stream_rewind(stream_right));
  321. mu_assert_int_eq(strlen(stream_test_right_data), stream_read(stream_right, data, 256));
  322. mu_assert_string_eq(stream_test_right_data, (const char*)data);
  323. stream_free(stream_right);
  324. stream_free(stream_left);
  325. }
  326. MU_TEST(stream_split_test) {
  327. // test string stream
  328. Stream* stream;
  329. stream = string_stream_alloc();
  330. MU_RUN_TEST_1(stream_split_subtest, stream);
  331. stream_free(stream);
  332. // test file stream
  333. Storage* storage = furi_record_open(RECORD_STORAGE);
  334. stream = file_stream_alloc(storage);
  335. mu_check(
  336. file_stream_open(stream, EXT_PATH("filestream.str"), FSAM_READ_WRITE, FSOM_CREATE_ALWAYS));
  337. MU_RUN_TEST_1(stream_split_subtest, stream);
  338. stream_free(stream);
  339. // test buffered stream
  340. stream = buffered_file_stream_alloc(storage);
  341. mu_check(buffered_file_stream_open(
  342. stream, EXT_PATH("filestream.str"), FSAM_READ_WRITE, FSOM_CREATE_ALWAYS));
  343. MU_RUN_TEST_1(stream_split_subtest, stream);
  344. stream_free(stream);
  345. furi_record_close(RECORD_STORAGE);
  346. }
  347. MU_TEST(stream_buffered_write_after_read_test) {
  348. const char* prefix = "I write ";
  349. const char* substr = "Hello there";
  350. const size_t substr_len = strlen(substr);
  351. const size_t prefix_len = strlen(prefix);
  352. const size_t buf_size = substr_len + 1;
  353. char buf[buf_size];
  354. memset(buf, 0, buf_size);
  355. Storage* storage = furi_record_open(RECORD_STORAGE);
  356. Stream* stream = buffered_file_stream_alloc(storage);
  357. mu_check(buffered_file_stream_open(
  358. stream, EXT_PATH("filestream.str"), FSAM_READ_WRITE, FSOM_CREATE_ALWAYS));
  359. mu_assert_int_eq(strlen(stream_test_data), stream_write_cstring(stream, stream_test_data));
  360. mu_check(stream_rewind(stream));
  361. mu_assert_int_eq(prefix_len, stream_read(stream, (uint8_t*)buf, prefix_len));
  362. mu_assert_string_eq(prefix, buf);
  363. mu_assert_int_eq(substr_len, stream_write(stream, (uint8_t*)substr, substr_len));
  364. mu_check(stream_seek(stream, prefix_len, StreamOffsetFromStart));
  365. mu_assert_int_eq(substr_len, stream_read(stream, (uint8_t*)buf, substr_len));
  366. mu_assert_string_eq(substr, buf);
  367. stream_free(stream);
  368. furi_record_close(RECORD_STORAGE);
  369. }
  370. MU_TEST(stream_buffered_large_file_test) {
  371. FuriString* input_data;
  372. FuriString* output_data;
  373. input_data = furi_string_alloc();
  374. output_data = furi_string_alloc();
  375. Storage* storage = furi_record_open(RECORD_STORAGE);
  376. // generate test data consisting of several identical lines
  377. const size_t data_size = 4096;
  378. const size_t line_size = strlen(stream_test_data);
  379. const size_t rep_count = data_size / line_size + 1;
  380. for(size_t i = 0; i < rep_count; ++i) {
  381. furi_string_cat_printf(input_data, "%s\n", stream_test_data);
  382. }
  383. // write test data to file
  384. Stream* stream = buffered_file_stream_alloc(storage);
  385. mu_check(buffered_file_stream_open(
  386. stream, EXT_PATH("filestream.str"), FSAM_READ_WRITE, FSOM_CREATE_ALWAYS));
  387. mu_assert_int_eq(0, stream_size(stream));
  388. mu_assert_int_eq(furi_string_size(input_data), stream_write_string(stream, input_data));
  389. mu_assert_int_eq(furi_string_size(input_data), stream_size(stream));
  390. const size_t substr_start = 8;
  391. const size_t substr_len = 11;
  392. mu_check(stream_seek(stream, substr_start, StreamOffsetFromStart));
  393. mu_assert_int_eq(substr_start, stream_tell(stream));
  394. // copy one substring from test data
  395. char test_substr[substr_len + 1];
  396. memset(test_substr, 0, substr_len + 1);
  397. memcpy(test_substr, stream_test_data + substr_start, substr_len);
  398. char buf[substr_len + 1];
  399. memset(buf, 0, substr_len + 1);
  400. // read substring
  401. mu_assert_int_eq(substr_len, stream_read(stream, (uint8_t*)buf, substr_len));
  402. mu_assert_string_eq(test_substr, buf);
  403. memset(buf, 0, substr_len + 1);
  404. // forward seek to cause a cache miss
  405. mu_check(stream_seek(
  406. stream, (line_size + 1) * (rep_count - 1) - substr_len, StreamOffsetFromCurrent));
  407. // read same substring from a different line
  408. mu_assert_int_eq(substr_len, stream_read(stream, (uint8_t*)buf, substr_len));
  409. mu_assert_string_eq(test_substr, buf);
  410. memset(buf, 0, substr_len + 1);
  411. // backward seek to cause a cache miss
  412. mu_check(stream_seek(
  413. stream, -((line_size + 1) * (rep_count - 1) + substr_len), StreamOffsetFromCurrent));
  414. mu_assert_int_eq(substr_len, stream_read(stream, (uint8_t*)buf, substr_len));
  415. mu_assert_string_eq(test_substr, buf);
  416. // read the whole file
  417. mu_check(stream_rewind(stream));
  418. FuriString* tmp;
  419. tmp = furi_string_alloc();
  420. while(stream_read_line(stream, tmp)) {
  421. furi_string_cat(output_data, tmp);
  422. }
  423. furi_string_free(tmp);
  424. // check against generated data
  425. mu_assert_int_eq(furi_string_size(input_data), furi_string_size(output_data));
  426. mu_check(furi_string_equal(input_data, output_data));
  427. mu_check(stream_eof(stream));
  428. stream_free(stream);
  429. furi_record_close(RECORD_STORAGE);
  430. furi_string_free(input_data);
  431. furi_string_free(output_data);
  432. }
  433. MU_TEST_SUITE(stream_suite) {
  434. MU_RUN_TEST(stream_write_read_save_load_test);
  435. MU_RUN_TEST(stream_composite_test);
  436. MU_RUN_TEST(stream_split_test);
  437. MU_RUN_TEST(stream_buffered_write_after_read_test);
  438. MU_RUN_TEST(stream_buffered_large_file_test);
  439. }
  440. int run_minunit_test_stream() {
  441. MU_RUN_SUITE(stream_suite);
  442. return MU_EXIT_CODE;
  443. }