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