61#include "lexleo_cmocka.h"
129 assert_ptr_equal(ret.
stdio_ops, dummy_stdio_ops_p);
130 assert_ptr_equal(ret.
mem, dummy_mem_p);
262 size_t fail_call_idx;
266 out_expect_t out_expect;
267} test_stdio_stream_create_stream_case_t;
288 const test_stdio_stream_create_stream_case_t *tc;
289} test_stdio_stream_create_stream_fixture_t;
298static int setup_stdio_stream_create_stream(
void **state)
300 const test_stdio_stream_create_stream_case_t *tc =
301 (
const test_stdio_stream_create_stream_case_t *)(*state);
303 test_stdio_stream_create_stream_fixture_t *fx =
304 (test_stdio_stream_create_stream_fixture_t *)malloc(
sizeof(*fx));
312 fake_memory_fail_only_on_call(tc->fail_call_idx);
322 fx->args.kind = tc->kind;
324 fx->cfg.reserved = 0;
333static int teardown_stdio_stream_create_stream(
void **state)
335 test_stdio_stream_create_stream_fixture_t *fx =
336 (test_stdio_stream_create_stream_fixture_t *)(*state);
343 assert_true(fake_memory_no_leak());
344 assert_true(fake_memory_no_invalid_free());
345 assert_true(fake_memory_no_double_free());
358static void test_stdio_stream_create_stream(
void **state)
360 test_stdio_stream_create_stream_fixture_t *fx =
361 (test_stdio_stream_create_stream_fixture_t *)(*state);
362 const test_stdio_stream_create_stream_case_t *tc = fx->tc;
380 if (tc->out_expect == OUT_EXPECT_UNCHANGED && out_arg != NULL) {
381 fx->out = (
stream_t *)(uintptr_t)0xDEADC0DEu;
384 stream_t *out_arg_snapshot = fx->out;
390 assert_int_equal(ret, tc->expected_ret);
392 switch (tc->out_expect) {
393 case OUT_CHECK_NONE:
break;
394 case OUT_EXPECT_NULL: assert_null(fx->out);
break;
395 case OUT_EXPECT_NON_NULL: assert_non_null(fx->out);
break;
396 case OUT_EXPECT_UNCHANGED:
397 assert_ptr_equal(out_arg_snapshot, fx->out);
404 const uint8_t payload[] = {
'O',
'K' };
405 size_t n =
stream_write(fx->out, payload,
sizeof(payload), &st);
408 assert_int_equal(n,
sizeof(payload));
411 fake_stdio_write_call_count(fake_stdio_stdout()),
415 fake_stdio_buffered_len(fake_stdio_stdout()),
419 fake_stdio_buffered_backing(fake_stdio_stdout()),
430static const test_stdio_stream_create_stream_case_t
431CASE_STDIO_STREAM_CREATE_STREAM_OUT_NULL = {
432 .name =
"stdio_stream_create_stream_out_null",
438 .out_expect = OUT_CHECK_NONE
441static const test_stdio_stream_create_stream_case_t
442CASE_STDIO_STREAM_CREATE_STREAM_ARGS_NULL = {
443 .name =
"stdio_stream_create_stream_arg_null",
449 .out_expect = OUT_EXPECT_UNCHANGED
452static const test_stdio_stream_create_stream_case_t
453CASE_STDIO_STREAM_CREATE_STREAM_CFG_NULL = {
454 .name =
"stdio_stream_create_stream_cfg_null",
460 .out_expect = OUT_EXPECT_UNCHANGED
463static const test_stdio_stream_create_stream_case_t
464CASE_STDIO_STREAM_CREATE_STREAM_ENV_NULL = {
465 .name =
"stdio_stream_create_stream_env_null",
471 .out_expect = OUT_EXPECT_UNCHANGED
474static const test_stdio_stream_create_stream_case_t
475CASE_STDIO_STREAM_CREATE_STREAM_UNSUPPORTED_KIND = {
476 .name =
"stdio_stream_create_stream_unsupported_kind",
482 .out_expect = OUT_EXPECT_UNCHANGED
485static const test_stdio_stream_create_stream_case_t
486CASE_STDIO_STREAM_CREATE_STREAM_OOM_1 = {
487 .name =
"stdio_stream_create_stream_oom_1",
493 .out_expect = OUT_EXPECT_UNCHANGED
496static const test_stdio_stream_create_stream_case_t
497CASE_STDIO_STREAM_CREATE_STREAM_OK = {
498 .name =
"stdio_stream_create_stream_ok",
504 .out_expect = OUT_EXPECT_NON_NULL
511#define STDIO_STREAM_CREATE_STREAM_CASES(X) \
512X(CASE_STDIO_STREAM_CREATE_STREAM_OUT_NULL) \
513X(CASE_STDIO_STREAM_CREATE_STREAM_ARGS_NULL) \
514X(CASE_STDIO_STREAM_CREATE_STREAM_CFG_NULL) \
515X(CASE_STDIO_STREAM_CREATE_STREAM_ENV_NULL) \
516X(CASE_STDIO_STREAM_CREATE_STREAM_UNSUPPORTED_KIND) \
517X(CASE_STDIO_STREAM_CREATE_STREAM_OOM_1) \
518X(CASE_STDIO_STREAM_CREATE_STREAM_OK)
520#define STDIO_STREAM_MAKE_CREATE_STREAM_TEST(case_sym) \
521LEXLEO_MAKE_TEST(stdio_stream_create_stream, case_sym)
523static const struct CMUnitTest stdio_stream_create_stream_tests[] = {
524 STDIO_STREAM_CREATE_STREAM_CASES(
525 STDIO_STREAM_MAKE_CREATE_STREAM_TEST)
528#undef STDIO_STREAM_CREATE_STREAM_CASES
529#undef STDIO_STREAM_MAKE_CREATE_STREAM_TEST
667 size_t fail_call_idx;
671 desc_expect_t desc_expect;
672} test_stdio_stream_create_desc_case_t;
695 const test_stdio_stream_create_desc_case_t *tc;
696} test_stdio_stream_create_desc_fixture_t;
706static int setup_stdio_stream_create_desc(
void **state)
708 const test_stdio_stream_create_desc_case_t *tc =
709 (
const test_stdio_stream_create_desc_case_t *)(*state);
711 test_stdio_stream_create_desc_fixture_t *fx =
712 (test_stdio_stream_create_desc_fixture_t *)malloc(
sizeof(*fx));
720 fake_memory_fail_only_on_call(tc->fail_call_idx);
733 fx->cfg.reserved = 0;
743static int teardown_stdio_stream_create_desc(
void **state)
745 test_stdio_stream_create_desc_fixture_t *fx =
746 (test_stdio_stream_create_desc_fixture_t *)(*state);
748 if (fx->out.ud_dtor) fx->out.ud_dtor(fx->out.ud, fx->mem);
750 assert_true(fake_memory_no_leak());
751 assert_true(fake_memory_no_invalid_free());
752 assert_true(fake_memory_no_double_free());
766static void test_stdio_stream_create_desc(
void **state)
768 test_stdio_stream_create_desc_fixture_t *fx =
769 (test_stdio_stream_create_desc_fixture_t *)(*state);
770 const test_stdio_stream_create_desc_case_t *tc = fx->tc;
789 if (tc->desc_expect == DESC_EXPECT_EMPTY && out_arg != NULL) {
791 fx->out.ctor = (
void *)(uintptr_t)0xDEADC0DEu;
792 fx->out.ud = (
void *)(uintptr_t)0xDEADC0DEu;
793 fx->out.ud_dtor = (
void *)(uintptr_t)0xDEADC0DEu;
800 assert_int_equal(ret, tc->expected_ret);
802 if (tc->desc_expect == DESC_EXPECT_EMPTY) {
803 assert_null(fx->out.key);
804 assert_null(fx->out.ctor);
805 assert_null(fx->out.ud);
806 assert_null(fx->out.ud_dtor);
808 else if (tc->desc_expect == DESC_EXPECT_VALID) {
809 assert_true(fx->out.key != (
stream_key_t)(uintptr_t)0xDEADC0DEu);
810 assert_non_null(fx->out.key);
811 assert_true(*fx->out.key !=
'\0');
812 assert_true(fx->out.ctor != (
void *)(uintptr_t)0xDEADC0DEu);
813 assert_non_null(fx->out.ctor);
814 assert_true(fx->out.ud != (
void *)(uintptr_t)0xDEADC0DEu);
815 assert_non_null(fx->out.ud);
816 assert_true(fx->out.ud_dtor != (
void *)(uintptr_t)0xDEADC0DEu);
817 assert_non_null(fx->out.ud_dtor);
820 assert_true(tc->desc_expect == DESC_CHECK_NONE);
828static const test_stdio_stream_create_desc_case_t
829CASE_STDIO_STREAM_CREATE_DESC_OUT_NULL = {
830 .name =
"stdio_stream_create_desc_out_null",
835 .desc_expect = DESC_CHECK_NONE
838static const test_stdio_stream_create_desc_case_t
839CASE_STDIO_STREAM_CREATE_DESC_KEY_NULL = {
840 .name =
"stdio_stream_create_desc_key_null",
845 .desc_expect = DESC_EXPECT_EMPTY
848static const test_stdio_stream_create_desc_case_t
849CASE_STDIO_STREAM_CREATE_DESC_KEY_EMPTY = {
850 .name =
"stdio_stream_create_desc_key_empty",
855 .desc_expect = DESC_EXPECT_EMPTY
858static const test_stdio_stream_create_desc_case_t
859CASE_STDIO_STREAM_CREATE_DESC_CFG_NULL = {
860 .name =
"stdio_stream_create_desc_cfg_null",
865 .desc_expect = DESC_EXPECT_EMPTY
868static const test_stdio_stream_create_desc_case_t
869CASE_STDIO_STREAM_CREATE_DESC_ENV_NULL = {
870 .name =
"stdio_stream_create_desc_env_null",
875 .desc_expect = DESC_EXPECT_EMPTY
878static const test_stdio_stream_create_desc_case_t
879CASE_STDIO_STREAM_CREATE_DESC_MEM_NULL = {
880 .name =
"stdio_stream_create_desc_mem_null",
885 .desc_expect = DESC_EXPECT_EMPTY
888static const test_stdio_stream_create_desc_case_t
889CASE_STDIO_STREAM_CREATE_DESC_OOM_1 = {
890 .name =
"stdio_stream_create_desc_oom_1",
895 .desc_expect = DESC_EXPECT_EMPTY
898static const test_stdio_stream_create_desc_case_t
899CASE_STDIO_STREAM_CREATE_DESC_OK = {
900 .name =
"stdio_stream_create_desc_ok",
905 .desc_expect = DESC_EXPECT_VALID
912#define STDIO_STREAM_CREATE_DESC_CASES(X) \
913X(CASE_STDIO_STREAM_CREATE_DESC_OUT_NULL) \
914X(CASE_STDIO_STREAM_CREATE_DESC_KEY_NULL) \
915X(CASE_STDIO_STREAM_CREATE_DESC_KEY_EMPTY) \
916X(CASE_STDIO_STREAM_CREATE_DESC_CFG_NULL) \
917X(CASE_STDIO_STREAM_CREATE_DESC_ENV_NULL) \
918X(CASE_STDIO_STREAM_CREATE_DESC_MEM_NULL) \
919X(CASE_STDIO_STREAM_CREATE_DESC_OOM_1) \
920X(CASE_STDIO_STREAM_CREATE_DESC_OK)
922#define STDIO_STREAM_MAKE_CREATE_DESC_TEST(case_sym) \
923LEXLEO_MAKE_TEST(stdio_stream_create_desc, case_sym)
925static const struct CMUnitTest create_desc_stdio_stream_tests[] = {
926 STDIO_STREAM_CREATE_DESC_CASES(
927 STDIO_STREAM_MAKE_CREATE_DESC_TEST)
930#undef STDIO_STREAM_CREATE_DESC_CASES
931#undef STDIO_STREAM_MAKE_CREATE_DESC_TEST
1031 size_t fail_call_idx;
1035 out_expect_t out_expect;
1036} test_stdio_stream_ctor_case_t;
1058 const test_stdio_stream_ctor_case_t *tc;
1059} test_stdio_stream_ctor_fixture_t;
1068static int setup_stdio_stream_ctor(
void **state)
1070 const test_stdio_stream_ctor_case_t *tc =
1071 (
const test_stdio_stream_ctor_case_t *)(*state);
1073 test_stdio_stream_ctor_fixture_t *fx =
1074 (test_stdio_stream_ctor_fixture_t *)malloc(
sizeof(*fx));
1080 fake_memory_reset();
1082 fake_memory_fail_only_on_call(tc->fail_call_idx);
1091 fx->args.kind = tc->kind;
1092 fx->cfg.reserved = 0;
1093 fx->ud.cfg = fx->cfg;
1094 fx->ud.env = fx->env;
1103static int teardown_stdio_stream_ctor(
void **state)
1105 test_stdio_stream_ctor_fixture_t *fx =
1106 (test_stdio_stream_ctor_fixture_t *)(*state);
1113 assert_true(fake_memory_no_leak());
1114 assert_true(fake_memory_no_invalid_free());
1115 assert_true(fake_memory_no_double_free());
1128static void test_stdio_stream_ctor(
void **state)
1130 test_stdio_stream_ctor_fixture_t *fx =
1131 (test_stdio_stream_ctor_fixture_t *)(*state);
1132 const test_stdio_stream_ctor_case_t *tc = fx->tc;
1140 const void *ud_arg = (
const void *)&fx->ud;
1148 if (tc->out_expect == OUT_EXPECT_UNCHANGED && out_arg != NULL) {
1149 fx->out = (
stream_t *)(uintptr_t)0xDEADC0DEu;
1152 stream_t *out_arg_snapshot = fx->out;
1158 assert_int_equal(ret, tc->expected_ret);
1160 switch (tc->out_expect) {
1161 case OUT_CHECK_NONE:
break;
1162 case OUT_EXPECT_NULL: assert_null(fx->out);
break;
1163 case OUT_EXPECT_NON_NULL: assert_non_null(fx->out);
break;
1164 case OUT_EXPECT_UNCHANGED:
1165 assert_ptr_equal(out_arg_snapshot, fx->out);
1172 const uint8_t payload[] = {
'O',
'K' };
1173 size_t n =
stream_write(fx->out, payload,
sizeof(payload), &st);
1176 assert_int_equal(n,
sizeof(payload));
1179 fake_stdio_write_call_count(fake_stdio_stdout()),
1183 fake_stdio_buffered_len(fake_stdio_stdout()),
1186 assert_memory_equal(
1187 fake_stdio_buffered_backing(fake_stdio_stdout()),
1198static const test_stdio_stream_ctor_case_t
1199CASE_STDIO_STREAM_CTOR_OUT_NULL = {
1200 .name =
"stdio_stream_ctor_out_null",
1206 .out_expect = OUT_CHECK_NONE
1209static const test_stdio_stream_ctor_case_t
1210CASE_STDIO_STREAM_CTOR_ARGS_NULL = {
1211 .name =
"stdio_stream_ctor_args_null",
1217 .out_expect = OUT_EXPECT_UNCHANGED
1220static const test_stdio_stream_ctor_case_t
1221CASE_STDIO_STREAM_CTOR_UD_NULL = {
1222 .name =
"stdio_stream_ctor_ud_null",
1228 .out_expect = OUT_EXPECT_UNCHANGED
1231static const test_stdio_stream_ctor_case_t
1232CASE_STDIO_STREAM_CTOR_UNSUPPORTED_KIND = {
1233 .name =
"stdio_stream_ctor_unsupported_kind",
1239 .out_expect = OUT_EXPECT_UNCHANGED
1242static const test_stdio_stream_ctor_case_t
1243CASE_STDIO_STREAM_CTOR_OOM_1 = {
1244 .name =
"stdio_stream_ctor_oom_1",
1250 .out_expect = OUT_EXPECT_UNCHANGED
1253static const test_stdio_stream_ctor_case_t
1254CASE_STDIO_STREAM_CTOR_OK = {
1255 .name =
"stdio_stream_ctor_ok",
1261 .out_expect = OUT_EXPECT_NON_NULL
1268#define STDIO_STREAM_CTOR_CASES(X) \
1269X(CASE_STDIO_STREAM_CTOR_OUT_NULL) \
1270X(CASE_STDIO_STREAM_CTOR_ARGS_NULL) \
1271X(CASE_STDIO_STREAM_CTOR_UD_NULL) \
1272X(CASE_STDIO_STREAM_CTOR_UNSUPPORTED_KIND) \
1273X(CASE_STDIO_STREAM_CTOR_OOM_1) \
1274X(CASE_STDIO_STREAM_CTOR_OK)
1276#define STDIO_STREAM_MAKE_CTOR_TEST(case_sym) \
1277LEXLEO_MAKE_TEST(stdio_stream_ctor, case_sym)
1279static const struct CMUnitTest stdio_stream_ctor_tests[] = {
1280 STDIO_STREAM_CTOR_CASES(
1281 STDIO_STREAM_MAKE_CTOR_TEST)
1284#undef STDIO_STREAM_CTOR_CASES
1285#undef STDIO_STREAM_MAKE_CTOR_TEST
1466 uint8_t write_data[FAKE_STDIO_BUF_SIZE];
1468 bool pass_status_ptr;
1471 size_t expected_ret;
1473 uint8_t expected_buffered_backing[FAKE_STDIO_BUF_SIZE];
1474 size_t expected_buffered_len;
1475 bool expect_backing_invariance;
1476} test_stdio_stream_write_case_t;
1497 uint8_t buffered_backing_snapshot[FAKE_STDIO_BUF_SIZE];
1498 size_t buffered_backing_snapshot_len;
1509 const test_stdio_stream_write_case_t *tc;
1510} test_stdio_stream_write_fixture_t;
1520static int setup_stdio_stream_write(
void **state)
1522 const test_stdio_stream_write_case_t *tc =
1523 (
const test_stdio_stream_write_case_t *)(*state);
1525 test_stdio_stream_write_fixture_t *fx =
1526 (test_stdio_stream_write_fixture_t *)malloc(
sizeof(*fx));
1533 fake_memory_reset();
1541 fx->cfg.reserved = 0;
1542 fx->args.kind = tc->kind;
1556static int teardown_stdio_stream_write(
void **state)
1558 test_stdio_stream_write_fixture_t *fx =
1559 (test_stdio_stream_write_fixture_t *)(*state);
1566 assert_true(fake_memory_no_leak());
1567 assert_true(fake_memory_no_invalid_free());
1568 assert_true(fake_memory_no_double_free());
1586static void test_stdio_stream_write(
void **state)
1588 test_stdio_stream_write_fixture_t *fx =
1589 (test_stdio_stream_write_fixture_t *)(*state);
1590 const test_stdio_stream_write_case_t *tc = fx->tc;
1598 const void *buf_arg = tc->write_data;
1599 size_t n_arg = tc->write_len;
1612 if (!tc->pass_status_ptr) st_arg = NULL;
1614 if (tc->expect_backing_invariance) {
1615 fx->buffered_backing_snapshot_len = fake_stdio_buffered_len(stdio);
1617 fx->buffered_backing_snapshot,
1618 fake_stdio_buffered_backing(stdio),
1627 assert_int_equal((
int)ret, (
int)tc->expected_ret);
1628 if (tc->pass_status_ptr) {
1629 assert_int_equal((
int)st, (
int)tc->expected_st);
1633 (
int)fake_stdio_buffered_len(stdio),
1634 (
int)tc->expected_buffered_len);
1635 if (tc->expected_buffered_len > 0) {
1636 assert_memory_equal(
1637 fake_stdio_buffered_backing(stdio),
1638 tc->expected_buffered_backing,
1639 tc->expected_buffered_len
1643 if (tc->expect_backing_invariance) {
1645 (
int)fake_stdio_buffered_len(stdio),
1646 (
int)fx->buffered_backing_snapshot_len
1648 assert_memory_equal(
1649 fake_stdio_buffered_backing(stdio),
1650 fx->buffered_backing_snapshot,
1660static const test_stdio_stream_write_case_t
1661CASE_STDIO_STREAM_WRITE_ZERO_LEN = {
1662 .name =
"stdio_stream_write_zero_len",
1665 .pass_status_ptr =
true,
1669 .expected_buffered_len = 0,
1670 .expect_backing_invariance =
true
1673static const test_stdio_stream_write_case_t
1674CASE_STDIO_STREAM_WRITE_BUF_NULL_ZERO_LEN = {
1675 .name =
"stdio_stream_write_buf_null_zero_len",
1678 .pass_status_ptr =
true,
1682 .expected_buffered_len = 0,
1683 .expect_backing_invariance =
true
1686static const test_stdio_stream_write_case_t
1687CASE_STDIO_STREAM_WRITE_BUF_NULL_NONZERO = {
1688 .name =
"stdio_stream_write_buf_null_nonzero",
1692 .pass_status_ptr =
true,
1696 .expected_buffered_len = 0,
1697 .expect_backing_invariance =
true
1700static const test_stdio_stream_write_case_t
1701CASE_STDIO_STREAM_WRITE_STDIN_FORBIDDEN = {
1702 .name =
"stdio_stream_write_stdin_forbidden",
1705 .write_data ={ 0x01, 0x02, 0x03 },
1707 .pass_status_ptr =
true,
1711 .expect_backing_invariance =
true
1714static const test_stdio_stream_write_case_t
1715CASE_STDIO_STREAM_WRITE_ST_NULL_STDOUT = {
1716 .name =
"stdio_stream_write_st_null_stdout",
1719 .write_data ={ 0x01, 0x02, 0x03 },
1721 .pass_status_ptr =
false,
1724 .expected_buffered_backing ={ 0x01, 0x02, 0x03 },
1725 .expected_buffered_len = 3,
1728static const test_stdio_stream_write_case_t
1729CASE_STDIO_STREAM_WRITE_ST_NULL_STDERR = {
1730 .name =
"stdio_stream_write_st_null_stderr",
1733 .write_data ={ 0x01, 0x02, 0x03 },
1735 .pass_status_ptr =
false,
1738 .expected_buffered_backing ={ 0x01, 0x02, 0x03 },
1739 .expected_buffered_len = 3,
1742static const test_stdio_stream_write_case_t
1743CASE_STDIO_STREAM_WRITE_OK_STDOUT = {
1744 .name =
"stdio_stream_write_ok_stdout",
1747 .write_data ={ 0x01, 0x02, 0x03 },
1749 .pass_status_ptr =
true,
1753 .expected_buffered_backing ={ 0x01, 0x02, 0x03 },
1754 .expected_buffered_len = 3,
1757static const test_stdio_stream_write_case_t
1758CASE_STDIO_STREAM_WRITE_OK_STDERR = {
1759 .name =
"stdio_stream_write_ok_stderr",
1762 .write_data ={ 0x01, 0x02, 0x03 },
1764 .pass_status_ptr =
true,
1768 .expected_buffered_backing ={ 0x01, 0x02, 0x03 },
1769 .expected_buffered_len = 3,
1776#define STDIO_STREAM_WRITE_CASES(X) \
1777X(CASE_STDIO_STREAM_WRITE_ZERO_LEN) \
1778X(CASE_STDIO_STREAM_WRITE_BUF_NULL_ZERO_LEN) \
1779X(CASE_STDIO_STREAM_WRITE_BUF_NULL_NONZERO) \
1780X(CASE_STDIO_STREAM_WRITE_STDIN_FORBIDDEN) \
1781X(CASE_STDIO_STREAM_WRITE_ST_NULL_STDOUT) \
1782X(CASE_STDIO_STREAM_WRITE_ST_NULL_STDERR) \
1783X(CASE_STDIO_STREAM_WRITE_OK_STDOUT) \
1784X(CASE_STDIO_STREAM_WRITE_OK_STDERR)
1786#define STDIO_STREAM_MAKE_WRITE_TEST(case_sym) \
1787LEXLEO_MAKE_TEST(stdio_stream_write, case_sym)
1789static const struct CMUnitTest stdio_stream_write_tests[] = {
1790 STDIO_STREAM_WRITE_CASES(STDIO_STREAM_MAKE_WRITE_TEST)
1793#undef STDIO_STREAM_WRITE_CASES
1794#undef STDIO_STREAM_MAKE_WRITE_TEST
1994 uint8_t buffered_backing[FAKE_STDIO_BUF_SIZE];
1995 size_t buffered_len;
1997 bool pass_status_ptr;
2000 size_t expected_ret;
2002 uint8_t expected_buf[FAKE_STDIO_BUF_SIZE];
2003 size_t expected_pos;
2004 bool expect_buf_invariance;
2005} test_stdio_stream_read_case_t;
2027 uint8_t buffered_backing_snapshot[FAKE_STDIO_BUF_SIZE];
2028 size_t buffered_backing_snapshot_len;
2039 const test_stdio_stream_read_case_t *tc;
2040} test_stdio_stream_read_fixture_t;
2050static int setup_stdio_stream_read(
void **state)
2052 const test_stdio_stream_read_case_t *tc =
2053 (
const test_stdio_stream_read_case_t *)(*state);
2055 test_stdio_stream_read_fixture_t *fx =
2056 (test_stdio_stream_read_fixture_t *)malloc(
sizeof(*fx));
2063 fake_memory_reset();
2071 fx->cfg.reserved = 0;
2072 fx->args.kind = tc->kind;
2080 fake_stdio_set_buffered_backing(
2082 tc->buffered_backing,
2086 (
int)fake_stdio_read_pos(stdio),
2098static int teardown_stdio_stream_read(
void **state)
2100 test_stdio_stream_read_fixture_t *fx =
2101 (test_stdio_stream_read_fixture_t *)(*state);
2108 assert_true(fake_memory_no_leak());
2109 assert_true(fake_memory_no_invalid_free());
2110 assert_true(fake_memory_no_double_free());
2128static void test_stdio_stream_read(
void **state)
2130 test_stdio_stream_read_fixture_t *fx =
2131 (test_stdio_stream_read_fixture_t *)(*state);
2132 const test_stdio_stream_read_case_t *tc = fx->tc;
2138 uint8_t buf[FAKE_STDIO_BUF_SIZE] = { 0 };
2139 void *buf_arg = buf;
2140 size_t n_arg = tc->read_len;
2154 if (!tc->pass_status_ptr) st_arg = NULL;
2157 fx->buffered_backing_snapshot_len = fake_stdio_buffered_len(stdio);
2159 fx->buffered_backing_snapshot,
2160 fake_stdio_buffered_backing(stdio),
2170 (
int)tc->expected_ret
2172 if (tc->pass_status_ptr) {
2175 (
int)tc->expected_st
2179 const uint8_t *buffered_backing = fake_stdio_buffered_backing(stdio);
2180 const uint8_t zeros_buf[FAKE_STDIO_BUF_SIZE] = { 0 };
2182 if (tc->expected_ret > 0) {
2183 assert_memory_equal(
2188 assert_memory_equal(
2189 buf + tc->expected_ret,
2190 zeros_buf + tc->expected_ret,
2191 FAKE_STDIO_BUF_SIZE - tc->expected_ret
2196 (
int)fake_stdio_read_pos(stdio),
2197 (
int)tc->expected_pos
2200 if (tc->expect_buf_invariance) {
2201 assert_memory_equal(
2210 (
int)fake_stdio_buffered_len(stdio),
2211 (
int)fx->buffered_backing_snapshot_len
2213 assert_memory_equal(
2215 fx->buffered_backing_snapshot,
2225static const test_stdio_stream_read_case_t
2226CASE_STDIO_READ_READ_ZERO_LEN = {
2227 .name =
"stdio_stream_read_zero_len",
2230 .buffered_backing = { 0x01, 0x02, 0x03 },
2233 .pass_status_ptr =
true,
2237 .expected_buf = { 0 },
2239 .expect_buf_invariance =
true
2242static const test_stdio_stream_read_case_t
2243CASE_STDIO_READ_READ_BUF_NULL_ZERO_LEN = {
2244 .name =
"stdio_stream_read_buf_null_zero_len",
2247 .buffered_backing = { 0x01, 0x02, 0x03 },
2250 .pass_status_ptr =
true,
2254 .expected_buf = { 0 },
2256 .expect_buf_invariance =
true
2259static const test_stdio_stream_read_case_t
2260CASE_STDIO_READ_READ_BUF_NULL_NONZERO = {
2261 .name =
"stdio_stream_read_buf_null_nonzero",
2264 .buffered_backing = { 0x01, 0x02, 0x03 },
2267 .pass_status_ptr =
true,
2271 .expected_buf = { 0 },
2273 .expect_buf_invariance =
true
2276static const test_stdio_stream_read_case_t
2277CASE_STDIO_READ_READ_STDOUT_FORBIDDEN = {
2278 .name =
"stdio_stream_read_stdout_forbidden",
2281 .buffered_backing = { 0x01, 0x02, 0x03 },
2284 .pass_status_ptr =
true,
2288 .expected_buf = { 0 },
2290 .expect_buf_invariance =
true
2293static const test_stdio_stream_read_case_t
2294CASE_STDIO_READ_READ_STDERR_FORBIDDEN = {
2295 .name =
"stdio_stream_read_stderr_forbidden",
2298 .buffered_backing = { 0x01, 0x02, 0x03 },
2301 .pass_status_ptr =
true,
2305 .expected_buf = { 0 },
2307 .expect_buf_invariance =
true
2310static const test_stdio_stream_read_case_t
2311CASE_STDIO_READ_READ_ST_NULL_STDIN = {
2312 .name =
"stdio_stream_read_st_null_stdin",
2315 .buffered_backing = { 0x01, 0x02, 0x03 },
2318 .pass_status_ptr =
false,
2321 .expected_buf = { 0x01, 0x02 },
2323 .expect_buf_invariance =
false
2326static const test_stdio_stream_read_case_t
2327CASE_STDIO_READ_READ_OK_STDIN = {
2328 .name =
"stdio_stream_read_ok_stdin",
2331 .buffered_backing = { 0x01, 0x02, 0x03 },
2334 .pass_status_ptr =
true,
2338 .expected_buf = { 0x01, 0x02 },
2340 .expect_buf_invariance =
false
2343static const test_stdio_stream_read_case_t
2344CASE_STDIO_READ_READ_PARTIAL_STDIN = {
2345 .name =
"stdio_stream_read_partial_stdin",
2348 .buffered_backing = { 0x01, 0x02, 0x03 },
2351 .pass_status_ptr =
true,
2355 .expected_buf = { 0x01, 0x02, 0x03 },
2357 .expect_buf_invariance =
false
2364#define STDIO_STREAM_READ_CASES(X) \
2365X(CASE_STDIO_READ_READ_ZERO_LEN) \
2366X(CASE_STDIO_READ_READ_BUF_NULL_ZERO_LEN) \
2367X(CASE_STDIO_READ_READ_BUF_NULL_NONZERO) \
2368X(CASE_STDIO_READ_READ_STDOUT_FORBIDDEN) \
2369X(CASE_STDIO_READ_READ_STDERR_FORBIDDEN) \
2370X(CASE_STDIO_READ_READ_ST_NULL_STDIN) \
2371X(CASE_STDIO_READ_READ_OK_STDIN) \
2372X(CASE_STDIO_READ_READ_PARTIAL_STDIN)
2374#define STDIO_STREAM_MAKE_READ_TEST(case_sym) \
2375LEXLEO_MAKE_TEST(stdio_stream_read, case_sym)
2377static const struct CMUnitTest stdio_stream_read_tests[] = {
2378 STDIO_STREAM_READ_CASES(STDIO_STREAM_MAKE_READ_TEST)
2381#undef STDIO_STREAM_READ_CASES
2382#undef STDIO_STREAM_MAKE_READ_TEST
2499 uint8_t initial_buffered_backing[FAKE_STDIO_BUF_SIZE];
2500 size_t initial_buffered_len;
2501 uint8_t initial_sink_backing[FAKE_STDIO_BUF_SIZE];
2502 size_t initial_sink_len;
2506 uint8_t expected_buffered_backing[FAKE_STDIO_BUF_SIZE];
2507 size_t expected_buffered_len;
2508 uint8_t expected_sink_backing[FAKE_STDIO_BUF_SIZE];
2509 size_t expected_sink_len;
2510 bool expect_buffered_invariance;
2511 bool expect_sink_invariance;
2512} test_stdio_stream_flush_case_t;
2534 uint8_t buffered_backing_snapshot[FAKE_STDIO_BUF_SIZE];
2535 size_t buffered_backing_snapshot_len;
2536 uint8_t sink_backing_snapshot[FAKE_STDIO_BUF_SIZE];
2537 size_t sink_backing_snapshot_len;
2545 const test_stdio_stream_flush_case_t *tc;
2546} test_stdio_stream_flush_fixture_t;
2556static int setup_stdio_stream_flush(
void **state)
2558 const test_stdio_stream_flush_case_t *tc =
2559 (
const test_stdio_stream_flush_case_t *)(*state);
2561 test_stdio_stream_flush_fixture_t *fx =
2562 (test_stdio_stream_flush_fixture_t *)malloc(
sizeof(*fx));
2569 fake_memory_reset();
2577 fx->cfg.reserved = 0;
2578 fx->args.kind = tc->kind;
2586 fake_stdio_set_buffered_backing(
2588 tc->initial_buffered_backing,
2589 tc->initial_buffered_len
2591 fake_stdio_set_sink_backing(
2593 tc->initial_sink_backing,
2594 tc->initial_sink_len
2605static int teardown_stdio_stream_flush(
void **state)
2607 test_stdio_stream_flush_fixture_t *fx =
2608 (test_stdio_stream_flush_fixture_t *)(*state);
2615 assert_true(fake_memory_no_leak());
2616 assert_true(fake_memory_no_invalid_free());
2617 assert_true(fake_memory_no_double_free());
2635static void test_stdio_stream_flush(
void **state)
2637 test_stdio_stream_flush_fixture_t *fx =
2638 (test_stdio_stream_flush_fixture_t *)(*state);
2639 const test_stdio_stream_flush_case_t *tc = fx->tc;
2646 fx->buffered_backing_snapshot_len = fake_stdio_buffered_len(stdio);
2648 fx->buffered_backing_snapshot,
2649 fake_stdio_buffered_backing(stdio),
2653 fx->sink_backing_snapshot_len = fake_stdio_sink_len(stdio);
2655 fx->sink_backing_snapshot,
2656 fake_stdio_sink_backing(stdio),
2666 (
int)tc->expected_status
2669 const uint8_t *buffered_backing = fake_stdio_buffered_backing(stdio);
2670 const uint8_t *sink_backing = fake_stdio_sink_backing(stdio);
2673 (
int)fake_stdio_buffered_len(stdio),
2674 (
int)tc->expected_buffered_len
2676 assert_memory_equal(
2678 tc->expected_buffered_backing,
2683 (
int)fake_stdio_sink_len(stdio),
2684 (
int)tc->expected_sink_len
2686 assert_memory_equal(
2688 tc->expected_sink_backing,
2692 if (tc->expect_buffered_invariance) {
2694 (
int)fake_stdio_buffered_len(stdio),
2695 (
int)fx->buffered_backing_snapshot_len
2697 assert_memory_equal(
2699 fx->buffered_backing_snapshot,
2704 if (tc->expect_sink_invariance) {
2706 (
int)fake_stdio_sink_len(stdio),
2707 (
int)fx->sink_backing_snapshot_len
2709 assert_memory_equal(
2711 fx->sink_backing_snapshot,
2721static const test_stdio_stream_flush_case_t
2722CASE_STDIO_STREAM_FLUSH_STDIN_FORBIDDEN = {
2723 .name =
"stdio_stream_flush_stdin_forbidden",
2726 .initial_buffered_backing = { 0x01, 0x02, 0x03 },
2727 .initial_buffered_len = 3,
2728 .initial_sink_backing = { 0x0a, 0x0b },
2729 .initial_sink_len = 2,
2732 .expected_buffered_backing = { 0x01, 0x02, 0x03 },
2733 .expected_buffered_len = 3,
2734 .expected_sink_backing = { 0x0a, 0x0b },
2735 .expected_sink_len = 2,
2736 .expect_buffered_invariance =
true,
2737 .expect_sink_invariance =
true
2740static const test_stdio_stream_flush_case_t
2741CASE_STDIO_STREAM_FLUSH_OK_STDOUT = {
2742 .name =
"stdio_stream_flush_ok_stdout",
2745 .initial_buffered_backing = { 0x01, 0x02, 0x03 },
2746 .initial_buffered_len = 3,
2747 .initial_sink_backing = { 0x0a, 0x0b },
2748 .initial_sink_len = 2,
2751 .expected_buffered_backing = { 0 },
2752 .expected_buffered_len = 0,
2753 .expected_sink_backing = { 0x0a, 0x0b, 0x01, 0x02, 0x03 },
2754 .expected_sink_len = 5,
2755 .expect_buffered_invariance =
false,
2756 .expect_sink_invariance =
false
2759static const test_stdio_stream_flush_case_t
2760CASE_STDIO_STREAM_FLUSH_OK_STDERR = {
2761 .name =
"stdio_stream_flush_ok_stderr",
2764 .initial_buffered_backing = { 0x01, 0x02, 0x03 },
2765 .initial_buffered_len = 3,
2766 .initial_sink_backing = { 0x0a, 0x0b },
2767 .initial_sink_len = 2,
2770 .expected_buffered_backing = { 0 },
2771 .expected_buffered_len = 0,
2772 .expected_sink_backing = { 0x0a, 0x0b, 0x01, 0x02, 0x03 },
2773 .expected_sink_len = 5,
2774 .expect_buffered_invariance =
false,
2775 .expect_sink_invariance =
false
2782#define STDIO_STREAM_FLUSH_CASES(X) \
2783X(CASE_STDIO_STREAM_FLUSH_STDIN_FORBIDDEN) \
2784X(CASE_STDIO_STREAM_FLUSH_OK_STDOUT) \
2785X(CASE_STDIO_STREAM_FLUSH_OK_STDERR)
2787#define STDIO_STREAM_MAKE_FLUSH_TEST(case_sym) \
2788LEXLEO_MAKE_TEST(stdio_stream_flush, case_sym)
2790static const struct CMUnitTest stdio_stream_flush_tests[] = {
2791 STDIO_STREAM_FLUSH_CASES(STDIO_STREAM_MAKE_FLUSH_TEST)
2794#undef STDIO_STREAM_FLUSH_CASES
2795#undef STDIO_STREAM_MAKE_FLUSH_TEST
2895 bool expected_handle_is_null;
2896 bool expect_no_leak;
2897} test_stdio_stream_close_case_t;
2924 const test_stdio_stream_close_case_t *tc;
2925} test_stdio_stream_close_fixture_t;
2935static int setup_stdio_stream_close(
void **state)
2937 const test_stdio_stream_close_case_t *tc =
2938 (
const test_stdio_stream_close_case_t *)(*state);
2940 test_stdio_stream_close_fixture_t *fx =
2941 (test_stdio_stream_close_fixture_t *)malloc(
sizeof(*fx));
2948 fake_memory_reset();
2956 fx->cfg.reserved = 0;
2957 fx->args.kind = tc->kind;
2971static int teardown_stdio_stream_close(
void **state)
2973 test_stdio_stream_close_fixture_t *fx =
2974 (test_stdio_stream_close_fixture_t *)(*state);
2981 assert_true(fake_memory_no_leak());
2982 assert_true(fake_memory_no_invalid_free());
2983 assert_true(fake_memory_no_double_free());
3001static void test_stdio_stream_close(
void **state)
3003 test_stdio_stream_close_fixture_t *fx =
3004 (test_stdio_stream_close_fixture_t *)(*state);
3005 const test_stdio_stream_close_case_t *tc = fx->tc;
3017 (
int)(fx->s == NULL),
3018 (
int)tc->expected_handle_is_null
3026static const test_stdio_stream_close_case_t
3027CASE_STDIO_STREAM_CLOSE_OK_STDIN = {
3028 .name =
"stdio_stream_close_ok_stdin",
3032 .expected_handle_is_null =
true,
3033 .expect_no_leak =
true
3036static const test_stdio_stream_close_case_t
3037CASE_STDIO_STREAM_CLOSE_OK_STDOUT = {
3038 .name =
"stdio_stream_close_ok_stdout",
3042 .expected_handle_is_null =
true,
3043 .expect_no_leak =
true
3046static const test_stdio_stream_close_case_t
3047CASE_STDIO_STREAM_CLOSE_OK_STDERR = {
3048 .name =
"stdio_stream_close_ok_stderr",
3052 .expected_handle_is_null =
true,
3053 .expect_no_leak =
true
3060#define STDIO_STREAM_CLOSE_CASES(X) \
3061X(CASE_STDIO_STREAM_CLOSE_OK_STDIN) \
3062X(CASE_STDIO_STREAM_CLOSE_OK_STDOUT) \
3063X(CASE_STDIO_STREAM_CLOSE_OK_STDERR)
3065#define STDIO_STREAM_MAKE_CLOSE_TEST(case_sym) \
3066LEXLEO_MAKE_TEST(stdio_stream_close, case_sym)
3068static const struct CMUnitTest stdio_stream_close_tests[] = {
3069 STDIO_STREAM_CLOSE_CASES(STDIO_STREAM_MAKE_CLOSE_TEST)
3072#undef STDIO_STREAM_CLOSE_CASES
3073#undef STDIO_STREAM_MAKE_CLOSE_TEST
3082 static const struct CMUnitTest stdio_stream_non_parametric_tests[] = {
3088 failed += cmocka_run_group_tests(stdio_stream_non_parametric_tests, NULL, NULL);
3089 failed += cmocka_run_group_tests(stdio_stream_create_stream_tests, NULL, NULL);
3090 failed += cmocka_run_group_tests(create_desc_stdio_stream_tests, NULL, NULL);
3091 failed += cmocka_run_group_tests(stdio_stream_ctor_tests, NULL, NULL);
3092 failed += cmocka_run_group_tests(stdio_stream_write_tests, NULL, NULL);
3093 failed += cmocka_run_group_tests(stdio_stream_read_tests, NULL, NULL);
3094 failed += cmocka_run_group_tests(stdio_stream_flush_tests, NULL, NULL);
3095 failed += cmocka_run_group_tests(stdio_stream_close_tests, NULL, NULL);
void * osal_memset(void *s, int c, size_t n)
void * osal_memcpy(void *dest, const void *src, size_t n)
const osal_mem_ops_t * osal_mem_test_fake_ops(void)
const osal_stdio_ops_t * osal_stdio_test_fake_ops(void)
Composition Root API for wiring the stdio_stream adapter into the stream factory.
stream_status_t stdio_stream_ctor(const void *ud, const void *args, stream_t **out)
Factory-compatible constructor callback for the stdio_stream adapter.
stream_status_t stdio_stream_create_stream(stream_t **out, const stdio_stream_args_t *args, const stdio_stream_cfg_t *cfg, const stdio_stream_env_t *env)
Create a standard-I/O-backed stream instance.
stdio_stream_env_t stdio_stream_default_env(const osal_stdio_ops_t *stdio_ops, const osal_mem_ops_t *mem, const stream_env_t *port_env)
Build a default environment for the stdio_stream adapter.
stdio_stream_cfg_t stdio_stream_default_cfg(void)
Return a default configuration for the stdio_stream adapter.
stream_status_t stdio_stream_create_desc(stream_adapter_desc_t *out, stream_key_t key, const stdio_stream_cfg_t *cfg, const stdio_stream_env_t *env, const osal_mem_ops_t *mem)
Build a stream adapter descriptor for the stdio_stream adapter.
Private constructor user-data stored in stdio_stream factory descriptors.
Private backend handle definition for the stdio_stream adapter.
@ STDIO_STREAM_KIND_STDERR
Standard error stream.
@ STDIO_STREAM_KIND_STDOUT
Standard output stream.
@ STDIO_STREAM_KIND_STDIN
Standard input stream.
@ STDIO_STREAM_KIND_COUNT
Number of supported standard I/O stream kinds.
Borrower-facing runtime operations for the stream port.
stream_status_t stream_flush(stream_t *s)
Flush a stream.
size_t stream_write(stream_t *s, const void *buf, size_t n, stream_status_t *st)
Write bytes to a stream.
size_t stream_read(stream_t *s, void *buf, size_t n, stream_status_t *st)
Read bytes from a stream.
Private stream handle definition for the stream port.
const char * stream_key_t
Public identifier type for a registered stream adapter.
Lifecycle services for stream_t handles.
void stream_destroy(stream_t **s)
Destroy a stream handle.
stream_status_t
Public status codes used by the stream port.
Creation arguments for the stdio_stream adapter.
Configuration type for the stdio_stream adapter.
int reserved
Reserved configuration field.
Private constructor user-data for stdio_stream factory registration.
Injected dependencies for the stdio_stream adapter.
const osal_stdio_ops_t * stdio_ops
Borrowed OSAL stdio operations table.
stream_env_t port_env
Borrowed stream port environment.
const osal_mem_ops_t * mem
Borrowed memory operations table for adapter-owned allocations.
Private backend handle for the stdio_stream adapter.
Public descriptor used to register a concrete stream adapter.
Runtime environment for the stream port.
Private handle structure for a stream_t.
stdio_stream_flush_scenario_t
Scenarios for stdio_stream_flush().
@ STDIO_STREAM_FLUSH_SCENARIO_STDIN_FORBIDDEN
@ STDIO_STREAM_FLUSH_SCENARIO_OK_STDOUT
@ STDIO_STREAM_FLUSH_SCENARIO_OK_STDERR
stdio_stream_create_stream_scenario_t
Scenarios for stdio_stream_create_stream().
@ STDIO_STREAM_CREATE_STREAM_SCENARIO_ENV_NULL
@ STDIO_STREAM_CREATE_STREAM_SCENARIO_OOM
@ STDIO_STREAM_CREATE_STREAM_SCENARIO_ARGS_NULL
@ STDIO_STREAM_CREATE_STREAM_SCENARIO_OUT_NULL
@ STDIO_STREAM_CREATE_STREAM_SCENARIO_CFG_NULL
@ STDIO_STREAM_CREATE_STREAM_SCENARIO_UNSUPPORTED_KIND
@ STDIO_STREAM_CREATE_STREAM_SCENARIO_OK
stdio_stream_write_scenario_t
Scenarios for stdio_stream_write().
@ STDIO_STREAM_WRITE_SCENARIO_ST_NULL_STDERR
@ STDIO_STREAM_WRITE_SCENARIO_OK_STDERR
@ STDIO_STREAM_WRITE_SCENARIO_ZERO_LEN
@ STDIO_STREAM_WRITE_SCENARIO_BUF_NULL_ZERO_LEN
@ STDIO_STREAM_WRITE_SCENARIO_STDIN_FORBIDDEN
@ STDIO_STREAM_WRITE_SCENARIO_OK_STDOUT
@ STDIO_STREAM_WRITE_SCENARIO_ST_NULL_STDOUT
@ STDIO_STREAM_WRITE_SCENARIO_BUF_NULL_NONZERO
stdio_stream_read_scenario_t
Scenarios for stdio_stream_read().
@ STDIO_STREAM_READ_SCENARIO_BUF_NULL_ZERO_LEN
@ STDIO_STREAM_READ_SCENARIO_OK_STDIN
@ STDIO_STREAM_READ_SCENARIO_PARTIAL_STDIN
@ STDIO_STREAM_READ_SCENARIO_ST_NULL_STDIN
@ STDIO_STREAM_READ_SCENARIO_STDOUT_FORBIDDEN
@ STDIO_STREAM_READ_SCENARIO_BUF_NULL_NONZERO
@ STDIO_STREAM_READ_SCENARIO_STDERR_FORBIDDEN
@ STDIO_STREAM_READ_SCENARIO_ZERO_LEN
stdio_stream_create_desc_scenario_t
Scenarios for stdio_stream_create_desc().
@ STDIO_STREAM_CREATE_DESC_SCENARIO_OOM
@ STDIO_STREAM_CREATE_DESC_SCENARIO_KEY_NULL
@ STDIO_STREAM_CREATE_DESC_SCENARIO_CFG_NULL
@ STDIO_STREAM_CREATE_DESC_SCENARIO_OUT_NULL
@ STDIO_STREAM_CREATE_DESC_SCENARIO_KEY_EMPTY
@ STDIO_STREAM_CREATE_DESC_SCENARIO_MEM_NULL
@ STDIO_STREAM_CREATE_DESC_SCENARIO_OK
@ STDIO_STREAM_CREATE_DESC_SCENARIO_ENV_NULL
static void test_stdio_stream_default_env(void **state)
Test stdio_stream_default_env().
stdio_stream_close_scenario_t
Scenarios for stdio_stream_close().
@ STDIO_STREAM_CLOSE_SCENARIO_OK_STDIN
@ STDIO_STREAM_CLOSE_SCENARIO_OK_STDERR
@ STDIO_STREAM_CLOSE_SCENARIO_OK_STDOUT
stdio_stream_ctor_scenario_t
Scenarios for stdio_stream_ctor().
@ STDIO_STREAM_CTOR_SCENARIO_ARGS_NULL
@ STDIO_STREAM_CTOR_SCENARIO_OUT_NULL
@ STDIO_STREAM_CTOR_SCENARIO_UNSUPPORTED_KIND
@ STDIO_STREAM_CTOR_SCENARIO_OK
@ STDIO_STREAM_CTOR_SCENARIO_OOM
@ STDIO_STREAM_CTOR_SCENARIO_UD_NULL
static void test_stdio_stream_default_cfg(void **state)
Test stdio_stream_default_cfg().