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 #include <sys/param.h> 28 #include <sys/sbuf.h> 29 #include <errno.h> 30 #include <libutil.h> 31 #include <stdio.h> 32 #include <stdlib.h> 33 #include <string.h> 34 35 #include <atf-c.h> 36 37 #include "sbuf_test_common.h" 38 39 static char test_string[] = "this is a test string"; 40 static char test_whitespace_string[] = " \f\n\r\t\v "; 41 static int test_buffer[] = { 0, 1, 2, 3, 4, 5, }; 42 43 static void 44 check_buffers_equal(const void *sb_buf, const void *test_buf, size_t len) 45 { 46 47 if (memcmp(sb_buf, test_buf, len) != 0) { 48 printf("sbuf:\n"); 49 hexdump(sb_buf, len, NULL, 0), 50 printf("test_buf:\n"); 51 hexdump(test_buf, len, NULL, 0); 52 atf_tc_fail("contents of sbuf didn't match test_buf contents"); 53 } 54 } 55 56 ATF_TC_WITHOUT_HEAD(sbuf_bcat_test); 57 ATF_TC_BODY(sbuf_bcat_test, tc) 58 { 59 struct sbuf *sb; 60 int *test_buffer_tmp; 61 ssize_t test_sbuf_len; 62 63 test_buffer_tmp = malloc(sizeof(test_buffer) * 2); 64 ATF_REQUIRE_MSG(test_buffer_tmp != NULL, "malloc failed"); 65 66 memcpy(test_buffer_tmp, test_buffer, sizeof(test_buffer)); 67 memcpy(&test_buffer_tmp[nitems(test_buffer)], test_buffer, 68 sizeof(test_buffer)); 69 70 sb = sbuf_new_auto(); 71 ATF_REQUIRE_MSG(sb != NULL, "sbuf_new_auto failed: %s", 72 strerror(errno)); 73 74 ATF_CHECK_MSG(sbuf_bcat(sb, test_buffer, sizeof(test_buffer)) == 0, 75 "sbuf_bcat failed"); 76 77 test_sbuf_len = sbuf_len(sb); 78 ATF_REQUIRE_MSG(test_sbuf_len == (ssize_t)sizeof(test_buffer), 79 "sbuf_len(..) => %zd (actual) != %zu (expected)", 80 test_sbuf_len, sizeof(test_buffer)); 81 82 ATF_CHECK_MSG(sbuf_bcat(sb, test_buffer, sizeof(test_buffer)) == 0, 83 "sbuf_bcat failed"); 84 85 test_sbuf_len = sbuf_len(sb); 86 ATF_REQUIRE_MSG(test_sbuf_len == (ssize_t)(2 * sizeof(test_buffer)), 87 "sbuf_len(..) => %zd (actual) != %zu (expected)", 88 test_sbuf_len, 2 * sizeof(test_buffer)); 89 90 ATF_REQUIRE_MSG(sbuf_finish(sb) == 0, "sbuf_finish failed: %s", 91 strerror(errno)); 92 93 check_buffers_equal(sbuf_data(sb), test_buffer_tmp, 94 (size_t)test_sbuf_len); 95 96 sbuf_delete(sb); 97 98 free(test_buffer_tmp); 99 } 100 101 ATF_TC_WITHOUT_HEAD(sbuf_bcpy_test); 102 ATF_TC_BODY(sbuf_bcpy_test, tc) 103 { 104 struct sbuf *sb; 105 ssize_t test_sbuf_len; 106 107 sb = sbuf_new_auto(); 108 ATF_REQUIRE_MSG(sb != NULL, "sbuf_new_auto failed: %s", 109 strerror(errno)); 110 111 ATF_CHECK_MSG(sbuf_bcpy(sb, test_buffer, sizeof(test_buffer)) == 0, 112 "sbuf_bcpy failed"); 113 114 test_sbuf_len = sbuf_len(sb); 115 ATF_REQUIRE_MSG(test_sbuf_len == (ssize_t)sizeof(test_buffer), 116 "sbuf_len(..) => %zd (actual) != %zu (expected)", 117 test_sbuf_len, sizeof(test_buffer)); 118 119 ATF_CHECK_MSG(sbuf_bcpy(sb, test_buffer, sizeof(test_buffer)) == 0, 120 "sbuf_bcpy failed"); 121 122 test_sbuf_len = sbuf_len(sb); 123 ATF_REQUIRE_MSG(test_sbuf_len == (ssize_t)sizeof(test_buffer), 124 "sbuf_len(..) => %zd (actual) != %zu (expected)", 125 test_sbuf_len, sizeof(test_buffer)); 126 127 ATF_REQUIRE_MSG(sbuf_finish(sb) == 0, "sbuf_finish failed: %s", 128 strerror(errno)); 129 130 check_buffers_equal(sbuf_data(sb), test_buffer, (size_t)test_sbuf_len); 131 132 sbuf_delete(sb); 133 } 134 135 ATF_TC_WITHOUT_HEAD(sbuf_cat_test); 136 ATF_TC_BODY(sbuf_cat_test, tc) 137 { 138 struct sbuf *sb; 139 char *test_string_tmp; 140 ssize_t test_sbuf_len; 141 142 asprintf(&test_string_tmp, "%s%s", test_string, test_string); 143 ATF_REQUIRE_MSG(test_string_tmp != NULL, "asprintf failed"); 144 145 sb = sbuf_new_auto(); 146 ATF_REQUIRE_MSG(sb != NULL, "sbuf_new_auto failed: %s", 147 strerror(errno)); 148 149 ATF_CHECK_MSG(sbuf_cat(sb, test_string) == 0, "sbuf_cat failed"); 150 151 test_sbuf_len = sbuf_len(sb); 152 ATF_REQUIRE_MSG(test_sbuf_len == (ssize_t)strlen(test_string), 153 "sbuf_len(..) => %zd (actual) != %zu (expected)", 154 test_sbuf_len, sizeof(test_string)); 155 156 ATF_CHECK_MSG(sbuf_cat(sb, test_string) == 0, "sbuf_cat failed"); 157 158 test_sbuf_len = sbuf_len(sb); 159 ATF_REQUIRE_MSG(test_sbuf_len == (ssize_t)strlen(test_string_tmp), 160 "sbuf_len(..) => %zd (actual) != %zu (expected)", 161 test_sbuf_len, strlen(test_string_tmp)); 162 163 ATF_REQUIRE_MSG(sbuf_finish(sb) == 0, "sbuf_finish failed: %s", 164 strerror(errno)); 165 166 ATF_REQUIRE_STREQ_MSG(sbuf_data(sb), test_string_tmp, 167 "sbuf (\"%s\") != test string (\"%s\")", sbuf_data(sb), 168 test_string_tmp); 169 170 sbuf_delete(sb); 171 172 free(test_string_tmp); 173 } 174 175 ATF_TC_WITHOUT_HEAD(sbuf_cpy_test); 176 ATF_TC_BODY(sbuf_cpy_test, tc) 177 { 178 struct sbuf *sb; 179 ssize_t test_sbuf_len; 180 181 sb = sbuf_new_auto(); 182 ATF_REQUIRE_MSG(sb != NULL, "sbuf_new_auto failed: %s", 183 strerror(errno)); 184 185 ATF_CHECK_MSG(sbuf_cpy(sb, test_string) == 0, "sbuf_cpy failed"); 186 187 test_sbuf_len = sbuf_len(sb); 188 ATF_REQUIRE_MSG(test_sbuf_len == (ssize_t)strlen(test_string), 189 "sbuf_len(..) => %zd (actual) != %zu (expected)", 190 test_sbuf_len, strlen(test_string)); 191 192 ATF_CHECK_MSG(sbuf_cpy(sb, test_string) == 0, "sbuf_cpy failed"); 193 194 test_sbuf_len = sbuf_len(sb); 195 ATF_REQUIRE_MSG(test_sbuf_len == (ssize_t)strlen(test_string), 196 "sbuf_len(..) => %zd (actual) != %zu (expected)", 197 test_sbuf_len, strlen(test_string)); 198 199 ATF_REQUIRE_MSG(sbuf_finish(sb) == 0, "sbuf_finish failed: %s", 200 strerror(errno)); 201 202 ATF_REQUIRE_STREQ_MSG(sbuf_data(sb), test_string, 203 "sbuf (\"%s\") != test string (\"%s\")", sbuf_data(sb), 204 test_string); 205 206 sbuf_delete(sb); 207 } 208 209 ATF_TC_WITHOUT_HEAD(sbuf_putc_test); 210 ATF_TC_BODY(sbuf_putc_test, tc) 211 { 212 struct sbuf *sb; 213 ssize_t test_sbuf_len; 214 size_t i; 215 216 sb = sbuf_new_auto(); 217 ATF_REQUIRE_MSG(sb != NULL, "sbuf_new_auto failed: %s", 218 strerror(errno)); 219 220 for (i = 0; i <= strlen(test_string); i++) { /* Include the NUL */ 221 ATF_REQUIRE_MSG(sbuf_putc(sb, test_string[i]) == 0, 222 "sbuf_putc failed"); 223 224 /* The best we can do until sbuf_finish(3) is called. */ 225 test_sbuf_len = sbuf_len(sb); 226 ATF_REQUIRE_MSG((ssize_t)(i + 1) == test_sbuf_len, 227 "sbuf_len(..) => %zd (actual) != %zu (expected)", 228 test_sbuf_len, i + 1); 229 } 230 231 ATF_REQUIRE_MSG(sbuf_finish(sb) == 0, "sbuf_finish failed: %s", 232 strerror(errno)); 233 234 ATF_REQUIRE_STREQ_MSG(sbuf_data(sb), test_string, 235 "sbuf (\"%s\") != test string (\"%s\")", sbuf_data(sb), 236 test_string); 237 238 sbuf_delete(sb); 239 } 240 241 ATF_TC_WITHOUT_HEAD(sbuf_trim_test); 242 ATF_TC_BODY(sbuf_trim_test, tc) 243 { 244 struct sbuf *sb; 245 ssize_t exp_sbuf_len, test_sbuf_len; 246 247 sb = sbuf_new_auto(); 248 ATF_REQUIRE_MSG(sb != NULL, "sbuf_new_auto failed: %s", 249 strerror(errno)); 250 251 ATF_CHECK_MSG(sbuf_cpy(sb, test_string) == 0, "sbuf_cpy failed"); 252 ATF_CHECK_MSG(sbuf_cat(sb, test_whitespace_string) == 0, 253 "sbuf_cat failed"); 254 255 /* The best we can do until sbuf_finish(3) is called. */ 256 exp_sbuf_len = (ssize_t)(strlen(test_string) + 257 strlen(test_whitespace_string)); 258 test_sbuf_len = sbuf_len(sb); 259 ATF_REQUIRE_MSG(exp_sbuf_len == test_sbuf_len, 260 "sbuf_len(..) => %zd (actual) != %zu (expected)", 261 test_sbuf_len, exp_sbuf_len); 262 263 ATF_REQUIRE_MSG(sbuf_trim(sb) == 0, "sbuf_trim failed"); 264 265 ATF_REQUIRE_MSG(sbuf_finish(sb) == 0, "sbuf_finish failed: %s", 266 strerror(errno)); 267 268 ATF_REQUIRE_STREQ_MSG(sbuf_data(sb), test_string, 269 "sbuf (\"%s\") != test string (\"%s\") (trimmed)", sbuf_data(sb), 270 test_string); 271 272 sbuf_delete(sb); 273 } 274 275 ATF_TP_ADD_TCS(tp) 276 { 277 278 ATF_TP_ADD_TC(tp, sbuf_bcat_test); 279 ATF_TP_ADD_TC(tp, sbuf_bcpy_test); 280 ATF_TP_ADD_TC(tp, sbuf_cat_test); 281 ATF_TP_ADD_TC(tp, sbuf_cpy_test); 282 ATF_TP_ADD_TC(tp, sbuf_putc_test); 283 ATF_TP_ADD_TC(tp, sbuf_trim_test); 284 285 return (atf_no_error()); 286 } 287