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