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