48#include "lexleo_cmocka.h"
115 assert_ptr_equal(ret.
file_ops, dummy_file_ops_p);
290 size_t fail_call_idx;
295 out_expect_t out_expect;
296} test_fs_stream_create_stream_case_t;
321 const test_fs_stream_create_stream_case_t *tc;
322} test_fs_stream_create_stream_fixture_t;
331static int setup_fs_stream_create_stream(
void **state)
333 const test_fs_stream_create_stream_case_t *tc =
334 (
const test_fs_stream_create_stream_case_t *)(*state);
336 test_fs_stream_create_stream_fixture_t *fx =
337 (test_fs_stream_create_stream_fixture_t *)malloc(
sizeof(*fx));
346 fake_memory_fail_only_on_call(tc->fail_call_idx);
350 fake_file_set_backing(fx->backing,
sizeof(fx->backing), 0);
351 fake_file_set_pos(0);
352 fake_file_fail_disable();
355 fake_file_fail_enable(FAKE_FILE_OP_OPEN, 1, tc->open_fail_status);
363 fx->args.path =
"crazy_injection.txt";
365 fx->args.autoclose =
true;
367 fx->cfg.reserved = 0;
376static int teardown_fs_stream_create_stream(
void **state)
378 test_fs_stream_create_stream_fixture_t *fx =
379 (test_fs_stream_create_stream_fixture_t *)(*state);
386 assert_true(fake_memory_no_leak());
387 assert_true(fake_memory_no_invalid_free());
388 assert_true(fake_memory_no_double_free());
401static void test_fs_stream_create_stream(
void **state)
403 test_fs_stream_create_stream_fixture_t *fx =
404 (test_fs_stream_create_stream_fixture_t *)(*state);
405 const test_fs_stream_create_stream_case_t *tc = fx->tc;
426 if (tc->out_expect == OUT_EXPECT_UNCHANGED && out_arg != NULL) {
427 fx->out = (
stream_t *)(uintptr_t)0xDEADC0DEu;
430 stream_t *out_arg_snapshot = fx->out;
436 assert_int_equal(ret, tc->expected_ret);
438 switch (tc->out_expect) {
439 case OUT_CHECK_NONE:
break;
440 case OUT_EXPECT_NULL: assert_null(fx->out);
break;
441 case OUT_EXPECT_NON_NULL: assert_non_null(fx->out);
break;
442 case OUT_EXPECT_UNCHANGED:
443 assert_ptr_equal(out_arg_snapshot, fx->out);
446 default: assert_true(
false);
450 assert_non_null(fx->out);
451 const char msg[] =
"hello";
452 size_t w =
stream_write(fx->out, msg,
sizeof(msg) - 1, &st);
453 assert_int_equal((
int)w, (
int)(
sizeof(msg) - 1));
455 assert_int_equal(fake_file_backing_len(),
sizeof(msg) - 1);
456 assert_memory_equal(fx->backing, msg,
sizeof(msg) - 1);
465static const test_fs_stream_create_stream_case_t CASE_FS_OK = {
466 .name =
"fs_create_stream_ok",
472 .out_expect = OUT_EXPECT_NON_NULL
475static const test_fs_stream_create_stream_case_t CASE_FS_OUT_NULL = {
476 .name =
"fs_create_stream_out_null",
482 .out_expect = OUT_CHECK_NONE
485static const test_fs_stream_create_stream_case_t CASE_FS_ARGS_NULL = {
486 .name =
"fs_create_stream_args_null",
492 .out_expect = OUT_EXPECT_UNCHANGED
495static const test_fs_stream_create_stream_case_t CASE_FS_CFG_NULL = {
496 .name =
"fs_create_stream_cfg_null",
502 .out_expect = OUT_EXPECT_UNCHANGED
505static const test_fs_stream_create_stream_case_t CASE_FS_ENV_NULL = {
506 .name =
"fs_create_stream_env_null",
512 .out_expect = OUT_EXPECT_UNCHANGED
515static const test_fs_stream_create_stream_case_t CASE_FS_PATH_NULL = {
516 .name =
"fs_create_stream_path_null",
522 .out_expect = OUT_EXPECT_UNCHANGED
525static const test_fs_stream_create_stream_case_t CASE_FS_PATH_EMPTY = {
526 .name =
"fs_create_stream_path_empty",
532 .out_expect = OUT_EXPECT_UNCHANGED
535static const test_fs_stream_create_stream_case_t CASE_FS_FLAGS_ZERO = {
536 .name =
"fs_create_stream_flags_zero",
542 .out_expect = OUT_EXPECT_UNCHANGED
545static const test_fs_stream_create_stream_case_t CASE_FS_OOM_1 = {
546 .name =
"fs_create_stream_oom_1",
552 .out_expect = OUT_EXPECT_UNCHANGED
555static const test_fs_stream_create_stream_case_t CASE_FS_OPEN_FAIL_NOT_FOUND = {
556 .name =
"fs_create_stream_open_fail_not_found",
562 .out_expect = OUT_EXPECT_UNCHANGED
569#define FS_STREAM_CREATE_STREAM_CASES(X) \
572X(CASE_FS_ARGS_NULL) \
573X(CASE_FS_PATH_NULL) \
574X(CASE_FS_PATH_EMPTY) \
575X(CASE_FS_FLAGS_ZERO) \
579X(CASE_FS_OPEN_FAIL_NOT_FOUND)
581#define FS_STREAM_MAKE_CREATE_STREAM_TEST(case_sym) \
582LEXLEO_MAKE_TEST(fs_stream_create_stream, case_sym)
584static const struct CMUnitTest fs_stream_stream_create_stream_tests[] = {
585 FS_STREAM_CREATE_STREAM_CASES(FS_STREAM_MAKE_CREATE_STREAM_TEST)
588#undef FS_STREAM_CREATE_STREAM_CASES
589#undef FS_STREAM_MAKE_CREATE_STREAM_TEST
723 size_t fail_call_idx;
727 desc_expect_t desc_expect;
728} test_fs_stream_create_desc_case_t;
751 const test_fs_stream_create_desc_case_t *tc;
752} test_fs_stream_create_desc_fixture_t;
761static int setup_fs_stream_create_desc(
void **state)
763 const test_fs_stream_create_desc_case_t *tc =
764 (
const test_fs_stream_create_desc_case_t *)(*state);
766 test_fs_stream_create_desc_fixture_t *fx =
767 (test_fs_stream_create_desc_fixture_t *)malloc(
sizeof(*fx));
775 fake_memory_fail_only_on_call(tc->fail_call_idx);
786 fx->cfg.reserved = 0;
795static int teardown_fs_stream_create_desc(
void **state)
797 test_fs_stream_create_desc_fixture_t *fx =
798 (test_fs_stream_create_desc_fixture_t *)(*state);
800 if (fx->out.ud_dtor) fx->out.ud_dtor(fx->out.ud, fx->mem);
802 assert_true(fake_memory_no_leak());
803 assert_true(fake_memory_no_invalid_free());
804 assert_true(fake_memory_no_double_free());
817static void test_fs_stream_create_desc(
void **state)
819 test_fs_stream_create_desc_fixture_t *fx =
820 (test_fs_stream_create_desc_fixture_t *)(*state);
821 const test_fs_stream_create_desc_case_t *tc = fx->tc;
840 if (tc->desc_expect == DESC_EXPECT_EMPTY && out_arg != NULL) {
842 fx->out.ctor = (
void *)(uintptr_t)0xDEADC0DEu;
843 fx->out.ud = (
void *)(uintptr_t)0xDEADC0DEu;
844 fx->out.ud_dtor = (
void *)(uintptr_t)0xDEADC0DEu;
851 assert_int_equal(ret, tc->expected_ret);
853 if (tc->desc_expect == DESC_EXPECT_EMPTY) {
854 assert_null(fx->out.key);
855 assert_null(fx->out.ctor);
856 assert_null(fx->out.ud);
857 assert_null(fx->out.ud_dtor);
859 else if (tc->desc_expect == DESC_EXPECT_VALID) {
860 assert_true(fx->out.key != (
stream_key_t)(uintptr_t)0xDEADC0DEu);
861 assert_non_null(fx->out.key);
862 assert_true(*fx->out.key !=
'\0');
863 assert_true(fx->out.ctor != (
void *)(uintptr_t)0xDEADC0DEu);
864 assert_non_null(fx->out.ctor);
865 assert_true(fx->out.ud != (
void *)(uintptr_t)0xDEADC0DEu);
866 assert_non_null(fx->out.ud);
867 assert_true(fx->out.ud_dtor != (
void *)(uintptr_t)0xDEADC0DEu);
868 assert_non_null(fx->out.ud_dtor);
871 assert_true(tc->desc_expect == DESC_CHECK_NONE);
879static const test_fs_stream_create_desc_case_t CASE_FS_STREAM_CREATE_DESC_OK = {
880 .name =
"fs_stream_create_desc_ok",
885 .desc_expect = DESC_EXPECT_VALID
888static const test_fs_stream_create_desc_case_t CASE_FS_STREAM_CREATE_DESC_OUT_NULL = {
889 .name =
"fs_stream_create_desc_out_null",
894 .desc_expect = DESC_CHECK_NONE
897static const test_fs_stream_create_desc_case_t CASE_FS_STREAM_CREATE_DESC_KEY_NULL = {
898 .name =
"fs_stream_create_desc_key_null",
903 .desc_expect = DESC_EXPECT_EMPTY
906static const test_fs_stream_create_desc_case_t CASE_FS_STREAM_CREATE_DESC_KEY_EMPTY = {
907 .name =
"fs_stream_create_desc_key_empty",
912 .desc_expect = DESC_EXPECT_EMPTY
915static const test_fs_stream_create_desc_case_t CASE_FS_STREAM_CREATE_DESC_CFG_NULL = {
916 .name =
"fs_stream_create_desc_cfg_null",
921 .desc_expect = DESC_EXPECT_EMPTY
924static const test_fs_stream_create_desc_case_t CASE_FS_STREAM_CREATE_DESC_ENV_NULL = {
925 .name =
"fs_stream_create_desc_env_null",
930 .desc_expect = DESC_EXPECT_EMPTY
933static const test_fs_stream_create_desc_case_t CASE_FS_STREAM_CREATE_DESC_MEM_NULL = {
934 .name =
"fs_stream_create_desc_mem_null",
939 .desc_expect = DESC_EXPECT_EMPTY
942static const test_fs_stream_create_desc_case_t CASE_FS_STREAM_CREATE_DESC_OOM_1 = {
943 .name =
"fs_stream_create_desc_oom_1",
948 .desc_expect = DESC_EXPECT_EMPTY
955#define FS_STREAM_CREATE_DESC_CASES(X) \
956X(CASE_FS_STREAM_CREATE_DESC_OK) \
957X(CASE_FS_STREAM_CREATE_DESC_OUT_NULL) \
958X(CASE_FS_STREAM_CREATE_DESC_KEY_NULL) \
959X(CASE_FS_STREAM_CREATE_DESC_KEY_EMPTY) \
960X(CASE_FS_STREAM_CREATE_DESC_CFG_NULL) \
961X(CASE_FS_STREAM_CREATE_DESC_ENV_NULL) \
962X(CASE_FS_STREAM_CREATE_DESC_MEM_NULL) \
963X(CASE_FS_STREAM_CREATE_DESC_OOM_1)
965#define FS_STREAM_MAKE_CREATE_DESC_TEST(case_sym) \
966LEXLEO_MAKE_TEST(fs_stream_create_desc, case_sym)
968static const struct CMUnitTest create_desc_fs_stream_tests[] = {
969 FS_STREAM_CREATE_DESC_CASES(FS_STREAM_MAKE_CREATE_DESC_TEST)
972#undef FS_STREAM_CREATE_DESC_CASES
973#undef FS_STREAM_MAKE_CREATE_DESC_TEST
1111 size_t fail_call_idx;
1116 out_expect_t out_expect;
1117} test_fs_stream_desc_ctor_case_t;
1147 uint8_t backing[64];
1150 const test_fs_stream_desc_ctor_case_t *tc;
1151} test_fs_stream_desc_ctor_fixture_t;
1161static int setup_fs_stream_desc_ctor(
void **state)
1163 const test_fs_stream_desc_ctor_case_t *tc =
1164 (
const test_fs_stream_desc_ctor_case_t *)(*state);
1166 test_fs_stream_desc_ctor_fixture_t *fx =
1167 (test_fs_stream_desc_ctor_fixture_t *)malloc(
sizeof(*fx));
1174 fake_memory_reset();
1177 fake_file_set_backing(fx->backing,
sizeof(fx->backing), 0);
1178 fake_file_set_pos(0);
1179 fake_file_fail_disable();
1182 fake_file_fail_enable(FAKE_FILE_OP_OPEN, 1, tc->open_fail_status);
1191 fx->cfg.reserved = 0;
1197 fake_memory_fail_only_on_call(tc->fail_call_idx);
1200 fx->args.path =
"crazy_injection.txt";
1202 fx->args.autoclose =
true;
1212static int teardown_fs_stream_desc_ctor(
void **state)
1214 test_fs_stream_desc_ctor_fixture_t *fx =
1215 (test_fs_stream_desc_ctor_fixture_t *)(*state);
1222 if (fx->desc.ud_dtor) fx->desc.ud_dtor(fx->desc.ud, fx->mem);
1224 assert_true(fake_memory_no_leak());
1225 assert_true(fake_memory_no_invalid_free());
1226 assert_true(fake_memory_no_double_free());
1240static void test_fs_stream_desc_ctor(
void **state)
1242 test_fs_stream_desc_ctor_fixture_t *fx =
1243 (test_fs_stream_desc_ctor_fixture_t *)(*state);
1244 const test_fs_stream_desc_ctor_case_t *tc = fx->tc;
1261 if (tc->out_expect == OUT_EXPECT_UNCHANGED && out_arg != NULL) {
1262 fx->out = (
stream_t *)(uintptr_t)0xDEADC0DEu;
1265 stream_t *out_arg_snapshot = fx->out;
1268 ret = fx->desc.ctor(fx->desc.ud, args_arg, out_arg);
1271 assert_int_equal(ret, tc->expected_ret);
1273 switch (tc->out_expect) {
1274 case OUT_CHECK_NONE:
break;
1275 case OUT_EXPECT_NULL: assert_null(fx->out);
break;
1276 case OUT_EXPECT_NON_NULL: assert_non_null(fx->out);
break;
1277 case OUT_EXPECT_UNCHANGED:
1278 assert_ptr_equal(out_arg_snapshot, fx->out);
1281 default: assert_true(
false);
1285 assert_non_null(fx->out);
1286 const char msg[] =
"hello";
1287 size_t w =
stream_write(fx->out, msg,
sizeof(msg) - 1, &st);
1288 assert_int_equal((
int)w, (
int)(
sizeof(msg) - 1));
1290 assert_int_equal(fake_file_backing_len(),
sizeof(msg) - 1);
1291 assert_memory_equal(fx->backing, msg,
sizeof(msg) - 1);
1300static const test_fs_stream_desc_ctor_case_t CASE_FS_STREAM_DESC_CTOR_OK = {
1301 .name =
"fs_stream_desc_ctor_create_stream_ok",
1307 .out_expect = OUT_EXPECT_NON_NULL
1310static const test_fs_stream_desc_ctor_case_t CASE_FS_STREAM_DESC_CTOR_ARGS_NULL = {
1311 .name =
"fs_stream_desc_ctor_create_stream_args_null",
1317 .out_expect = OUT_EXPECT_UNCHANGED
1320static const test_fs_stream_desc_ctor_case_t CASE_FS_STREAM_DESC_CTOR_OUT_NULL = {
1321 .name =
"fs_stream_desc_ctor_create_stream_out_null",
1327 .out_expect = OUT_CHECK_NONE
1330static const test_fs_stream_desc_ctor_case_t CASE_FS_STREAM_DESC_CTOR_PATH_NULL = {
1331 .name =
"fs_stream_desc_ctor_create_stream_path_null",
1337 .out_expect = OUT_EXPECT_UNCHANGED
1340static const test_fs_stream_desc_ctor_case_t CASE_FS_STREAM_DESC_CTOR_PATH_EMPTY = {
1341 .name =
"fs_stream_desc_ctor_create_stream_path_empty",
1347 .out_expect = OUT_EXPECT_UNCHANGED
1350static const test_fs_stream_desc_ctor_case_t CASE_FS_STREAM_DESC_CTOR_FLAGS_ZERO = {
1351 .name =
"fs_stream_desc_ctor_create_stream_flags_zero",
1357 .out_expect = OUT_EXPECT_UNCHANGED
1360static const test_fs_stream_desc_ctor_case_t CASE_FS_STREAM_DESC_CTOR_OOM_1 = {
1361 .name =
"fs_stream_desc_ctor_create_stream_oom_1",
1367 .out_expect = OUT_EXPECT_UNCHANGED
1370static const test_fs_stream_desc_ctor_case_t CASE_FS_STREAM_DESC_CTOR_OPEN_FAIL = {
1371 .name =
"fs_stream_desc_ctor_create_stream_open_fail",
1377 .out_expect = OUT_EXPECT_UNCHANGED
1384#define FS_STREAM_DESC_CTOR_CASES(X) \
1385X(CASE_FS_STREAM_DESC_CTOR_OK) \
1386X(CASE_FS_STREAM_DESC_CTOR_ARGS_NULL) \
1387X(CASE_FS_STREAM_DESC_CTOR_OUT_NULL) \
1388X(CASE_FS_STREAM_DESC_CTOR_PATH_NULL) \
1389X(CASE_FS_STREAM_DESC_CTOR_PATH_EMPTY) \
1390X(CASE_FS_STREAM_DESC_CTOR_FLAGS_ZERO) \
1391X(CASE_FS_STREAM_DESC_CTOR_OOM_1) \
1392X(CASE_FS_STREAM_DESC_CTOR_OPEN_FAIL)
1394#define FS_STREAM_MAKE_DESC_CTOR_TEST(case_sym) \
1395LEXLEO_MAKE_TEST(fs_stream_desc_ctor, case_sym)
1397static const struct CMUnitTest desc_ctor_fs_stream_tests[] = {
1398 FS_STREAM_DESC_CTOR_CASES(FS_STREAM_MAKE_DESC_CTOR_TEST)
1401#undef FS_STREAM_DESC_CTOR_CASES
1402#undef FS_STREAM_MAKE_DESC_CTOR_TEST
1409 static const struct CMUnitTest fs_stream_tests[] = {
1415 failed += cmocka_run_group_tests(fs_stream_tests, NULL, NULL);
1416 failed += cmocka_run_group_tests(fs_stream_stream_create_stream_tests, NULL, NULL);
1417 failed += cmocka_run_group_tests(create_desc_fs_stream_tests, NULL, NULL);
1418 failed += cmocka_run_group_tests(desc_ctor_fs_stream_tests, NULL, NULL);
Composition Root API for wiring the fs_stream adapter into the stream factory.
stream_status_t fs_stream_create_stream(stream_t **out, const fs_stream_args_t *args, const fs_stream_cfg_t *cfg, const fs_stream_env_t *env)
Create a file-backed stream instance.
fs_stream_cfg_t fs_stream_default_cfg(void)
Return a default configuration for the fs_stream adapter.
stream_status_t fs_stream_create_desc(stream_adapter_desc_t *out, stream_key_t key, const fs_stream_cfg_t *cfg, const fs_stream_env_t *env, const osal_mem_ops_t *mem)
Build an adapter descriptor for registering fs_stream in a factory.
fs_stream_env_t fs_stream_default_env(const osal_file_env_t *file_env, const osal_file_ops_t *file_ops, const stream_env_t *port_env)
Build a default environment for the fs_stream adapter.
const osal_file_ops_t * osal_file_test_fake_ops(void)
void * osal_memset(void *s, int c, size_t n)
const osal_mem_ops_t * osal_mem_test_fake_ops(void)
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.
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.
Arguments provided when creating a file-backed stream.
const char * path
UTF-8 path of the target file.
Configuration type for the fs_stream adapter.
int reserved
Reserved configuration field.
Injected dependencies for the fs_stream adapter.
osal_file_env_t file_env
Borrowed OSAL file environment.
stream_env_t port_env
Borrowed stream port environment.
const osal_file_ops_t * file_ops
Borrowed OSAL file operations table.
Public descriptor used to register a concrete stream adapter.
Runtime environment for the stream port.
Private handle structure for a stream_t.
static void test_fs_stream_default_cfg(void **state)
Test fs_stream_default_cfg().
fs_create_stream_scenario_t
Scenarios for fs_stream_create_stream().
@ FS_CREATE_STREAM_SCENARIO_OUT_NULL
@ FS_CREATE_STREAM_SCENARIO_ENV_NULL
@ FS_CREATE_STREAM_SCENARIO_OPEN_FAIL
@ FS_CREATE_STREAM_SCENARIO_ARGS_NULL
@ FS_CREATE_STREAM_SCENARIO_OK
@ FS_CREATE_STREAM_SCENARIO_FLAGS_ZERO
@ FS_CREATE_STREAM_SCENARIO_OOM
@ FS_CREATE_STREAM_SCENARIO_PATH_NULL
@ FS_CREATE_STREAM_SCENARIO_PATH_EMPTY
@ FS_CREATE_STREAM_SCENARIO_CFG_NULL
fs_stream_create_desc_scenario_t
Scenarios for fs_stream_create_desc().
@ FS_STREAM_CREATE_DESC_SCENARIO_OOM
@ FS_STREAM_CREATE_DESC_SCENARIO_ENV_NULL
@ FS_STREAM_CREATE_DESC_SCENARIO_OK
@ FS_STREAM_CREATE_DESC_SCENARIO_OUT_NULL
@ FS_STREAM_CREATE_DESC_SCENARIO_KEY_NULL
@ FS_STREAM_CREATE_DESC_SCENARIO_KEY_EMPTY
@ FS_STREAM_CREATE_DESC_SCENARIO_MEM_NULL
@ FS_STREAM_CREATE_DESC_SCENARIO_CFG_NULL
static void test_fs_stream_default_env(void **state)
Test fs_stream_default_env().
fs_stream_desc_ctor_scenario_t
Scenarios for fs_stream_create_desc() descriptor constructor usage.
@ FS_STREAM_DESC_CTOR_SCENARIO_ARGS_NULL
@ FS_STREAM_DESC_CTOR_SCENARIO_OPEN_FAIL
@ FS_STREAM_DESC_CTOR_SCENARIO_FLAGS_ZERO
@ FS_STREAM_DESC_CTOR_SCENARIO_PATH_EMPTY
@ FS_STREAM_DESC_CTOR_SCENARIO_OK
@ FS_STREAM_DESC_CTOR_SCENARIO_OOM
@ FS_STREAM_DESC_CTOR_SCENARIO_OUT_NULL
@ FS_STREAM_DESC_CTOR_SCENARIO_PATH_NULL