diff --git a/lib/libsbuf/tests/sbuf_core_test.c b/lib/libsbuf/tests/sbuf_core_test.c --- a/lib/libsbuf/tests/sbuf_core_test.c +++ b/lib/libsbuf/tests/sbuf_core_test.c @@ -25,6 +25,8 @@ #include #include + +#include #include #include #include @@ -32,12 +34,10 @@ #include #include -#include - #include "sbuf_test_common.h" -static char test_string[] = "this is a test string"; -#define TEST_STRING_CHOP_COUNT 5 +static char test_string[] = "this is a test string"; +#define TEST_STRING_CHOP_COUNT 5 _Static_assert(nitems(test_string) > TEST_STRING_CHOP_COUNT, "test_string is too short"); @@ -75,8 +75,8 @@ buf_len = sbuf_len(sb); ATF_REQUIRE_MSG(buf_len == 0, "sbuf_len (%zd) != 0", buf_len); - ATF_REQUIRE_STREQ_MSG(sbuf_data(sb), "", - "sbuf (\"%s\") was not empty", sbuf_data(sb)); + ATF_REQUIRE_STREQ_MSG(sbuf_data(sb), "", "sbuf (\"%s\") was not empty", + sbuf_data(sb)); sbuf_delete(sb); } @@ -103,7 +103,6 @@ static int drain_ret0(void *arg, const char *data, int len) { - (void)arg; (void)data; (void)len; @@ -144,10 +143,11 @@ buf_len = sbuf_len(sb); ATF_REQUIRE_MSG(buf_len == (ssize_t)(i * test_string_len), "sbuf_len (%zd) != %zu", buf_len, i * test_string_len); - ATF_REQUIRE_MSG(sbuf_cat(sb, test_string) == 0, "sbuf_cat failed"); + ATF_REQUIRE_MSG(sbuf_cat(sb, test_string) == 0, + "sbuf_cat failed"); } -#ifdef HAVE_SBUF_SET_FLAGS +#ifdef HAVE_SBUF_SET_FLAGS sbuf_set_flags(sb, SBUF_INCLUDENUL); ATF_REQUIRE_MSG((ssize_t)(i * test_string_len + 1) == sbuf_len(sb), "sbuf_len(..) didn't report the NUL char"); @@ -172,8 +172,8 @@ child_proc = atf_utils_fork(); if (child_proc == 0) { - ATF_REQUIRE_EQ_MSG(0, sbuf_finish(&sb), "sbuf_finish failed: %s", - strerror(errno)); + ATF_REQUIRE_EQ_MSG(0, sbuf_finish(&sb), + "sbuf_finish failed: %s", strerror(errno)); sbuf_putbuf(&sb); exit(0); @@ -182,7 +182,8 @@ sbuf_putc(&sb, ' '); - ATF_CHECK_EQ_MSG(-1, sbuf_finish(&sb), "failed to return error on overflow"); + ATF_CHECK_EQ_MSG(-1, sbuf_finish(&sb), + "failed to return error on overflow"); sbuf_delete(&sb); } @@ -241,27 +242,197 @@ sbuf_delete(sb); } -ATF_TP_ADD_TCS(tp) +ATF_TC(sbuf_get_flags_test); +ATF_TC_HEAD(sbuf_get_flags_test, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test subf_get_flags for returning user flags"); +} +ATF_TC_BODY(sbuf_get_flags_test, tc) +{ + struct sbuf *sb; + + // Step 1: Create an auto-extended sbuf and verify initial user flags + sb = sbuf_new_auto(); + ATF_REQUIRE(sb != NULL); + ATF_CHECK_EQ_MSG(sbuf_get_flags(sb), SBUF_AUTOEXTEND, + "sbuf_get_flags should return SBUF_AUTOEXTEND for auto-extend buffers"); + + // Step 2: Verify internal flags are not included + ATF_CHECK_MSG((sbuf_get_flags(sb) & SBUF_FINISHED) == 0, + "sbuf_get_flags should not return internal flags like SBUF_FINISHED"); + + // Cleanup + sbuf_delete(sb); +} + +ATF_TC(sbuf_set_flags_test); +ATF_TC_HEAD(sbuf_set_flags_test, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test subf_set_flags for correctly setting user flags"); +} +ATF_TC_BODY(sbuf_set_flags_test, tc) +{ + struct sbuf *sb; + + // Step 1: Create a fixed-length sbuf and set additional flags + sb = sbuf_new(NULL, NULL, 128, SBUF_FIXEDLEN); + ATF_REQUIRE(sb != NULL); + + sbuf_set_flags(sb, SBUF_INCLUDENUL | SBUF_DRAINTOEOR); + ATF_CHECK_EQ_MSG(sbuf_get_flags(sb), + (SBUF_INCLUDENUL | SBUF_DRAINTOEOR), + "sbuf_get_flags should reflect flags set by sbuf_set_flags"); + + // Step 2: Try setting a non-user flag and ensure it is ignored + sbuf_set_flags(sb, SBUF_DYNAMIC); // SBUF_DYNAMIC is not a user flag + ATF_CHECK_MSG((sbuf_get_flags(sb) & SBUF_DYNAMIC) == 0, + "sbuf_set_flags should not modify non-user flags like SBUF_DYNAMIC"); + + // Cleanup + sbuf_delete(sb); +} + +ATF_TC(sbuf_clear_flags_test); +ATF_TC_HEAD(sbuf_clear_flags_test, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test sbuf_clear_flags for correctly clearing user flags"); +} +ATF_TC_BODY(sbuf_clear_flags_test, tc) +{ + struct sbuf *sb; + + // Step 1: Create a fixed-length sbuf and set multiple user flags + sb = sbuf_new(NULL, NULL, 128, SBUF_FIXEDLEN); + ATF_REQUIRE(sb != NULL); + sbuf_set_flags(sb, SBUF_INCLUDENUL | SBUF_DRAINTOEOR | SBUF_NOWAIT); + + // Verify that flags are correctly set + ATF_CHECK_EQ_MSG(sbuf_get_flags(sb), + (SBUF_FIXEDLEN | SBUF_INCLUDENUL | SBUF_DRAINTOEOR | SBUF_NOWAIT), + "sbuf_get_flags should reflect all user flags set"); + + // Step 2: Clear a single user flag + sbuf_clear_flags(sb, SBUF_DRAINTOEOR); + ATF_CHECK_EQ_MSG(sbuf_get_flags(sb), + (SBUF_FIXEDLEN | SBUF_INCLUDENUL | SBUF_NOWAIT), + "sbuf_get_flags should exclude the cleared flag (SBUF_DRAINTOEOR)"); + + // Step 3: Clear multiple user flags + sbuf_clear_flags(sb, SBUF_INCLUDENUL | SBUF_NOWAIT); + ATF_CHECK_EQ_MSG(sbuf_get_flags(sb), SBUF_FIXEDLEN, + "sbuf_get_flags should exclude all cleared flags (SBUF_INCLUDENUL and SBUF_NOWAIT"); + + // Step 4: Attepmt to clear a flag that isn't set + sbuf_clear_flags(sb, SBUF_AUTOEXTEND); // SBUF_AUTOEXTEND was never set + ATF_CHECK_EQ_MSG(sbuf_get_flags(sb), SBUF_FIXEDLEN, + "Clearing a flag that isn't set should not affect other flags"); + + // Step 5: Attempt to clear a non-user flag + sbuf_clear_flags(sb, SBUF_DYNAMIC); // SBUF_DYNAMIC is not a user flag + ATF_CHECK_MSG((sbuf_get_flags(sb) & SBUF_DYNAMIC) == 0, + "sbuf_clear_flags should not affect non-user flags like SBUF_DYNAMIC"); + + // Cleanup + sbuf_delete(sb); +} + +ATF_TC(sbuf_flags_interaction_test); +ATF_TC_HEAD(sbuf_flags_interaction_test, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test interaction of sbuf_get_flags, sbuf_set_flags, and sbuf_clear_flags"); +} +ATF_TC_BODY(sbuf_flags_interaction_test, tc) { + struct sbuf *sb; + + // Step 1: Create an auto-extend sbuf + sb = sbuf_new_auto(); + ATF_REQUIRE(sb != NULL); + + // Verify the initial user flags (only SBUF_AUTOEXTEND should be set) + ATF_CHECK_EQ_MSG(sbuf_get_flags(sb), SBUF_AUTOEXTEND, + "sbuf_get_flags should initially return SBUF_AUTOEXTEND"); + + // Step 2: Set additional user flags + sbuf_set_flags(sb, SBUF_INCLUDENUL | SBUF_DRAINTOEOR); + ATF_CHECK_EQ_MSG(sbuf_get_flags(sb), + (SBUF_AUTOEXTEND | SBUF_INCLUDENUL | SBUF_DRAINTOEOR), + "sbuf_get_flags should reflect flags set by sbuf_set_flags"); + + // Setp 3: Clear a single user flag + sbuf_clear_flags(sb, SBUF_AUTOEXTEND); + ATF_CHECK_EQ_MSG(sbuf_get_flags(sb), + (SBUF_INCLUDENUL | SBUF_DRAINTOEOR), + "sbuf_get_flags should exclude flags cleared by sbuf_clear_flags"); + + // Cleanup + sbuf_delete(sb); +} + +ATF_TC(sbuf_new_positive_test); +ATF_TC_HEAD(sbuf_new_positive_test, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sbuf_new with valid inputs"); +} +ATF_TC_BODY(sbuf_new_positive_test, tc) +{ + struct sbuf *sb; + char buf[128]; + + // Case 1: Dynamica allocation of sbuf and buffer + sb = sbuf_new(NULL, NULL, 128, SBUF_AUTOEXTEND); + ATF_REQUIRE(sb != NULL); + ATF_CHECK_EQ_MSG(sbuf_get_flags(sb), SBUF_AUTOEXTEND, + "sbuf_new should set SBUF_AUTOEXTEND when specified"); + sbuf_delete(sb); + + // Case 2: Preallocated sbuf, dynamic buffer + struct sbuf prealloc; + sb = sbuf_new(&prealloc, NULL, 128, SBUF_FIXEDLEN); + ATF_REQUIRE(sb == &prealloc); + ATF_CHECK_EQ_MSG(sbuf_get_flags(sb), SBUF_FIXEDLEN, + "sbuf_new should set SBUF_FIXEDLEN when specified"); + sbuf_delete(sb); + // Case 3: Preallocated sbuf and buffer + sb = sbuf_new(&prealloc, buf, sizeof(buf), SBUF_FIXEDLEN); + ATF_REQUIRE(sb == &prealloc); + ATF_REQUIRE(sb->s_buf == buf); + ATF_CHECK_EQ_MSG(sb->s_size, sizeof(buf), + "Buffer size should match preallocated buffer"); + sbuf_delete(sb); +} + +ATF_TP_ADD_TCS(tp) +{ ATF_TP_ADD_TC(tp, sbuf_clear_test); ATF_TP_ADD_TC(tp, sbuf_done_and_sbuf_finish_test); ATF_TP_ADD_TC(tp, sbuf_drain_ret0_test); ATF_TP_ADD_TC(tp, sbuf_len_test); ATF_TP_ADD_TC(tp, sbuf_new_fixedlen); -#if 0 - /* TODO */ -#ifdef HAVE_SBUF_CLEAR_FLAGS - ATF_TP_ADD_TC(tp, sbuf_clear_flags_test); -#endif -#ifdef HAVE_SBUF_GET_FLAGS + +#ifdef HAVE_SBUF_GET_FLAGS ATF_TP_ADD_TC(tp, sbuf_get_flags_test); -#endif ATF_TP_ADD_TC(tp, sbuf_new_positive_test); - ATF_TP_ADD_TC(tp, sbuf_new_negative_test); -#ifdef HAVE_SBUF_SET_FLAGS +#endif + +#if defined(HAVE_SBUF_SET_FLAGS) && defined(HAVE_SBUF_GET_FLAGS) ATF_TP_ADD_TC(tp, sbuf_set_flags_test); #endif + +#if defined(HAVE_SBUF_GET_FLAGS) && defined(HAVE_SBUF_SET_FLAGS) && \ + defined(HAVE_SBUF_CLEAR_FLAGS) + ATF_TP_ADD_TC(tp, sbuf_clear_flags_test); + ATF_TP_ADD_TC(tp, sbuf_flags_interaction_test); +#endif + +#if 0 + /* TODO */ + ATF_TP_ADD_TC(tp, sbuf_new_negative_test); #endif ATF_TP_ADD_TC(tp, sbuf_setpos_test);