1 /*- 2 * Copyright (c) 2017 Enji Cooper <ngie@freebsd.org> 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23 * SUCH DAMAGE. 24 */ 25 26 #include <sys/cdefs.h> 27 __FBSDID("$FreeBSD$"); 28 29 #include <sys/param.h> 30 #include <sys/sbuf.h> 31 #include <errno.h> 32 #include <libutil.h> 33 #include <stdio.h> 34 #include <stdlib.h> 35 #include <string.h> 36 37 #include <atf-c.h> 38 39 #include "sbuf_test_common.h" 40 41 static char test_string[] = "this is a test string"; 42 static char test_whitespace_string[] = " \f\n\r\t\v "; 43 static int test_buffer[] = { 0, 1, 2, 3, 4, 5, }; 44 45 static void 46 check_buffers_equal(const void *sb_buf, const void *test_buf, size_t len) 47 { 48 49 if (memcmp(sb_buf, test_buf, len) != 0) { 50 printf("sbuf:\n"); 51 hexdump(sb_buf, len, NULL, 0), 52 printf("test_buf:\n"); 53 hexdump(test_buf, len, NULL, 0); 54 atf_tc_fail("contents of sbuf didn't match test_buf contents"); 55 } 56 } 57 58 ATF_TC_WITHOUT_HEAD(sbuf_bcat_test); 59 ATF_TC_BODY(sbuf_bcat_test, tc) 60 { 61 struct sbuf *sb; 62 int *test_buffer_tmp; 63 ssize_t test_sbuf_len; 64 65 test_buffer_tmp = malloc(sizeof(test_buffer) * 2); 66 ATF_REQUIRE_MSG(test_buffer_tmp != NULL, "malloc failed"); 67 68 memcpy(test_buffer_tmp, test_buffer, sizeof(test_buffer)); 69 memcpy(&test_buffer_tmp[nitems(test_buffer)], test_buffer, 70 sizeof(test_buffer)); 71 72 sb = sbuf_new_auto(); 73 ATF_REQUIRE_MSG(sb != NULL, "sbuf_new_auto failed: %s", 74 strerror(errno)); 75 76 ATF_CHECK_MSG(sbuf_bcat(sb, test_buffer, sizeof(test_buffer)) == 0, 77 "sbuf_bcat failed"); 78 79 test_sbuf_len = sbuf_len(sb); 80 ATF_REQUIRE_MSG(test_sbuf_len == (ssize_t)sizeof(test_buffer), 81 "sbuf_len(..) => %zd (actual) != %zu (expected)", 82 test_sbuf_len, sizeof(test_buffer)); 83 84 ATF_CHECK_MSG(sbuf_bcat(sb, test_buffer, sizeof(test_buffer)) == 0, 85 "sbuf_bcat failed"); 86 87 test_sbuf_len = sbuf_len(sb); 88 ATF_REQUIRE_MSG(test_sbuf_len == (ssize_t)(2 * sizeof(test_buffer)), 89 "sbuf_len(..) => %zd (actual) != %zu (expected)", 90 test_sbuf_len, 2 * sizeof(test_buffer)); 91 92 ATF_REQUIRE_MSG(sbuf_finish(sb) == 0, "sbuf_finish failed: %s", 93 strerror(errno)); 94 95 check_buffers_equal(sbuf_data(sb), test_buffer_tmp, 96 (size_t)test_sbuf_len); 97 98 sbuf_delete(sb); 99 100 free(test_buffer_tmp); 101 } 102 103 ATF_TC_WITHOUT_HEAD(sbuf_bcpy_test); 104 ATF_TC_BODY(sbuf_bcpy_test, tc) 105 { 106 struct sbuf *sb; 107 ssize_t test_sbuf_len; 108 109 sb = sbuf_new_auto(); 110 ATF_REQUIRE_MSG(sb != NULL, "sbuf_new_auto failed: %s", 111 strerror(errno)); 112 113 ATF_CHECK_MSG(sbuf_bcpy(sb, test_buffer, sizeof(test_buffer)) == 0, 114 "sbuf_bcpy failed"); 115 116 test_sbuf_len = sbuf_len(sb); 117 ATF_REQUIRE_MSG(test_sbuf_len == (ssize_t)sizeof(test_buffer), 118 "sbuf_len(..) => %zd (actual) != %zu (expected)", 119 test_sbuf_len, sizeof(test_buffer)); 120 121 ATF_CHECK_MSG(sbuf_bcpy(sb, test_buffer, sizeof(test_buffer)) == 0, 122 "sbuf_bcpy failed"); 123 124 test_sbuf_len = sbuf_len(sb); 125 ATF_REQUIRE_MSG(test_sbuf_len == (ssize_t)sizeof(test_buffer), 126 "sbuf_len(..) => %zd (actual) != %zu (expected)", 127 test_sbuf_len, sizeof(test_buffer)); 128 129 ATF_REQUIRE_MSG(sbuf_finish(sb) == 0, "sbuf_finish failed: %s", 130 strerror(errno)); 131 132 check_buffers_equal(sbuf_data(sb), test_buffer, (size_t)test_sbuf_len); 133 134 sbuf_delete(sb); 135 } 136 137 ATF_TC_WITHOUT_HEAD(sbuf_cat_test); 138 ATF_TC_BODY(sbuf_cat_test, tc) 139 { 140 struct sbuf *sb; 141 char *test_string_tmp; 142 ssize_t test_sbuf_len; 143 144 asprintf(&test_string_tmp, "%s%s", test_string, test_string); 145 ATF_REQUIRE_MSG(test_string_tmp != NULL, "asprintf failed"); 146 147 sb = sbuf_new_auto(); 148 ATF_REQUIRE_MSG(sb != NULL, "sbuf_new_auto failed: %s", 149 strerror(errno)); 150 151 ATF_CHECK_MSG(sbuf_cat(sb, test_string) == 0, "sbuf_cat failed"); 152 153 test_sbuf_len = sbuf_len(sb); 154 ATF_REQUIRE_MSG(test_sbuf_len == (ssize_t)strlen(test_string), 155 "sbuf_len(..) => %zd (actual) != %zu (expected)", 156 test_sbuf_len, sizeof(test_string)); 157 158 ATF_CHECK_MSG(sbuf_cat(sb, test_string) == 0, "sbuf_cat failed"); 159 160 test_sbuf_len = sbuf_len(sb); 161 ATF_REQUIRE_MSG(test_sbuf_len == (ssize_t)strlen(test_string_tmp), 162 "sbuf_len(..) => %zd (actual) != %zu (expected)", 163 test_sbuf_len, strlen(test_string_tmp)); 164 165 ATF_REQUIRE_MSG(sbuf_finish(sb) == 0, "sbuf_finish failed: %s", 166 strerror(errno)); 167 168 ATF_REQUIRE_STREQ_MSG(sbuf_data(sb), test_string_tmp, 169 "sbuf (\"%s\") != test string (\"%s\")", sbuf_data(sb), 170 test_string_tmp); 171 172 sbuf_delete(sb); 173 174 free(test_string_tmp); 175 } 176 177 ATF_TC_WITHOUT_HEAD(sbuf_cpy_test); 178 ATF_TC_BODY(sbuf_cpy_test, tc) 179 { 180 struct sbuf *sb; 181 ssize_t test_sbuf_len; 182 183 sb = sbuf_new_auto(); 184 ATF_REQUIRE_MSG(sb != NULL, "sbuf_new_auto failed: %s", 185 strerror(errno)); 186 187 ATF_CHECK_MSG(sbuf_cpy(sb, test_string) == 0, "sbuf_cpy failed"); 188 189 test_sbuf_len = sbuf_len(sb); 190 ATF_REQUIRE_MSG(test_sbuf_len == (ssize_t)strlen(test_string), 191 "sbuf_len(..) => %zd (actual) != %zu (expected)", 192 test_sbuf_len, strlen(test_string)); 193 194 ATF_CHECK_MSG(sbuf_cpy(sb, test_string) == 0, "sbuf_cpy failed"); 195 196 test_sbuf_len = sbuf_len(sb); 197 ATF_REQUIRE_MSG(test_sbuf_len == (ssize_t)strlen(test_string), 198 "sbuf_len(..) => %zd (actual) != %zu (expected)", 199 test_sbuf_len, strlen(test_string)); 200 201 ATF_REQUIRE_MSG(sbuf_finish(sb) == 0, "sbuf_finish failed: %s", 202 strerror(errno)); 203 204 ATF_REQUIRE_STREQ_MSG(sbuf_data(sb), test_string, 205 "sbuf (\"%s\") != test string (\"%s\")", sbuf_data(sb), 206 test_string); 207 208 sbuf_delete(sb); 209 } 210 211 ATF_TC_WITHOUT_HEAD(sbuf_putc_test); 212 ATF_TC_BODY(sbuf_putc_test, tc) 213 { 214 struct sbuf *sb; 215 ssize_t test_sbuf_len; 216 size_t i; 217 218 sb = sbuf_new_auto(); 219 ATF_REQUIRE_MSG(sb != NULL, "sbuf_new_auto failed: %s", 220 strerror(errno)); 221 222 for (i = 0; i <= strlen(test_string); i++) { /* Include the NUL */ 223 ATF_REQUIRE_MSG(sbuf_putc(sb, test_string[i]) == 0, 224 "sbuf_putc failed"); 225 226 /* The best we can do until sbuf_finish(3) is called. */ 227 test_sbuf_len = sbuf_len(sb); 228 ATF_REQUIRE_MSG((ssize_t)(i + 1) == test_sbuf_len, 229 "sbuf_len(..) => %zd (actual) != %zu (expected)", 230 test_sbuf_len, i + 1); 231 } 232 233 ATF_REQUIRE_MSG(sbuf_finish(sb) == 0, "sbuf_finish failed: %s", 234 strerror(errno)); 235 236 ATF_REQUIRE_STREQ_MSG(sbuf_data(sb), test_string, 237 "sbuf (\"%s\") != test string (\"%s\")", sbuf_data(sb), 238 test_string); 239 240 sbuf_delete(sb); 241 } 242 243 ATF_TC_WITHOUT_HEAD(sbuf_trim_test); 244 ATF_TC_BODY(sbuf_trim_test, tc) 245 { 246 struct sbuf *sb; 247 ssize_t exp_sbuf_len, test_sbuf_len; 248 249 sb = sbuf_new_auto(); 250 ATF_REQUIRE_MSG(sb != NULL, "sbuf_new_auto failed: %s", 251 strerror(errno)); 252 253 ATF_CHECK_MSG(sbuf_cpy(sb, test_string) == 0, "sbuf_cpy failed"); 254 ATF_CHECK_MSG(sbuf_cat(sb, test_whitespace_string) == 0, 255 "sbuf_cat failed"); 256 257 /* The best we can do until sbuf_finish(3) is called. */ 258 exp_sbuf_len = (ssize_t)(strlen(test_string) + 259 strlen(test_whitespace_string)); 260 test_sbuf_len = sbuf_len(sb); 261 ATF_REQUIRE_MSG(exp_sbuf_len == test_sbuf_len, 262 "sbuf_len(..) => %zd (actual) != %zu (expected)", 263 test_sbuf_len, exp_sbuf_len); 264 265 ATF_REQUIRE_MSG(sbuf_trim(sb) == 0, "sbuf_trim failed"); 266 267 ATF_REQUIRE_MSG(sbuf_finish(sb) == 0, "sbuf_finish failed: %s", 268 strerror(errno)); 269 270 ATF_REQUIRE_STREQ_MSG(sbuf_data(sb), test_string, 271 "sbuf (\"%s\") != test string (\"%s\") (trimmed)", sbuf_data(sb), 272 test_string); 273 274 sbuf_delete(sb); 275 } 276 277 ATF_TP_ADD_TCS(tp) 278 { 279 280 ATF_TP_ADD_TC(tp, sbuf_bcat_test); 281 ATF_TP_ADD_TC(tp, sbuf_bcpy_test); 282 ATF_TP_ADD_TC(tp, sbuf_cat_test); 283 ATF_TP_ADD_TC(tp, sbuf_cpy_test); 284 ATF_TP_ADD_TC(tp, sbuf_putc_test); 285 ATF_TP_ADD_TC(tp, sbuf_trim_test); 286 287 return (atf_no_error()); 288 } 289