1 /* $OpenBSD: test_helper.c,v 1.12 2019/08/02 01:41:24 djm 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 #include <sys/uio.h> 23 24 #include <fcntl.h> 25 #include <stdio.h> 26 #include <stdint.h> 27 #include <stdlib.h> 28 #include <string.h> 29 #include <assert.h> 30 #include <unistd.h> 31 #include <signal.h> 32 33 #include <openssl/bn.h> 34 35 #include <vis.h> 36 37 #include "test_helper.h" 38 #include "atomicio.h" 39 40 #define TEST_CHECK_INT(r, pred) do { \ 41 switch (pred) { \ 42 case TEST_EQ: \ 43 if (r == 0) \ 44 return; \ 45 break; \ 46 case TEST_NE: \ 47 if (r != 0) \ 48 return; \ 49 break; \ 50 case TEST_LT: \ 51 if (r < 0) \ 52 return; \ 53 break; \ 54 case TEST_LE: \ 55 if (r <= 0) \ 56 return; \ 57 break; \ 58 case TEST_GT: \ 59 if (r > 0) \ 60 return; \ 61 break; \ 62 case TEST_GE: \ 63 if (r >= 0) \ 64 return; \ 65 break; \ 66 default: \ 67 abort(); \ 68 } \ 69 } while (0) 70 71 #define TEST_CHECK(x1, x2, pred) do { \ 72 switch (pred) { \ 73 case TEST_EQ: \ 74 if (x1 == x2) \ 75 return; \ 76 break; \ 77 case TEST_NE: \ 78 if (x1 != x2) \ 79 return; \ 80 break; \ 81 case TEST_LT: \ 82 if (x1 < x2) \ 83 return; \ 84 break; \ 85 case TEST_LE: \ 86 if (x1 <= x2) \ 87 return; \ 88 break; \ 89 case TEST_GT: \ 90 if (x1 > x2) \ 91 return; \ 92 break; \ 93 case TEST_GE: \ 94 if (x1 >= x2) \ 95 return; \ 96 break; \ 97 default: \ 98 abort(); \ 99 } \ 100 } while (0) 101 102 extern char *__progname; 103 104 static int verbose_mode = 0; 105 static int quiet_mode = 0; 106 static char *active_test_name = NULL; 107 static u_int test_number = 0; 108 static test_onerror_func_t *test_onerror = NULL; 109 static void *onerror_ctx = NULL; 110 static const char *data_dir = NULL; 111 static char subtest_info[512]; 112 static int fast = 0; 113 static int slow = 0; 114 115 int 116 main(int argc, char **argv) 117 { 118 int ch; 119 120 while ((ch = getopt(argc, argv, "Ffvqd:")) != -1) { 121 switch (ch) { 122 case 'F': 123 slow = 1; 124 break; 125 case 'f': 126 fast = 1; 127 break; 128 case 'd': 129 data_dir = optarg; 130 break; 131 case 'q': 132 verbose_mode = 0; 133 quiet_mode = 1; 134 break; 135 case 'v': 136 verbose_mode = 1; 137 quiet_mode = 0; 138 break; 139 default: 140 fprintf(stderr, "Unrecognised command line option\n"); 141 fprintf(stderr, "Usage: %s [-v]\n", __progname); 142 exit(1); 143 } 144 } 145 setvbuf(stdout, NULL, _IONBF, 0); 146 if (!quiet_mode) 147 printf("%s: ", __progname); 148 if (verbose_mode) 149 printf("\n"); 150 151 tests(); 152 153 if (!quiet_mode) 154 printf(" %u tests ok\n", test_number); 155 return 0; 156 } 157 158 int 159 test_is_verbose(void) 160 { 161 return verbose_mode; 162 } 163 164 int 165 test_is_quiet(void) 166 { 167 return quiet_mode; 168 } 169 170 int 171 test_is_fast(void) 172 { 173 return fast; 174 } 175 176 int 177 test_is_slow(void) 178 { 179 return slow; 180 } 181 182 const char * 183 test_data_file(const char *name) 184 { 185 static char ret[PATH_MAX]; 186 187 if (data_dir != NULL) 188 snprintf(ret, sizeof(ret), "%s/%s", data_dir, name); 189 else 190 strlcpy(ret, name, sizeof(ret)); 191 if (access(ret, F_OK) != 0) { 192 fprintf(stderr, "Cannot access data file %s: %s\n", 193 ret, strerror(errno)); 194 exit(1); 195 } 196 return ret; 197 } 198 199 void 200 test_info(char *s, size_t len) 201 { 202 snprintf(s, len, "In test %u: \"%s\"%s%s\n", test_number, 203 active_test_name == NULL ? "<none>" : active_test_name, 204 *subtest_info != '\0' ? " - " : "", subtest_info); 205 } 206 207 static void 208 siginfo(int unused __attribute__((__unused__))) 209 { 210 char buf[256]; 211 212 test_info(buf, sizeof(buf)); 213 atomicio(vwrite, STDERR_FILENO, buf, strlen(buf)); 214 } 215 216 void 217 test_start(const char *n) 218 { 219 assert(active_test_name == NULL); 220 assert((active_test_name = strdup(n)) != NULL); 221 *subtest_info = '\0'; 222 if (verbose_mode) 223 printf("test %u - \"%s\": ", test_number, active_test_name); 224 test_number++; 225 #ifdef SIGINFO 226 signal(SIGINFO, siginfo); 227 #endif 228 signal(SIGUSR1, siginfo); 229 } 230 231 void 232 set_onerror_func(test_onerror_func_t *f, void *ctx) 233 { 234 test_onerror = f; 235 onerror_ctx = ctx; 236 } 237 238 void 239 test_done(void) 240 { 241 *subtest_info = '\0'; 242 assert(active_test_name != NULL); 243 free(active_test_name); 244 active_test_name = NULL; 245 if (verbose_mode) 246 printf("OK\n"); 247 else if (!quiet_mode) { 248 printf("."); 249 fflush(stdout); 250 } 251 } 252 253 void 254 test_subtest_info(const char *fmt, ...) 255 { 256 va_list ap; 257 258 va_start(ap, fmt); 259 vsnprintf(subtest_info, sizeof(subtest_info), fmt, ap); 260 va_end(ap); 261 } 262 263 void 264 ssl_err_check(const char *file, int line) 265 { 266 long openssl_error = ERR_get_error(); 267 268 if (openssl_error == 0) 269 return; 270 271 fprintf(stderr, "\n%s:%d: uncaught OpenSSL error: %s", 272 file, line, ERR_error_string(openssl_error, NULL)); 273 abort(); 274 } 275 276 static const char * 277 pred_name(enum test_predicate p) 278 { 279 switch (p) { 280 case TEST_EQ: 281 return "EQ"; 282 case TEST_NE: 283 return "NE"; 284 case TEST_LT: 285 return "LT"; 286 case TEST_LE: 287 return "LE"; 288 case TEST_GT: 289 return "GT"; 290 case TEST_GE: 291 return "GE"; 292 default: 293 return "UNKNOWN"; 294 } 295 } 296 297 static void 298 test_die(void) 299 { 300 if (test_onerror != NULL) 301 test_onerror(onerror_ctx); 302 abort(); 303 } 304 305 static void 306 test_header(const char *file, int line, const char *a1, const char *a2, 307 const char *name, enum test_predicate pred) 308 { 309 fprintf(stderr, "\n%s:%d test #%u \"%s\"%s%s\n", 310 file, line, test_number, active_test_name, 311 *subtest_info != '\0' ? " - " : "", subtest_info); 312 fprintf(stderr, "ASSERT_%s_%s(%s%s%s) failed:\n", 313 name, pred_name(pred), a1, 314 a2 != NULL ? ", " : "", a2 != NULL ? a2 : ""); 315 } 316 317 void 318 assert_bignum(const char *file, int line, const char *a1, const char *a2, 319 const BIGNUM *aa1, const BIGNUM *aa2, enum test_predicate pred) 320 { 321 int r = BN_cmp(aa1, aa2); 322 323 TEST_CHECK_INT(r, pred); 324 test_header(file, line, a1, a2, "BIGNUM", pred); 325 fprintf(stderr, "%12s = 0x%s\n", a1, BN_bn2hex(aa1)); 326 fprintf(stderr, "%12s = 0x%s\n", a2, BN_bn2hex(aa2)); 327 test_die(); 328 } 329 330 void 331 assert_string(const char *file, int line, const char *a1, const char *a2, 332 const char *aa1, const char *aa2, enum test_predicate pred) 333 { 334 int r; 335 336 /* Verify pointers are not NULL */ 337 assert_ptr(file, line, a1, "NULL", aa1, NULL, TEST_NE); 338 assert_ptr(file, line, a2, "NULL", aa2, NULL, TEST_NE); 339 340 r = strcmp(aa1, aa2); 341 TEST_CHECK_INT(r, pred); 342 test_header(file, line, a1, a2, "STRING", pred); 343 fprintf(stderr, "%12s = %s (len %zu)\n", a1, aa1, strlen(aa1)); 344 fprintf(stderr, "%12s = %s (len %zu)\n", a2, aa2, strlen(aa2)); 345 test_die(); 346 } 347 348 static char * 349 tohex(const void *_s, size_t l) 350 { 351 u_int8_t *s = (u_int8_t *)_s; 352 size_t i, j; 353 const char *hex = "0123456789abcdef"; 354 char *r = malloc((l * 2) + 1); 355 356 assert(r != NULL); 357 for (i = j = 0; i < l; i++) { 358 r[j++] = hex[(s[i] >> 4) & 0xf]; 359 r[j++] = hex[s[i] & 0xf]; 360 } 361 r[j] = '\0'; 362 return r; 363 } 364 365 void 366 assert_mem(const char *file, int line, const char *a1, const char *a2, 367 const void *aa1, const void *aa2, size_t l, enum test_predicate pred) 368 { 369 int r; 370 char *aa1_tohex = NULL; 371 char *aa2_tohex = NULL; 372 373 if (l == 0) 374 return; 375 /* If length is >0, then verify pointers are not NULL */ 376 assert_ptr(file, line, a1, "NULL", aa1, NULL, TEST_NE); 377 assert_ptr(file, line, a2, "NULL", aa2, NULL, TEST_NE); 378 379 r = memcmp(aa1, aa2, l); 380 TEST_CHECK_INT(r, pred); 381 test_header(file, line, a1, a2, "STRING", pred); 382 aa1_tohex = tohex(aa1, MIN(l, 256)); 383 aa2_tohex = tohex(aa2, MIN(l, 256)); 384 fprintf(stderr, "%12s = %s (len %zu)\n", a1, aa1_tohex, l); 385 fprintf(stderr, "%12s = %s (len %zu)\n", a2, aa2_tohex, l); 386 free(aa1_tohex); 387 free(aa2_tohex); 388 test_die(); 389 } 390 391 static int 392 memvalcmp(const u_int8_t *s, u_char v, size_t l, size_t *where) 393 { 394 size_t i; 395 396 for (i = 0; i < l; i++) { 397 if (s[i] != v) { 398 *where = i; 399 return 1; 400 } 401 } 402 return 0; 403 } 404 405 void 406 assert_mem_filled(const char *file, int line, const char *a1, 407 const void *aa1, u_char v, size_t l, enum test_predicate pred) 408 { 409 size_t where = -1; 410 int r; 411 char tmp[64]; 412 char *aa1_tohex = NULL; 413 414 if (l == 0) 415 return; 416 /* If length is >0, then verify the pointer is not NULL */ 417 assert_ptr(file, line, a1, "NULL", aa1, NULL, TEST_NE); 418 419 r = memvalcmp(aa1, v, l, &where); 420 TEST_CHECK_INT(r, pred); 421 test_header(file, line, a1, NULL, "MEM_ZERO", pred); 422 aa1_tohex = tohex(aa1, MIN(l, 20)); 423 fprintf(stderr, "%20s = %s%s (len %zu)\n", a1, 424 aa1_tohex, l > 20 ? "..." : "", l); 425 free(aa1_tohex); 426 snprintf(tmp, sizeof(tmp), "(%s)[%zu]", a1, where); 427 fprintf(stderr, "%20s = 0x%02x (expected 0x%02x)\n", tmp, 428 ((u_char *)aa1)[where], v); 429 test_die(); 430 } 431 432 void 433 assert_int(const char *file, int line, const char *a1, const char *a2, 434 int aa1, int aa2, enum test_predicate pred) 435 { 436 TEST_CHECK(aa1, aa2, pred); 437 test_header(file, line, a1, a2, "INT", pred); 438 fprintf(stderr, "%12s = %d\n", a1, aa1); 439 fprintf(stderr, "%12s = %d\n", a2, aa2); 440 test_die(); 441 } 442 443 void 444 assert_size_t(const char *file, int line, const char *a1, const char *a2, 445 size_t aa1, size_t aa2, enum test_predicate pred) 446 { 447 TEST_CHECK(aa1, aa2, pred); 448 test_header(file, line, a1, a2, "SIZE_T", pred); 449 fprintf(stderr, "%12s = %zu\n", a1, aa1); 450 fprintf(stderr, "%12s = %zu\n", a2, aa2); 451 test_die(); 452 } 453 454 void 455 assert_u_int(const char *file, int line, const char *a1, const char *a2, 456 u_int aa1, u_int aa2, enum test_predicate pred) 457 { 458 TEST_CHECK(aa1, aa2, pred); 459 test_header(file, line, a1, a2, "U_INT", pred); 460 fprintf(stderr, "%12s = %u / 0x%x\n", a1, aa1, aa1); 461 fprintf(stderr, "%12s = %u / 0x%x\n", a2, aa2, aa2); 462 test_die(); 463 } 464 465 void 466 assert_long(const char *file, int line, const char *a1, const char *a2, 467 long aa1, long aa2, enum test_predicate pred) 468 { 469 TEST_CHECK(aa1, aa2, pred); 470 test_header(file, line, a1, a2, "LONG", pred); 471 fprintf(stderr, "%12s = %ld / 0x%lx\n", a1, aa1, aa1); 472 fprintf(stderr, "%12s = %ld / 0x%lx\n", a2, aa2, aa2); 473 test_die(); 474 } 475 476 void 477 assert_long_long(const char *file, int line, const char *a1, const char *a2, 478 long long aa1, long long aa2, enum test_predicate pred) 479 { 480 TEST_CHECK(aa1, aa2, pred); 481 test_header(file, line, a1, a2, "LONG LONG", pred); 482 fprintf(stderr, "%12s = %lld / 0x%llx\n", a1, aa1, aa1); 483 fprintf(stderr, "%12s = %lld / 0x%llx\n", a2, aa2, aa2); 484 test_die(); 485 } 486 487 void 488 assert_char(const char *file, int line, const char *a1, const char *a2, 489 char aa1, char aa2, enum test_predicate pred) 490 { 491 char buf[8]; 492 493 TEST_CHECK(aa1, aa2, pred); 494 test_header(file, line, a1, a2, "CHAR", pred); 495 fprintf(stderr, "%12s = '%s' / 0x02%x\n", a1, 496 vis(buf, aa1, VIS_SAFE|VIS_NL|VIS_TAB|VIS_OCTAL, 0), aa1); 497 fprintf(stderr, "%12s = '%s' / 0x02%x\n", a1, 498 vis(buf, aa2, VIS_SAFE|VIS_NL|VIS_TAB|VIS_OCTAL, 0), aa2); 499 test_die(); 500 } 501 502 void 503 assert_u8(const char *file, int line, const char *a1, const char *a2, 504 u_int8_t aa1, u_int8_t aa2, enum test_predicate pred) 505 { 506 TEST_CHECK(aa1, aa2, pred); 507 test_header(file, line, a1, a2, "U8", pred); 508 fprintf(stderr, "%12s = 0x%02x %u\n", a1, aa1, aa1); 509 fprintf(stderr, "%12s = 0x%02x %u\n", a2, aa2, aa2); 510 test_die(); 511 } 512 513 void 514 assert_u16(const char *file, int line, const char *a1, const char *a2, 515 u_int16_t aa1, u_int16_t aa2, enum test_predicate pred) 516 { 517 TEST_CHECK(aa1, aa2, pred); 518 test_header(file, line, a1, a2, "U16", pred); 519 fprintf(stderr, "%12s = 0x%04x %u\n", a1, aa1, aa1); 520 fprintf(stderr, "%12s = 0x%04x %u\n", a2, aa2, aa2); 521 test_die(); 522 } 523 524 void 525 assert_u32(const char *file, int line, const char *a1, const char *a2, 526 u_int32_t aa1, u_int32_t aa2, enum test_predicate pred) 527 { 528 TEST_CHECK(aa1, aa2, pred); 529 test_header(file, line, a1, a2, "U32", pred); 530 fprintf(stderr, "%12s = 0x%08x %u\n", a1, aa1, aa1); 531 fprintf(stderr, "%12s = 0x%08x %u\n", a2, aa2, aa2); 532 test_die(); 533 } 534 535 void 536 assert_u64(const char *file, int line, const char *a1, const char *a2, 537 u_int64_t aa1, u_int64_t aa2, enum test_predicate pred) 538 { 539 TEST_CHECK(aa1, aa2, pred); 540 test_header(file, line, a1, a2, "U64", pred); 541 fprintf(stderr, "%12s = 0x%016llx %llu\n", a1, 542 (unsigned long long)aa1, (unsigned long long)aa1); 543 fprintf(stderr, "%12s = 0x%016llx %llu\n", a2, 544 (unsigned long long)aa2, (unsigned long long)aa2); 545 test_die(); 546 } 547 548 void 549 assert_ptr(const char *file, int line, const char *a1, const char *a2, 550 const void *aa1, const void *aa2, enum test_predicate pred) 551 { 552 TEST_CHECK(aa1, aa2, pred); 553 test_header(file, line, a1, a2, "PTR", pred); 554 fprintf(stderr, "%12s = %p\n", a1, aa1); 555 fprintf(stderr, "%12s = %p\n", a2, aa2); 556 test_die(); 557 } 558 559