1 /* $OpenBSD: test_helper.c,v 1.2 2014/05/02 09:41:32 andre Exp $ */ 2 /* 3 * Copyright (c) 2011 Damien Miller <djm@mindrot.org> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 /* Utility functions/framework for regress tests */ 19 20 #include <sys/types.h> 21 #include <sys/param.h> 22 23 #include <fcntl.h> 24 #include <stdio.h> 25 #include <stdint.h> 26 #include <stdlib.h> 27 #include <string.h> 28 #include <assert.h> 29 #include <unistd.h> 30 31 #include <openssl/bn.h> 32 33 #include <vis.h> 34 35 #include "test_helper.h" 36 37 #define TEST_CHECK_INT(r, pred) do { \ 38 switch (pred) { \ 39 case TEST_EQ: \ 40 if (r == 0) \ 41 return; \ 42 break; \ 43 case TEST_NE: \ 44 if (r != 0) \ 45 return; \ 46 break; \ 47 case TEST_LT: \ 48 if (r < 0) \ 49 return; \ 50 break; \ 51 case TEST_LE: \ 52 if (r <= 0) \ 53 return; \ 54 break; \ 55 case TEST_GT: \ 56 if (r > 0) \ 57 return; \ 58 break; \ 59 case TEST_GE: \ 60 if (r >= 0) \ 61 return; \ 62 break; \ 63 default: \ 64 abort(); \ 65 } \ 66 } while (0) 67 68 #define TEST_CHECK(x1, x2, pred) do { \ 69 switch (pred) { \ 70 case TEST_EQ: \ 71 if (x1 == x2) \ 72 return; \ 73 break; \ 74 case TEST_NE: \ 75 if (x1 != x2) \ 76 return; \ 77 break; \ 78 case TEST_LT: \ 79 if (x1 < x2) \ 80 return; \ 81 break; \ 82 case TEST_LE: \ 83 if (x1 <= x2) \ 84 return; \ 85 break; \ 86 case TEST_GT: \ 87 if (x1 > x2) \ 88 return; \ 89 break; \ 90 case TEST_GE: \ 91 if (x1 >= x2) \ 92 return; \ 93 break; \ 94 default: \ 95 abort(); \ 96 } \ 97 } while (0) 98 99 extern char *__progname; 100 101 static int verbose_mode = 0; 102 static int quiet_mode = 0; 103 static char *active_test_name = NULL; 104 static u_int test_number = 0; 105 static test_onerror_func_t *test_onerror = NULL; 106 static void *onerror_ctx = NULL; 107 static const char *data_dir = NULL; 108 109 int 110 main(int argc, char **argv) 111 { 112 int ch; 113 114 while ((ch = getopt(argc, argv, "vqd:")) != -1) { 115 switch (ch) { 116 case 'd': 117 data_dir = optarg; 118 break; 119 case 'q': 120 verbose_mode = 0; 121 quiet_mode = 1; 122 break; 123 case 'v': 124 verbose_mode = 1; 125 quiet_mode = 0; 126 break; 127 default: 128 fprintf(stderr, "Unrecognised command line option\n"); 129 fprintf(stderr, "Usage: %s [-v]\n", __progname); 130 exit(1); 131 } 132 } 133 setvbuf(stdout, NULL, _IONBF, 0); 134 if (!quiet_mode) 135 printf("%s: ", __progname); 136 if (verbose_mode) 137 printf("\n"); 138 139 tests(); 140 141 if (!quiet_mode) 142 printf(" %u tests ok\n", test_number); 143 return 0; 144 } 145 146 const char * 147 test_data_file(const char *name) 148 { 149 static char ret[PATH_MAX]; 150 151 if (data_dir != NULL) 152 snprintf(ret, sizeof(ret), "%s/%s", data_dir, name); 153 else 154 strlcpy(ret, name, sizeof(ret)); 155 if (access(ret, F_OK) != 0) { 156 fprintf(stderr, "Cannot access data file %s: %s\n", 157 ret, strerror(errno)); 158 exit(1); 159 } 160 return ret; 161 } 162 163 void 164 test_start(const char *n) 165 { 166 assert(active_test_name == NULL); 167 assert((active_test_name = strdup(n)) != NULL); 168 if (verbose_mode) 169 printf("test %u - \"%s\": ", test_number, active_test_name); 170 test_number++; 171 } 172 173 void 174 set_onerror_func(test_onerror_func_t *f, void *ctx) 175 { 176 test_onerror = f; 177 onerror_ctx = ctx; 178 } 179 180 void 181 test_done(void) 182 { 183 assert(active_test_name != NULL); 184 free(active_test_name); 185 active_test_name = NULL; 186 if (verbose_mode) 187 printf("OK\n"); 188 else if (!quiet_mode) { 189 printf("."); 190 fflush(stdout); 191 } 192 } 193 194 void 195 ssl_err_check(const char *file, int line) 196 { 197 long openssl_error = ERR_get_error(); 198 199 if (openssl_error == 0) 200 return; 201 202 fprintf(stderr, "\n%s:%d: uncaught OpenSSL error: %s", 203 file, line, ERR_error_string(openssl_error, NULL)); 204 abort(); 205 } 206 207 static const char * 208 pred_name(enum test_predicate p) 209 { 210 switch (p) { 211 case TEST_EQ: 212 return "EQ"; 213 case TEST_NE: 214 return "NE"; 215 case TEST_LT: 216 return "LT"; 217 case TEST_LE: 218 return "LE"; 219 case TEST_GT: 220 return "GT"; 221 case TEST_GE: 222 return "GE"; 223 default: 224 return "UNKNOWN"; 225 } 226 } 227 228 static void 229 test_die(void) 230 { 231 if (test_onerror != NULL) 232 test_onerror(onerror_ctx); 233 abort(); 234 } 235 236 static void 237 test_header(const char *file, int line, const char *a1, const char *a2, 238 const char *name, enum test_predicate pred) 239 { 240 fprintf(stderr, "\n%s:%d test #%u \"%s\"\n", 241 file, line, test_number, active_test_name); 242 fprintf(stderr, "ASSERT_%s_%s(%s%s%s) failed:\n", 243 name, pred_name(pred), a1, 244 a2 != NULL ? ", " : "", a2 != NULL ? a2 : ""); 245 } 246 247 void 248 assert_bignum(const char *file, int line, const char *a1, const char *a2, 249 const BIGNUM *aa1, const BIGNUM *aa2, enum test_predicate pred) 250 { 251 int r = BN_cmp(aa1, aa2); 252 253 TEST_CHECK_INT(r, pred); 254 test_header(file, line, a1, a2, "BIGNUM", pred); 255 fprintf(stderr, "%12s = 0x%s\n", a1, BN_bn2hex(aa1)); 256 fprintf(stderr, "%12s = 0x%s\n", a2, BN_bn2hex(aa2)); 257 test_die(); 258 } 259 260 void 261 assert_string(const char *file, int line, const char *a1, const char *a2, 262 const char *aa1, const char *aa2, enum test_predicate pred) 263 { 264 int r = strcmp(aa1, aa2); 265 266 TEST_CHECK_INT(r, pred); 267 test_header(file, line, a1, a2, "STRING", pred); 268 fprintf(stderr, "%12s = %s (len %zu)\n", a1, aa1, strlen(aa1)); 269 fprintf(stderr, "%12s = %s (len %zu)\n", a2, aa2, strlen(aa2)); 270 test_die(); 271 } 272 273 static char * 274 tohex(const void *_s, size_t l) 275 { 276 u_int8_t *s = (u_int8_t *)_s; 277 size_t i, j; 278 const char *hex = "0123456789abcdef"; 279 char *r = malloc((l * 2) + 1); 280 281 assert(r != NULL); 282 for (i = j = 0; i < l; i++) { 283 r[j++] = hex[(s[i] >> 4) & 0xf]; 284 r[j++] = hex[s[i] & 0xf]; 285 } 286 r[j] = '\0'; 287 return r; 288 } 289 290 void 291 assert_mem(const char *file, int line, const char *a1, const char *a2, 292 const void *aa1, const void *aa2, size_t l, enum test_predicate pred) 293 { 294 int r = memcmp(aa1, aa2, l); 295 296 TEST_CHECK_INT(r, pred); 297 test_header(file, line, a1, a2, "STRING", pred); 298 fprintf(stderr, "%12s = %s (len %zu)\n", a1, tohex(aa1, MIN(l, 256)), l); 299 fprintf(stderr, "%12s = %s (len %zu)\n", a2, tohex(aa2, MIN(l, 256)), l); 300 test_die(); 301 } 302 303 static int 304 memvalcmp(const u_int8_t *s, u_char v, size_t l, size_t *where) 305 { 306 size_t i; 307 308 for (i = 0; i < l; i++) { 309 if (s[i] != v) { 310 *where = i; 311 return 1; 312 } 313 } 314 return 0; 315 } 316 317 void 318 assert_mem_filled(const char *file, int line, const char *a1, 319 const void *aa1, u_char v, size_t l, enum test_predicate pred) 320 { 321 size_t where = -1; 322 int r = memvalcmp(aa1, v, l, &where); 323 char tmp[64]; 324 325 if (l == 0) 326 return; 327 TEST_CHECK_INT(r, pred); 328 test_header(file, line, a1, NULL, "MEM_ZERO", pred); 329 fprintf(stderr, "%20s = %s%s (len %zu)\n", a1, 330 tohex(aa1, MIN(l, 20)), l > 20 ? "..." : "", l); 331 snprintf(tmp, sizeof(tmp), "(%s)[%zu]", a1, where); 332 fprintf(stderr, "%20s = 0x%02x (expected 0x%02x)\n", tmp, 333 ((u_char *)aa1)[where], v); 334 test_die(); 335 } 336 337 void 338 assert_int(const char *file, int line, const char *a1, const char *a2, 339 int aa1, int aa2, enum test_predicate pred) 340 { 341 TEST_CHECK(aa1, aa2, pred); 342 test_header(file, line, a1, a2, "INT", pred); 343 fprintf(stderr, "%12s = %d\n", a1, aa1); 344 fprintf(stderr, "%12s = %d\n", a2, aa2); 345 test_die(); 346 } 347 348 void 349 assert_size_t(const char *file, int line, const char *a1, const char *a2, 350 size_t aa1, size_t aa2, enum test_predicate pred) 351 { 352 TEST_CHECK(aa1, aa2, pred); 353 test_header(file, line, a1, a2, "SIZE_T", pred); 354 fprintf(stderr, "%12s = %zu\n", a1, aa1); 355 fprintf(stderr, "%12s = %zu\n", a2, aa2); 356 test_die(); 357 } 358 359 void 360 assert_u_int(const char *file, int line, const char *a1, const char *a2, 361 u_int aa1, u_int aa2, enum test_predicate pred) 362 { 363 TEST_CHECK(aa1, aa2, pred); 364 test_header(file, line, a1, a2, "U_INT", pred); 365 fprintf(stderr, "%12s = %u / 0x%x\n", a1, aa1, aa1); 366 fprintf(stderr, "%12s = %u / 0x%x\n", a2, aa2, aa2); 367 test_die(); 368 } 369 370 void 371 assert_long_long(const char *file, int line, const char *a1, const char *a2, 372 long long aa1, long long aa2, enum test_predicate pred) 373 { 374 TEST_CHECK(aa1, aa2, pred); 375 test_header(file, line, a1, a2, "LONG LONG", pred); 376 fprintf(stderr, "%12s = %lld / 0x%llx\n", a1, aa1, aa1); 377 fprintf(stderr, "%12s = %lld / 0x%llx\n", a2, aa2, aa2); 378 test_die(); 379 } 380 381 void 382 assert_char(const char *file, int line, const char *a1, const char *a2, 383 char aa1, char aa2, enum test_predicate pred) 384 { 385 char buf[8]; 386 387 TEST_CHECK(aa1, aa2, pred); 388 test_header(file, line, a1, a2, "CHAR", pred); 389 fprintf(stderr, "%12s = '%s' / 0x02%x\n", a1, 390 vis(buf, aa1, VIS_SAFE|VIS_NL|VIS_TAB|VIS_OCTAL, 0), aa1); 391 fprintf(stderr, "%12s = '%s' / 0x02%x\n", a1, 392 vis(buf, aa2, VIS_SAFE|VIS_NL|VIS_TAB|VIS_OCTAL, 0), aa2); 393 test_die(); 394 } 395 396 void 397 assert_u8(const char *file, int line, const char *a1, const char *a2, 398 u_int8_t aa1, u_int8_t aa2, enum test_predicate pred) 399 { 400 TEST_CHECK(aa1, aa2, pred); 401 test_header(file, line, a1, a2, "U8", pred); 402 fprintf(stderr, "%12s = 0x%02x %u\n", a1, aa1, aa1); 403 fprintf(stderr, "%12s = 0x%02x %u\n", a2, aa2, aa2); 404 test_die(); 405 } 406 407 void 408 assert_u16(const char *file, int line, const char *a1, const char *a2, 409 u_int16_t aa1, u_int16_t aa2, enum test_predicate pred) 410 { 411 TEST_CHECK(aa1, aa2, pred); 412 test_header(file, line, a1, a2, "U16", pred); 413 fprintf(stderr, "%12s = 0x%04x %u\n", a1, aa1, aa1); 414 fprintf(stderr, "%12s = 0x%04x %u\n", a2, aa2, aa2); 415 test_die(); 416 } 417 418 void 419 assert_u32(const char *file, int line, const char *a1, const char *a2, 420 u_int32_t aa1, u_int32_t aa2, enum test_predicate pred) 421 { 422 TEST_CHECK(aa1, aa2, pred); 423 test_header(file, line, a1, a2, "U32", pred); 424 fprintf(stderr, "%12s = 0x%08x %u\n", a1, aa1, aa1); 425 fprintf(stderr, "%12s = 0x%08x %u\n", a2, aa2, aa2); 426 test_die(); 427 } 428 429 void 430 assert_u64(const char *file, int line, const char *a1, const char *a2, 431 u_int64_t aa1, u_int64_t aa2, enum test_predicate pred) 432 { 433 TEST_CHECK(aa1, aa2, pred); 434 test_header(file, line, a1, a2, "U64", pred); 435 fprintf(stderr, "%12s = 0x%016llx %llu\n", a1, 436 (unsigned long long)aa1, (unsigned long long)aa1); 437 fprintf(stderr, "%12s = 0x%016llx %llu\n", a2, 438 (unsigned long long)aa2, (unsigned long long)aa2); 439 test_die(); 440 } 441 442 void 443 assert_ptr(const char *file, int line, const char *a1, const char *a2, 444 const void *aa1, const void *aa2, enum test_predicate pred) 445 { 446 TEST_CHECK(aa1, aa2, pred); 447 test_header(file, line, a1, a2, "PTR", pred); 448 fprintf(stderr, "%12s = %p\n", a1, aa1); 449 fprintf(stderr, "%12s = %p\n", a2, aa2); 450 test_die(); 451 } 452 453