1 /* $OpenBSD */ 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 22 #include <fcntl.h> 23 #include <limits.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 static const char * 195 pred_name(enum test_predicate p) 196 { 197 switch (p) { 198 case TEST_EQ: 199 return "EQ"; 200 case TEST_NE: 201 return "NE"; 202 case TEST_LT: 203 return "LT"; 204 case TEST_LE: 205 return "LE"; 206 case TEST_GT: 207 return "GT"; 208 case TEST_GE: 209 return "GE"; 210 default: 211 return "UNKNOWN"; 212 } 213 } 214 215 static void 216 test_die(void) 217 { 218 if (test_onerror != NULL) 219 test_onerror(onerror_ctx); 220 abort(); 221 } 222 223 static void 224 test_header(const char *file, int line, const char *a1, const char *a2, 225 const char *name, enum test_predicate pred) 226 { 227 fprintf(stderr, "\n%s:%d test #%u \"%s\"\n", 228 file, line, test_number, active_test_name); 229 fprintf(stderr, "ASSERT_%s_%s(%s%s%s) failed:\n", 230 name, pred_name(pred), a1, 231 a2 != NULL ? ", " : "", a2 != NULL ? a2 : ""); 232 } 233 234 void 235 assert_string(const char *file, int line, const char *a1, const char *a2, 236 const char *aa1, const char *aa2, enum test_predicate pred) 237 { 238 int r = strcmp(aa1, aa2); 239 240 TEST_CHECK_INT(r, pred); 241 test_header(file, line, a1, a2, "STRING", pred); 242 fprintf(stderr, "%12s = %s (len %zu)\n", a1, aa1, strlen(aa1)); 243 fprintf(stderr, "%12s = %s (len %zu)\n", a2, aa2, strlen(aa2)); 244 test_die(); 245 } 246 247 static char * 248 tohex(const void *_s, size_t l) 249 { 250 uint8_t *s = (uint8_t *)_s; 251 size_t i, j; 252 const char *hex = "0123456789abcdef"; 253 char *r = malloc((l * 2) + 1); 254 255 assert(r != NULL); 256 for (i = j = 0; i < l; i++) { 257 r[j++] = hex[(s[i] >> 4) & 0xf]; 258 r[j++] = hex[s[i] & 0xf]; 259 } 260 r[j] = '\0'; 261 return r; 262 } 263 264 void 265 assert_mem(const char *file, int line, const char *a1, const char *a2, 266 const void *aa1, const void *aa2, size_t l, enum test_predicate pred) 267 { 268 int r = memcmp(aa1, aa2, l); 269 270 TEST_CHECK_INT(r, pred); 271 test_header(file, line, a1, a2, "STRING", pred); 272 fprintf(stderr, "%12s = %s (len %zu)\n", a1, 273 tohex(aa1, MINIMUM(l, 256)), l); 274 fprintf(stderr, "%12s = %s (len %zu)\n", a2, 275 tohex(aa2, MINIMUM(l, 256)), l); 276 test_die(); 277 } 278 279 static int 280 memvalcmp(const uint8_t *s, u_char v, size_t l, size_t *where) 281 { 282 size_t i; 283 284 for (i = 0; i < l; i++) { 285 if (s[i] != v) { 286 *where = i; 287 return 1; 288 } 289 } 290 return 0; 291 } 292 293 void 294 assert_mem_filled(const char *file, int line, const char *a1, 295 const void *aa1, u_char v, size_t l, enum test_predicate pred) 296 { 297 size_t where = -1; 298 int r = memvalcmp(aa1, v, l, &where); 299 char tmp[64]; 300 301 if (l == 0) 302 return; 303 TEST_CHECK_INT(r, pred); 304 test_header(file, line, a1, NULL, "MEM_ZERO", pred); 305 fprintf(stderr, "%20s = %s%s (len %zu)\n", a1, 306 tohex(aa1, MINIMUM(l, 20)), l > 20 ? "..." : "", l); 307 snprintf(tmp, sizeof(tmp), "(%s)[%zu]", a1, where); 308 fprintf(stderr, "%20s = 0x%02x (expected 0x%02x)\n", tmp, 309 ((u_char *)aa1)[where], v); 310 test_die(); 311 } 312 313 void 314 assert_int(const char *file, int line, const char *a1, const char *a2, 315 int aa1, int aa2, enum test_predicate pred) 316 { 317 TEST_CHECK(aa1, aa2, pred); 318 test_header(file, line, a1, a2, "INT", pred); 319 fprintf(stderr, "%12s = %d\n", a1, aa1); 320 fprintf(stderr, "%12s = %d\n", a2, aa2); 321 test_die(); 322 } 323 324 void 325 assert_size_t(const char *file, int line, const char *a1, const char *a2, 326 size_t aa1, size_t aa2, enum test_predicate pred) 327 { 328 TEST_CHECK(aa1, aa2, pred); 329 test_header(file, line, a1, a2, "SIZE_T", pred); 330 fprintf(stderr, "%12s = %zu\n", a1, aa1); 331 fprintf(stderr, "%12s = %zu\n", a2, aa2); 332 test_die(); 333 } 334 335 void 336 assert_u_int(const char *file, int line, const char *a1, const char *a2, 337 u_int aa1, u_int aa2, enum test_predicate pred) 338 { 339 TEST_CHECK(aa1, aa2, pred); 340 test_header(file, line, a1, a2, "U_INT", pred); 341 fprintf(stderr, "%12s = %u / 0x%x\n", a1, aa1, aa1); 342 fprintf(stderr, "%12s = %u / 0x%x\n", a2, aa2, aa2); 343 test_die(); 344 } 345 346 void 347 assert_long_long(const char *file, int line, const char *a1, const char *a2, 348 long long aa1, long long aa2, enum test_predicate pred) 349 { 350 TEST_CHECK(aa1, aa2, pred); 351 test_header(file, line, a1, a2, "LONG LONG", pred); 352 fprintf(stderr, "%12s = %lld / 0x%llx\n", a1, aa1, aa1); 353 fprintf(stderr, "%12s = %lld / 0x%llx\n", a2, aa2, aa2); 354 test_die(); 355 } 356 357 void 358 assert_char(const char *file, int line, const char *a1, const char *a2, 359 char aa1, char aa2, enum test_predicate pred) 360 { 361 char buf[8]; 362 363 TEST_CHECK(aa1, aa2, pred); 364 test_header(file, line, a1, a2, "CHAR", pred); 365 fprintf(stderr, "%12s = '%s' / 0x02%x\n", a1, 366 vis(buf, aa1, VIS_SAFE|VIS_NL|VIS_TAB|VIS_OCTAL, 0), aa1); 367 fprintf(stderr, "%12s = '%s' / 0x02%x\n", a1, 368 vis(buf, aa2, VIS_SAFE|VIS_NL|VIS_TAB|VIS_OCTAL, 0), aa2); 369 test_die(); 370 } 371 372 void 373 assert_u8(const char *file, int line, const char *a1, const char *a2, 374 uint8_t aa1, uint8_t aa2, enum test_predicate pred) 375 { 376 TEST_CHECK(aa1, aa2, pred); 377 test_header(file, line, a1, a2, "U8", pred); 378 fprintf(stderr, "%12s = 0x%02x %u\n", a1, aa1, aa1); 379 fprintf(stderr, "%12s = 0x%02x %u\n", a2, aa2, aa2); 380 test_die(); 381 } 382 383 void 384 assert_u16(const char *file, int line, const char *a1, const char *a2, 385 uint16_t aa1, uint16_t aa2, enum test_predicate pred) 386 { 387 TEST_CHECK(aa1, aa2, pred); 388 test_header(file, line, a1, a2, "U16", pred); 389 fprintf(stderr, "%12s = 0x%04x %u\n", a1, aa1, aa1); 390 fprintf(stderr, "%12s = 0x%04x %u\n", a2, aa2, aa2); 391 test_die(); 392 } 393 394 void 395 assert_u32(const char *file, int line, const char *a1, const char *a2, 396 uint32_t aa1, uint32_t aa2, enum test_predicate pred) 397 { 398 TEST_CHECK(aa1, aa2, pred); 399 test_header(file, line, a1, a2, "U32", pred); 400 fprintf(stderr, "%12s = 0x%08x %u\n", a1, aa1, aa1); 401 fprintf(stderr, "%12s = 0x%08x %u\n", a2, aa2, aa2); 402 test_die(); 403 } 404 405 void 406 assert_u64(const char *file, int line, const char *a1, const char *a2, 407 uint64_t aa1, uint64_t aa2, enum test_predicate pred) 408 { 409 TEST_CHECK(aa1, aa2, pred); 410 test_header(file, line, a1, a2, "U64", pred); 411 fprintf(stderr, "%12s = 0x%016llx %llu\n", a1, 412 (unsigned long long)aa1, (unsigned long long)aa1); 413 fprintf(stderr, "%12s = 0x%016llx %llu\n", a2, 414 (unsigned long long)aa2, (unsigned long long)aa2); 415 test_die(); 416 } 417 418 void 419 assert_ptr(const char *file, int line, const char *a1, const char *a2, 420 const void *aa1, const void *aa2, enum test_predicate pred) 421 { 422 TEST_CHECK(aa1, aa2, pred); 423 test_header(file, line, a1, a2, "PTR", pred); 424 fprintf(stderr, "%12s = %p\n", a1, aa1); 425 fprintf(stderr, "%12s = %p\n", a2, aa2); 426 test_die(); 427 } 428 429