1316557Sngie/*- 2346920Sngie * Copyright (c) 2017 Enji Cooper <ngie@freebsd.org> 3316557Sngie * 4316557Sngie * Redistribution and use in source and binary forms, with or without 5316557Sngie * modification, are permitted provided that the following conditions 6316557Sngie * are met: 7316557Sngie * 1. Redistributions of source code must retain the above copyright 8316557Sngie * notice, this list of conditions and the following disclaimer. 9316557Sngie * 2. Redistributions in binary form must reproduce the above copyright 10316557Sngie * notice, this list of conditions and the following disclaimer in the 11316557Sngie * documentation and/or other materials provided with the distribution. 12316557Sngie * 13316557Sngie * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14316557Sngie * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15316557Sngie * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16316557Sngie * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17316557Sngie * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18316557Sngie * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19316557Sngie * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20316557Sngie * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21316557Sngie * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22316557Sngie * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23316557Sngie * SUCH DAMAGE. 24316557Sngie */ 25316557Sngie 26321117Sngie#include <sys/cdefs.h> 27321117Sngie__FBSDID("$FreeBSD: stable/11/lib/libsbuf/tests/sbuf_core_test.c 346920 2019-04-29 19:36:46Z ngie $"); 28321117Sngie 29316557Sngie#include <sys/param.h> 30316557Sngie#include <sys/sbuf.h> 31316557Sngie#include <errno.h> 32316557Sngie#include <stdarg.h> 33316557Sngie#include <stdio.h> 34316557Sngie#include <stdlib.h> 35316557Sngie#include <string.h> 36316557Sngie#include <unistd.h> 37316557Sngie 38316557Sngie#include <atf-c.h> 39316557Sngie 40316557Sngie#include "sbuf_test_common.h" 41316557Sngie 42316557Sngiestatic char test_string[] = "this is a test string"; 43316557Sngie#define TEST_STRING_CHOP_COUNT 5 44316557Sngie_Static_assert(nitems(test_string) > TEST_STRING_CHOP_COUNT, 45316557Sngie "test_string is too short"); 46316557Sngie 47316557SngieATF_TC_WITHOUT_HEAD(sbuf_clear_test); 48316557SngieATF_TC_BODY(sbuf_clear_test, tc) 49316557Sngie{ 50316557Sngie struct sbuf *sb; 51316557Sngie ssize_t buf_len; 52316557Sngie pid_t child_proc; 53316557Sngie 54316557Sngie sb = sbuf_new_auto(); 55316557Sngie ATF_REQUIRE_MSG(sb != NULL, "sbuf_new_auto failed: %s", 56316557Sngie strerror(errno)); 57316557Sngie 58316557Sngie ATF_REQUIRE_MSG(sbuf_cat(sb, test_string) == 0, "sbuf_cat failed"); 59316557Sngie 60316557Sngie /* 61316557Sngie * Cheat so we can get the contents of the buffer before calling 62316557Sngie * sbuf_finish(3) below, making additional sbuf changes impossible. 63316557Sngie */ 64316557Sngie child_proc = atf_utils_fork(); 65316557Sngie if (child_proc == 0) { 66316557Sngie sbuf_putbuf(sb); 67316557Sngie exit(0); 68316557Sngie } 69316557Sngie atf_utils_wait(child_proc, 0, test_string, ""); 70316557Sngie 71316557Sngie sbuf_clear(sb); 72316557Sngie 73316557Sngie ATF_REQUIRE_MSG(sbuf_finish(sb) == 0, "sbuf_finish failed: %s", 74316557Sngie strerror(errno)); 75316557Sngie 76316557Sngie buf_len = sbuf_len(sb); 77316557Sngie ATF_REQUIRE_MSG(buf_len == 0, "sbuf_len (%zd) != 0", buf_len); 78316557Sngie ATF_REQUIRE_STREQ_MSG(sbuf_data(sb), "", 79316557Sngie "sbuf (\"%s\") was not empty", sbuf_data(sb)); 80316557Sngie 81316557Sngie sbuf_delete(sb); 82316557Sngie} 83316557Sngie 84316557SngieATF_TC_WITHOUT_HEAD(sbuf_done_and_sbuf_finish_test); 85316557SngieATF_TC_BODY(sbuf_done_and_sbuf_finish_test, tc) 86316557Sngie{ 87316557Sngie struct sbuf *sb; 88316557Sngie 89316557Sngie sb = sbuf_new_auto(); 90316557Sngie ATF_REQUIRE_MSG(sb != NULL, "sbuf_new_auto failed: %s", 91316557Sngie strerror(errno)); 92316557Sngie 93316557Sngie ATF_CHECK(sbuf_done(sb) == 0); 94316557Sngie 95316557Sngie ATF_REQUIRE_MSG(sbuf_finish(sb) == 0, "sbuf_finish failed: %s", 96316557Sngie strerror(errno)); 97316557Sngie 98316557Sngie ATF_CHECK(sbuf_done(sb) != 0); 99316557Sngie 100316557Sngie sbuf_delete(sb); 101316557Sngie} 102316557Sngie 103316557SngieATF_TC_WITHOUT_HEAD(sbuf_len_test); 104316557SngieATF_TC_BODY(sbuf_len_test, tc) 105316557Sngie{ 106316557Sngie struct sbuf *sb; 107316557Sngie ssize_t buf_len, test_string_len; 108316557Sngie int i; 109316557Sngie 110316557Sngie sb = sbuf_new_auto(); 111316557Sngie ATF_REQUIRE_MSG(sb != NULL, "sbuf_new_auto failed: %s", 112316557Sngie strerror(errno)); 113316557Sngie 114316557Sngie test_string_len = strlen(test_string); 115316557Sngie for (i = 0; i < 20; i++) { 116316557Sngie buf_len = sbuf_len(sb); 117316557Sngie ATF_REQUIRE_MSG(buf_len == (ssize_t)(i * test_string_len), 118316557Sngie "sbuf_len (%zd) != %zu", buf_len, i * test_string_len); 119316557Sngie ATF_REQUIRE_MSG(sbuf_cat(sb, test_string) == 0, "sbuf_cat failed"); 120316557Sngie } 121316557Sngie 122316557Sngie#ifdef HAVE_SBUF_SET_FLAGS 123316557Sngie sbuf_set_flags(sb, SBUF_INCLUDENUL); 124316557Sngie ATF_REQUIRE_MSG((ssize_t)(i * test_string_len + 1) == sbuf_len(sb), 125316557Sngie "sbuf_len(..) didn't report the NUL char"); 126316557Sngie#endif 127316557Sngie 128316557Sngie ATF_REQUIRE_MSG(sbuf_finish(sb) == 0, "sbuf_finish failed: %s", 129316557Sngie strerror(errno)); 130316557Sngie 131316557Sngie sbuf_delete(sb); 132316557Sngie} 133316557Sngie 134316557SngieATF_TC_WITHOUT_HEAD(sbuf_setpos_test); 135316557SngieATF_TC_BODY(sbuf_setpos_test, tc) 136316557Sngie{ 137316557Sngie struct sbuf *sb; 138316557Sngie size_t test_string_chopped_len, test_string_len; 139316557Sngie ssize_t buf_len; 140316557Sngie 141316557Sngie sb = sbuf_new_auto(); 142316557Sngie ATF_REQUIRE_MSG(sb != NULL, "sbuf_new_auto failed: %s", 143316557Sngie strerror(errno)); 144316557Sngie 145316557Sngie /* 146316557Sngie * An obvious sanity check -- if sbuf_len(..) lies, these invariants 147316557Sngie * are impossible to test. 148316557Sngie */ 149316557Sngie ATF_REQUIRE(sbuf_len(sb) == 0); 150316557Sngie 151316557Sngie ATF_CHECK(sbuf_setpos(sb, -1) == -1); 152316557Sngie ATF_CHECK(sbuf_setpos(sb, 0) == 0); 153316557Sngie ATF_CHECK(sbuf_setpos(sb, 1) == -1); 154316557Sngie 155316557Sngie ATF_REQUIRE_MSG(sbuf_cat(sb, test_string) == 0, "sbuf_cat failed"); 156316557Sngie 157316557Sngie buf_len = sbuf_len(sb); 158316557Sngie test_string_len = strlen(test_string); 159316557Sngie test_string_chopped_len = test_string_len - TEST_STRING_CHOP_COUNT; 160316557Sngie ATF_REQUIRE_MSG(buf_len == (ssize_t)test_string_len, 161316557Sngie "sbuf length (%zd) != test_string length (%zu)", buf_len, 162316557Sngie test_string_len); 163316557Sngie 164316557Sngie /* Out of bounds (under length) */ 165316557Sngie ATF_CHECK(sbuf_setpos(sb, -1) == -1); 166316557Sngie /* 167316557Sngie * Out of bounds (over length) 168316557Sngie * 169316557Sngie * Note: SBUF_INCLUDENUL not set, so take '\0' into account. 170316557Sngie */ 171316557Sngie ATF_CHECK(sbuf_setpos(sb, test_string_len + 2) == -1); 172316557Sngie /* Within bounds */ 173316557Sngie ATF_CHECK(sbuf_setpos(sb, test_string_chopped_len) == 0); 174316557Sngie 175316557Sngie ATF_REQUIRE_MSG(sbuf_finish(sb) == 0, "sbuf_finish failed: %s", 176316557Sngie strerror(errno)); 177316557Sngie 178316557Sngie buf_len = sbuf_len(sb); 179316557Sngie ATF_REQUIRE_MSG(buf_len == (ssize_t)test_string_chopped_len, 180316557Sngie "sbuf_setpos didn't truncate string as expected"); 181316557Sngie ATF_REQUIRE_MSG(strncmp(sbuf_data(sb), test_string, buf_len) == 0, 182316557Sngie "sbuf (\"%s\") != test string (\"%s\") for [0,%zd]", sbuf_data(sb), 183316557Sngie test_string, buf_len); 184316557Sngie 185316557Sngie sbuf_delete(sb); 186316557Sngie} 187316557Sngie 188316557SngieATF_TP_ADD_TCS(tp) 189316557Sngie{ 190316557Sngie 191316557Sngie ATF_TP_ADD_TC(tp, sbuf_clear_test); 192316557Sngie ATF_TP_ADD_TC(tp, sbuf_done_and_sbuf_finish_test); 193316557Sngie ATF_TP_ADD_TC(tp, sbuf_len_test); 194316557Sngie#if 0 195316557Sngie /* TODO */ 196316557Sngie#ifdef HAVE_SBUF_CLEAR_FLAGS 197316557Sngie ATF_TP_ADD_TC(tp, sbuf_clear_flags_test); 198316557Sngie#endif 199316557Sngie#ifdef HAVE_SBUF_GET_FLAGS 200316557Sngie ATF_TP_ADD_TC(tp, sbuf_get_flags_test); 201316557Sngie#endif 202316557Sngie ATF_TP_ADD_TC(tp, sbuf_new_positive_test); 203316557Sngie ATF_TP_ADD_TC(tp, sbuf_new_negative_test); 204316557Sngie#ifdef HAVE_SBUF_SET_FLAGS 205316557Sngie ATF_TP_ADD_TC(tp, sbuf_set_flags_test); 206316557Sngie#endif 207316557Sngie#endif 208316557Sngie ATF_TP_ADD_TC(tp, sbuf_setpos_test); 209316557Sngie 210316557Sngie return (atf_no_error()); 211316557Sngie} 212