Index: lib/libsbuf/tests/sbuf_core_test.c =================================================================== --- lib/libsbuf/tests/sbuf_core_test.c +++ lib/libsbuf/tests/sbuf_core_test.c @@ -1,4 +1,4 @@ -/*- + /*- * Copyright (c) 2017 Enji Cooper * * Redistribution and use in source and binary forms, with or without @@ -26,7 +26,9 @@ #include __FBSDID("$FreeBSD$"); + #include +#include #include #include #include @@ -44,6 +46,7 @@ _Static_assert(nitems(test_string) > TEST_STRING_CHOP_COUNT, "test_string is too short"); + ATF_TC_WITHOUT_HEAD(sbuf_clear_test); ATF_TC_BODY(sbuf_clear_test, tc) { @@ -63,6 +66,9 @@ */ child_proc = atf_utils_fork(); if (child_proc == 0) { + ATF_REQUIRE_EQ_MSG(0, sbuf_finish(sb), "sbuf_finish failed: %s", + strerror(errno)); + sbuf_putbuf(sb); exit(0); } @@ -100,6 +106,34 @@ sbuf_delete(sb); } +static int +drain_ret0(void *arg, const char *data, int len) +{ + + (void)arg; + (void)data; + (void)len; + + return (0); +} + +ATF_TC_WITHOUT_HEAD(sbuf_drain_ret0_test); +ATF_TC_BODY(sbuf_drain_ret0_test, tc) +{ + struct sbuf *sb; + + sb = sbuf_new_auto(); + + sbuf_set_drain(sb, drain_ret0, NULL); + + sbuf_cat(sb, test_string); + + ATF_CHECK_EQ_MSG(-1, sbuf_finish(sb), + "required to return error when drain func returns 0"); + ATF_CHECK_EQ_MSG(EDEADLK, errno, + "errno required to be EDEADLK when drain func returns 0"); +} + ATF_TC_WITHOUT_HEAD(sbuf_len_test); ATF_TC_BODY(sbuf_len_test, tc) { @@ -131,6 +165,34 @@ sbuf_delete(sb); } +ATF_TC_WITHOUT_HEAD(sbuf_new_fixedlen); +ATF_TC_BODY(sbuf_new_fixedlen, tc) +{ + char buf[strlen(test_string) + 1]; + struct sbuf sb; + pid_t child_proc; + + sbuf_new(&sb, buf, sizeof(buf), SBUF_FIXEDLEN); + + sbuf_cat(&sb, test_string); + + child_proc = atf_utils_fork(); + if (child_proc == 0) { + ATF_REQUIRE_EQ_MSG(0, sbuf_finish(&sb), "sbuf_finish failed: %s", + strerror(errno)); + + sbuf_putbuf(&sb); + exit(0); + } + atf_utils_wait(child_proc, 0, test_string, ""); + + sbuf_putc(&sb, ' '); + + ATF_CHECK_EQ_MSG(-1, sbuf_finish(&sb), "failed to return error on overflow"); + + sbuf_delete(&sb); +} + ATF_TC_WITHOUT_HEAD(sbuf_setpos_test); ATF_TC_BODY(sbuf_setpos_test, tc) { @@ -147,8 +209,6 @@ * are impossible to test. */ ATF_REQUIRE(sbuf_len(sb) == 0); - - ATF_CHECK(sbuf_setpos(sb, -1) == -1); ATF_CHECK(sbuf_setpos(sb, 0) == 0); ATF_CHECK(sbuf_setpos(sb, 1) == -1); @@ -161,8 +221,6 @@ "sbuf length (%zd) != test_string length (%zu)", buf_len, test_string_len); - /* Out of bounds (under length) */ - ATF_CHECK(sbuf_setpos(sb, -1) == -1); /* * Out of bounds (over length) * @@ -185,27 +243,136 @@ sbuf_delete(sb); } +ATF_TC_WITHOUT_HEAD(sbuf_setpos_test_negative_pos); +ATF_TC_BODY(sbuf_setpos_test_negative_pos, tc) +{ + struct sbuf *sb; + + sb = sbuf_new_auto(); + ATF_REQUIRE_MSG(sb != NULL, "sbuf_new_auto failed: %s", + strerror(errno)); + + atf_tc_expect_death("position cannot be negative"); + sbuf_setpos(sb, -1); +} + +ATF_TC_WITHOUT_HEAD(sbuf_clear_flags_test); +ATF_TC_BODY(sbuf_clear_flags_test, tc) +{ + struct sbuf *sb = NULL; + + sb = sbuf_new_auto(); + ATF_REQUIRE_MSG(sb != NULL, "sbuf_new_auto failed: %s", + strerror(errno)); + + sbuf_set_flags(sb, SBUF_INCLUDENUL); + sbuf_set_flags(sb, SBUF_DRAINTOEOR); + + sbuf_clear_flags(sb, SBUF_INCLUDENUL); + int actual_flags = sbuf_get_flags(sb); + ATF_CHECK((actual_flags & SBUF_INCLUDENUL) == 0); + + int expected_flags = SBUF_AUTOEXTEND | SBUF_DRAINTOEOR; + ATF_CHECK(actual_flags == expected_flags); + + sbuf_clear_flags(sb, SBUF_AUTOEXTEND | SBUF_DRAINTOEOR); + actual_flags = sbuf_get_flags(sb); + ATF_CHECK(actual_flags == 0); + sbuf_delete(sb); +} + +ATF_TC_WITHOUT_HEAD(sbuf_set_get_flags_test); +ATF_TC_BODY(sbuf_set_get_flags_test, tc) +{ + struct sbuf *sb = NULL; + + char buf[strlen(test_string) + 1]; + sb = sbuf_new(sb, buf, sizeof(buf), SBUF_FIXEDLEN); + + int actual_flags = sbuf_get_flags(sb); + int expected_flags = SBUF_FIXEDLEN; + ATF_CHECK(actual_flags == expected_flags); + + sbuf_set_flags(sb, SBUF_AUTOEXTEND); + sbuf_set_flags(sb, SBUF_INCLUDENUL); + sbuf_set_flags(sb, SBUF_DRAINTOEOR); + + actual_flags = sbuf_get_flags(sb); + expected_flags = SBUF_AUTOEXTEND | SBUF_INCLUDENUL | SBUF_DRAINTOEOR; + ATF_CHECK(actual_flags == expected_flags); + ATF_CHECK((actual_flags & SBUF_AUTOEXTEND) == SBUF_AUTOEXTEND); + ATF_CHECK((actual_flags & SBUF_INCLUDENUL) == SBUF_INCLUDENUL); + ATF_CHECK((actual_flags & SBUF_DRAINTOEOR) == SBUF_DRAINTOEOR); + + sbuf_delete(sb); +} + +ATF_TC_WITHOUT_HEAD(sbuf_new_positive_test); +ATF_TC_BODY(sbuf_new_positive_test, tc) +{ + struct sbuf *sb = NULL; + + char buf[strlen(test_string) + 1]; + sb = sbuf_new(sb, buf, sizeof(buf), SBUF_FIXEDLEN); + ATF_REQUIRE_MSG(sb != NULL, "sbuf_new failed due to %s", + strerror(errno)); + + sbuf_delete(sb); + + sb = sbuf_new(sb, NULL, 0, SBUF_AUTOEXTEND); + ATF_REQUIRE_MSG(sb != NULL, "sbuf_new failed due to %s", + strerror(errno)); + sbuf_delete(sb); +} + +ATF_TC_WITHOUT_HEAD(sbuf_new_negative_test); +ATF_TC_BODY(sbuf_new_negative_test, tc) +{ + struct sbuf *sb = NULL; + + atf_tc_expect_death("Buffer length cannot be negative"); + sb = sbuf_new(sb, NULL, -1, SBUF_FIXEDLEN); +} + +ATF_TC_WITHOUT_HEAD(sbuf_new_negative_test_min_buf_size); +ATF_TC_BODY(sbuf_new_negative_test_min_buf_size, tc) +{ + struct sbuf *sb = NULL; + + atf_tc_expect_death("Minimum buffer length should be 2"); + sb = sbuf_new(sb, NULL, 1, SBUF_FIXEDLEN); +} + +ATF_TC_WITHOUT_HEAD(sbuf_new_negative_test_non_user_flags); +ATF_TC_BODY(sbuf_new_negative_test_non_user_flags, tc) +{ + struct sbuf *sb = NULL; + + atf_tc_expect_death("Non user flags cannot be specified"); + sb = sbuf_new(sb, NULL, 1, SBUF_FIXEDLEN | SBUF_DYNSTRUCT); +} + 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); -#if 0 - /* TODO */ + ATF_TP_ADD_TC(tp, sbuf_new_fixedlen); + #ifdef HAVE_SBUF_CLEAR_FLAGS ATF_TP_ADD_TC(tp, sbuf_clear_flags_test); #endif -#ifdef HAVE_SBUF_GET_FLAGS - ATF_TP_ADD_TC(tp, sbuf_get_flags_test); +#ifdef HAVE_SBUF_SET_FLAGS + ATF_TP_ADD_TC(tp, sbuf_set_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 - ATF_TP_ADD_TC(tp, sbuf_set_flags_test); -#endif -#endif + ATF_TP_ADD_TC(tp, sbuf_new_negative_test_min_buf_size); + ATF_TP_ADD_TC(tp, sbuf_new_negative_test_non_user_flags); ATF_TP_ADD_TC(tp, sbuf_setpos_test); + ATF_TP_ADD_TC(tp, sbuf_setpos_test_negative_pos); return (atf_no_error()); } Index: sys/kern/subr_sbuf.c =================================================================== --- sys/kern/subr_sbuf.c +++ sys/kern/subr_sbuf.c @@ -43,6 +43,7 @@ #include #include #else /* _KERNEL */ +#include #include #include #include @@ -59,7 +60,7 @@ #define SBMALLOC(size) malloc(size, M_SBUF, M_WAITOK|M_ZERO) #define SBFREE(buf) free(buf, M_SBUF) #else /* _KERNEL */ -#define KASSERT(e, m) +#define KASSERT(e, m) assert((e)) #define SBMALLOC(size) calloc(1, size) #define SBFREE(buf) free(buf) #endif /* _KERNEL */