1/* 2 * utils module tests 3 * Copyright (c) 2014-2015, Jouni Malinen <j@w1.fi> 4 * 5 * This software may be distributed under the terms of the BSD license. 6 * See README for more details. 7 */ 8 9#include "utils/includes.h" 10 11#include "utils/common.h" 12#include "common/ieee802_11_defs.h" 13#include "utils/bitfield.h" 14#include "utils/ext_password.h" 15#include "utils/trace.h" 16#include "utils/base64.h" 17#include "utils/ip_addr.h" 18#include "utils/eloop.h" 19#include "utils/json.h" 20#include "utils/module_tests.h" 21 22 23struct printf_test_data { 24 u8 *data; 25 size_t len; 26 char *encoded; 27}; 28 29static const struct printf_test_data printf_tests[] = { 30 { (u8 *) "abcde", 5, "abcde" }, 31 { (u8 *) "a\0b\nc\ed\re\tf\"\\", 13, "a\\0b\\nc\\ed\\re\\tf\\\"\\\\" }, 32 { (u8 *) "\x00\x31\x00\x32\x00\x39", 6, "\\x001\\0002\\09" }, 33 { (u8 *) "\n\n\n", 3, "\n\12\x0a" }, 34 { (u8 *) "\303\245\303\244\303\266\303\205\303\204\303\226", 12, 35 "\\xc3\\xa5\xc3\\xa4\\xc3\\xb6\\xc3\\x85\\xc3\\x84\\xc3\\x96" }, 36 { (u8 *) "\303\245\303\244\303\266\303\205\303\204\303\226", 12, 37 "\\303\\245\\303\\244\\303\\266\\303\\205\\303\\204\\303\\226" }, 38 { (u8 *) "\xe5\xe4\xf6\xc5\xc4\xd6", 6, 39 "\\xe5\\xe4\\xf6\\xc5\\xc4\\xd6" }, 40 { NULL, 0, NULL } 41}; 42 43 44static int printf_encode_decode_tests(void) 45{ 46 int i; 47 size_t binlen; 48 char buf[100]; 49 u8 bin[100]; 50 int errors = 0; 51 int array[10]; 52 53 wpa_printf(MSG_INFO, "printf encode/decode tests"); 54 55 for (i = 0; printf_tests[i].data; i++) { 56 const struct printf_test_data *test = &printf_tests[i]; 57 printf_encode(buf, sizeof(buf), test->data, test->len); 58 wpa_printf(MSG_INFO, "%d: -> \"%s\"", i, buf); 59 60 binlen = printf_decode(bin, sizeof(bin), buf); 61 if (binlen != test->len || 62 os_memcmp(bin, test->data, binlen) != 0) { 63 wpa_hexdump(MSG_ERROR, "Error in decoding#1", 64 bin, binlen); 65 errors++; 66 } 67 68 binlen = printf_decode(bin, sizeof(bin), test->encoded); 69 if (binlen != test->len || 70 os_memcmp(bin, test->data, binlen) != 0) { 71 wpa_hexdump(MSG_ERROR, "Error in decoding#2", 72 bin, binlen); 73 errors++; 74 } 75 } 76 77 buf[5] = 'A'; 78 printf_encode(buf, 5, (const u8 *) "abcde", 5); 79 if (buf[5] != 'A') { 80 wpa_printf(MSG_ERROR, "Error in bounds checking#1"); 81 errors++; 82 } 83 84 for (i = 5; i < 10; i++) { 85 buf[i] = 'A'; 86 printf_encode(buf, i, (const u8 *) "\xdd\xdd\xdd\xdd\xdd", 5); 87 if (buf[i] != 'A') { 88 wpa_printf(MSG_ERROR, "Error in bounds checking#2(%d)", 89 i); 90 errors++; 91 } 92 } 93 94 if (printf_decode(bin, 3, "abcde") != 2) 95 errors++; 96 97 if (printf_decode(bin, 3, "\\xa") != 1 || bin[0] != 10) 98 errors++; 99 100 if (printf_decode(bin, 3, "\\xq") != 1 || bin[0] != 'q') 101 errors++; 102 103 if (printf_decode(bin, 3, "\\a") != 1 || bin[0] != 'a') 104 errors++; 105 106 array[0] = 10; 107 array[1] = 10; 108 array[2] = 5; 109 array[3] = 10; 110 array[4] = 5; 111 array[5] = 0; 112 if (int_array_len(array) != 5) 113 errors++; 114 int_array_sort_unique(array); 115 if (int_array_len(array) != 2) 116 errors++; 117 118 if (errors) { 119 wpa_printf(MSG_ERROR, "%d printf test(s) failed", errors); 120 return -1; 121 } 122 123 return 0; 124} 125 126 127static int bitfield_tests(void) 128{ 129 struct bitfield *bf; 130 int i; 131 int errors = 0; 132 133 wpa_printf(MSG_INFO, "bitfield tests"); 134 135 bf = bitfield_alloc(123); 136 if (bf == NULL) 137 return -1; 138 139 for (i = 0; i < 123; i++) { 140 if (bitfield_is_set(bf, i) || bitfield_is_set(bf, i + 1)) 141 errors++; 142 if (i > 0 && bitfield_is_set(bf, i - 1)) 143 errors++; 144 bitfield_set(bf, i); 145 if (!bitfield_is_set(bf, i)) 146 errors++; 147 bitfield_clear(bf, i); 148 if (bitfield_is_set(bf, i)) 149 errors++; 150 } 151 152 for (i = 123; i < 200; i++) { 153 if (bitfield_is_set(bf, i) || bitfield_is_set(bf, i + 1)) 154 errors++; 155 if (i > 0 && bitfield_is_set(bf, i - 1)) 156 errors++; 157 bitfield_set(bf, i); 158 if (bitfield_is_set(bf, i)) 159 errors++; 160 bitfield_clear(bf, i); 161 if (bitfield_is_set(bf, i)) 162 errors++; 163 } 164 165 for (i = 0; i < 123; i++) { 166 if (bitfield_is_set(bf, i) || bitfield_is_set(bf, i + 1)) 167 errors++; 168 bitfield_set(bf, i); 169 if (!bitfield_is_set(bf, i)) 170 errors++; 171 } 172 173 for (i = 0; i < 123; i++) { 174 if (!bitfield_is_set(bf, i)) 175 errors++; 176 bitfield_clear(bf, i); 177 if (bitfield_is_set(bf, i)) 178 errors++; 179 } 180 181 for (i = 0; i < 123; i++) { 182 if (bitfield_get_first_zero(bf) != i) 183 errors++; 184 bitfield_set(bf, i); 185 } 186 if (bitfield_get_first_zero(bf) != -1) 187 errors++; 188 for (i = 0; i < 123; i++) { 189 if (!bitfield_is_set(bf, i)) 190 errors++; 191 bitfield_clear(bf, i); 192 if (bitfield_get_first_zero(bf) != i) 193 errors++; 194 bitfield_set(bf, i); 195 } 196 if (bitfield_get_first_zero(bf) != -1) 197 errors++; 198 199 bitfield_free(bf); 200 201 bf = bitfield_alloc(8); 202 if (bf == NULL) 203 return -1; 204 if (bitfield_get_first_zero(bf) != 0) 205 errors++; 206 for (i = 0; i < 8; i++) 207 bitfield_set(bf, i); 208 if (bitfield_get_first_zero(bf) != -1) 209 errors++; 210 bitfield_free(bf); 211 212 if (errors) { 213 wpa_printf(MSG_ERROR, "%d bitfield test(s) failed", errors); 214 return -1; 215 } 216 217 return 0; 218} 219 220 221static int int_array_tests(void) 222{ 223 int test1[] = { 1, 2, 3, 4, 5, 6, 0 }; 224 int test2[] = { 1, -1, 0 }; 225 int test3[] = { 1, 1, 1, -1, 2, 3, 4, 1, 2, 0 }; 226 int test3_res[] = { -1, 1, 2, 3, 4, 0 }; 227 int errors = 0; 228 int len; 229 230 wpa_printf(MSG_INFO, "int_array tests"); 231 232 if (int_array_len(test1) != 6 || 233 int_array_len(test2) != 2) 234 errors++; 235 236 int_array_sort_unique(test3); 237 len = int_array_len(test3_res); 238 if (int_array_len(test3) != len) 239 errors++; 240 else if (os_memcmp(test3, test3_res, len * sizeof(int)) != 0) 241 errors++; 242 243 if (errors) { 244 wpa_printf(MSG_ERROR, "%d int_array test(s) failed", errors); 245 return -1; 246 } 247 248 return 0; 249} 250 251 252static int ext_password_tests(void) 253{ 254 struct ext_password_data *data; 255 int ret = 0; 256 struct wpabuf *pw; 257 258 wpa_printf(MSG_INFO, "ext_password tests"); 259 260 data = ext_password_init("unknown", "foo"); 261 if (data != NULL) 262 return -1; 263 264 data = ext_password_init("test", NULL); 265 if (data == NULL) 266 return -1; 267 pw = ext_password_get(data, "foo"); 268 if (pw != NULL) 269 ret = -1; 270 ext_password_free(pw); 271 272 ext_password_deinit(data); 273 274 pw = ext_password_get(NULL, "foo"); 275 if (pw != NULL) 276 ret = -1; 277 ext_password_free(pw); 278 279 return ret; 280} 281 282 283static int trace_tests(void) 284{ 285 wpa_printf(MSG_INFO, "trace tests"); 286 287 wpa_trace_show("test backtrace"); 288 wpa_trace_dump_funcname("test funcname", trace_tests); 289 290 return 0; 291} 292 293 294static int base64_tests(void) 295{ 296 int errors = 0; 297 unsigned char *res; 298 size_t res_len; 299 300 wpa_printf(MSG_INFO, "base64 tests"); 301 302 res = base64_encode((const unsigned char *) "", ~0, &res_len); 303 if (res) { 304 errors++; 305 os_free(res); 306 } 307 308 res = base64_encode((const unsigned char *) "=", 1, &res_len); 309 if (!res || res_len != 5 || res[0] != 'P' || res[1] != 'Q' || 310 res[2] != '=' || res[3] != '=' || res[4] != '\n') 311 errors++; 312 os_free(res); 313 314 res = base64_encode((const unsigned char *) "=", 1, NULL); 315 if (!res || res[0] != 'P' || res[1] != 'Q' || 316 res[2] != '=' || res[3] != '=' || res[4] != '\n') 317 errors++; 318 os_free(res); 319 320 res = base64_decode((const unsigned char *) "", 0, &res_len); 321 if (res) { 322 errors++; 323 os_free(res); 324 } 325 326 res = base64_decode((const unsigned char *) "a", 1, &res_len); 327 if (res) { 328 errors++; 329 os_free(res); 330 } 331 332 res = base64_decode((const unsigned char *) "====", 4, &res_len); 333 if (res) { 334 errors++; 335 os_free(res); 336 } 337 338 res = base64_decode((const unsigned char *) "PQ==", 4, &res_len); 339 if (!res || res_len != 1 || res[0] != '=') 340 errors++; 341 os_free(res); 342 343 res = base64_decode((const unsigned char *) "P.Q-=!=*", 8, &res_len); 344 if (!res || res_len != 1 || res[0] != '=') 345 errors++; 346 os_free(res); 347 348 if (errors) { 349 wpa_printf(MSG_ERROR, "%d base64 test(s) failed", errors); 350 return -1; 351 } 352 353 return 0; 354} 355 356 357static int common_tests(void) 358{ 359 char buf[3], longbuf[100]; 360 u8 addr[ETH_ALEN] = { 1, 2, 3, 4, 5, 6 }; 361 u8 bin[3]; 362 int errors = 0; 363 struct wpa_freq_range_list ranges; 364 size_t len; 365 const char *txt; 366 u8 ssid[255]; 367 368 wpa_printf(MSG_INFO, "common tests"); 369 370 if (hwaddr_mask_txt(buf, 3, addr, addr) != -1) 371 errors++; 372 373 if (wpa_scnprintf(buf, 0, "hello") != 0 || 374 wpa_scnprintf(buf, 3, "hello") != 2) 375 errors++; 376 377 if (wpa_snprintf_hex(buf, 0, addr, ETH_ALEN) != 0 || 378 wpa_snprintf_hex(buf, 3, addr, ETH_ALEN) != 2) 379 errors++; 380 381 if (merge_byte_arrays(bin, 3, addr, ETH_ALEN, NULL, 0) != 3 || 382 merge_byte_arrays(bin, 3, NULL, 0, addr, ETH_ALEN) != 3) 383 errors++; 384 385 if (dup_binstr(NULL, 0) != NULL) 386 errors++; 387 388 if (freq_range_list_includes(NULL, 0) != 0) 389 errors++; 390 391 os_memset(&ranges, 0, sizeof(ranges)); 392 if (freq_range_list_parse(&ranges, "") != 0 || 393 freq_range_list_includes(&ranges, 0) != 0 || 394 freq_range_list_str(&ranges) != NULL) 395 errors++; 396 397 if (utf8_unescape(NULL, 0, buf, sizeof(buf)) != 0 || 398 utf8_unescape("a", 1, NULL, 0) != 0 || 399 utf8_unescape("a\\", 2, buf, sizeof(buf)) != 0 || 400 utf8_unescape("abcde", 5, buf, sizeof(buf)) != 0 || 401 utf8_unescape("abc", 3, buf, 3) != 3) 402 errors++; 403 404 if (utf8_unescape("a", 0, buf, sizeof(buf)) != 1 || buf[0] != 'a') 405 errors++; 406 407 if (utf8_unescape("\\b", 2, buf, sizeof(buf)) != 1 || buf[0] != 'b') 408 errors++; 409 410 if (utf8_escape(NULL, 0, buf, sizeof(buf)) != 0 || 411 utf8_escape("a", 1, NULL, 0) != 0 || 412 utf8_escape("abcde", 5, buf, sizeof(buf)) != 0 || 413 utf8_escape("a\\bcde", 6, buf, sizeof(buf)) != 0 || 414 utf8_escape("ab\\cde", 6, buf, sizeof(buf)) != 0 || 415 utf8_escape("abc\\de", 6, buf, sizeof(buf)) != 0 || 416 utf8_escape("abc", 3, buf, 3) != 3) 417 errors++; 418 419 if (utf8_escape("a", 0, buf, sizeof(buf)) != 1 || buf[0] != 'a') 420 errors++; 421 422 os_memset(ssid, 0, sizeof(ssid)); 423 txt = wpa_ssid_txt(ssid, sizeof(ssid)); 424 len = os_strlen(txt); 425 /* Verify that SSID_MAX_LEN * 4 buffer limit is enforced. */ 426 if (len != SSID_MAX_LEN * 4) { 427 wpa_printf(MSG_ERROR, 428 "Unexpected wpa_ssid_txt() result with too long SSID"); 429 errors++; 430 } 431 432 if (wpa_snprintf_hex_sep(longbuf, 0, addr, ETH_ALEN, '-') != 0 || 433 wpa_snprintf_hex_sep(longbuf, 5, addr, ETH_ALEN, '-') != 3 || 434 os_strcmp(longbuf, "01-0") != 0) 435 errors++; 436 437 if (errors) { 438 wpa_printf(MSG_ERROR, "%d common test(s) failed", errors); 439 return -1; 440 } 441 442 return 0; 443} 444 445 446static int os_tests(void) 447{ 448 int errors = 0; 449 void *ptr; 450 os_time_t t; 451 452 wpa_printf(MSG_INFO, "os tests"); 453 454 ptr = os_calloc((size_t) -1, (size_t) -1); 455 if (ptr) { 456 errors++; 457 os_free(ptr); 458 } 459 ptr = os_calloc((size_t) 2, (size_t) -1); 460 if (ptr) { 461 errors++; 462 os_free(ptr); 463 } 464 ptr = os_calloc((size_t) -1, (size_t) 2); 465 if (ptr) { 466 errors++; 467 os_free(ptr); 468 } 469 470 ptr = os_realloc_array(NULL, (size_t) -1, (size_t) -1); 471 if (ptr) { 472 errors++; 473 os_free(ptr); 474 } 475 476 os_sleep(1, 1); 477 478 if (os_mktime(1969, 1, 1, 1, 1, 1, &t) == 0 || 479 os_mktime(1971, 0, 1, 1, 1, 1, &t) == 0 || 480 os_mktime(1971, 13, 1, 1, 1, 1, &t) == 0 || 481 os_mktime(1971, 1, 0, 1, 1, 1, &t) == 0 || 482 os_mktime(1971, 1, 32, 1, 1, 1, &t) == 0 || 483 os_mktime(1971, 1, 1, -1, 1, 1, &t) == 0 || 484 os_mktime(1971, 1, 1, 24, 1, 1, &t) == 0 || 485 os_mktime(1971, 1, 1, 1, -1, 1, &t) == 0 || 486 os_mktime(1971, 1, 1, 1, 60, 1, &t) == 0 || 487 os_mktime(1971, 1, 1, 1, 1, -1, &t) == 0 || 488 os_mktime(1971, 1, 1, 1, 1, 61, &t) == 0 || 489 os_mktime(1971, 1, 1, 1, 1, 1, &t) != 0 || 490 os_mktime(2020, 1, 2, 3, 4, 5, &t) != 0 || 491 os_mktime(2015, 12, 31, 23, 59, 59, &t) != 0) 492 errors++; 493 494 if (os_setenv("hwsim_test_env", "test value", 0) != 0 || 495 os_setenv("hwsim_test_env", "test value 2", 1) != 0 || 496 os_unsetenv("hwsim_test_env") != 0) 497 errors++; 498 499 if (os_file_exists("/this-file-does-not-exists-hwsim") != 0) 500 errors++; 501 502 if (errors) { 503 wpa_printf(MSG_ERROR, "%d os test(s) failed", errors); 504 return -1; 505 } 506 507 return 0; 508} 509 510 511static int wpabuf_tests(void) 512{ 513 int errors = 0; 514 void *ptr; 515 struct wpabuf *buf; 516 517 wpa_printf(MSG_INFO, "wpabuf tests"); 518 519 ptr = os_malloc(100); 520 if (ptr) { 521 buf = wpabuf_alloc_ext_data(ptr, 100); 522 if (buf) { 523 if (wpabuf_resize(&buf, 100) < 0) 524 errors++; 525 else 526 wpabuf_put(buf, 100); 527 wpabuf_free(buf); 528 } else { 529 errors++; 530 os_free(ptr); 531 } 532 } else { 533 errors++; 534 } 535 536 buf = wpabuf_alloc(100); 537 if (buf) { 538 struct wpabuf *buf2; 539 540 wpabuf_put(buf, 100); 541 if (wpabuf_resize(&buf, 100) < 0) 542 errors++; 543 else 544 wpabuf_put(buf, 100); 545 buf2 = wpabuf_concat(buf, NULL); 546 if (buf2 != buf) 547 errors++; 548 wpabuf_free(buf2); 549 } else { 550 errors++; 551 } 552 553 buf = NULL; 554 buf = wpabuf_zeropad(buf, 10); 555 if (buf != NULL) 556 errors++; 557 558 if (errors) { 559 wpa_printf(MSG_ERROR, "%d wpabuf test(s) failed", errors); 560 return -1; 561 } 562 563 return 0; 564} 565 566 567static int ip_addr_tests(void) 568{ 569 int errors = 0; 570 struct hostapd_ip_addr addr; 571 char buf[100]; 572 573 wpa_printf(MSG_INFO, "ip_addr tests"); 574 575 if (hostapd_parse_ip_addr("1.2.3.4", &addr) != 0 || 576 addr.af != AF_INET || 577 hostapd_ip_txt(NULL, buf, sizeof(buf)) != NULL || 578 hostapd_ip_txt(&addr, buf, 1) != buf || buf[0] != '\0' || 579 hostapd_ip_txt(&addr, buf, 0) != NULL || 580 hostapd_ip_txt(&addr, buf, sizeof(buf)) != buf) 581 errors++; 582 583 if (hostapd_parse_ip_addr("::", &addr) != 0 || 584 addr.af != AF_INET6 || 585 hostapd_ip_txt(&addr, buf, 1) != buf || buf[0] != '\0' || 586 hostapd_ip_txt(&addr, buf, sizeof(buf)) != buf) 587 errors++; 588 589 if (errors) { 590 wpa_printf(MSG_ERROR, "%d ip_addr test(s) failed", errors); 591 return -1; 592 } 593 594 return 0; 595} 596 597 598struct test_eloop { 599 unsigned int magic; 600 int close_in_timeout; 601 int pipefd1[2]; 602 int pipefd2[2]; 603}; 604 605 606static void eloop_tests_start(int close_in_timeout); 607 608 609static void eloop_test_read_2(int sock, void *eloop_ctx, void *sock_ctx) 610{ 611 struct test_eloop *t = eloop_ctx; 612 ssize_t res; 613 char buf[10]; 614 615 wpa_printf(MSG_INFO, "%s: sock=%d", __func__, sock); 616 617 if (t->magic != 0x12345678) { 618 wpa_printf(MSG_INFO, "%s: unexpected magic 0x%x", 619 __func__, t->magic); 620 } 621 622 if (t->pipefd2[0] != sock) { 623 wpa_printf(MSG_INFO, "%s: unexpected sock %d != %d", 624 __func__, sock, t->pipefd2[0]); 625 } 626 627 res = read(sock, buf, sizeof(buf)); 628 wpa_printf(MSG_INFO, "%s: sock=%d --> res=%d", 629 __func__, sock, (int) res); 630} 631 632 633static void eloop_test_read_2_wrong(int sock, void *eloop_ctx, void *sock_ctx) 634{ 635 struct test_eloop *t = eloop_ctx; 636 637 wpa_printf(MSG_INFO, "%s: sock=%d", __func__, sock); 638 639 if (t->magic != 0x12345678) { 640 wpa_printf(MSG_INFO, "%s: unexpected magic 0x%x", 641 __func__, t->magic); 642 } 643 644 if (t->pipefd2[0] != sock) { 645 wpa_printf(MSG_INFO, "%s: unexpected sock %d != %d", 646 __func__, sock, t->pipefd2[0]); 647 } 648 649 /* 650 * This is expected to block due to the original socket with data having 651 * been closed and no new data having been written to the new socket 652 * with the same fd. To avoid blocking the process during test, skip the 653 * read here. 654 */ 655 wpa_printf(MSG_ERROR, "%s: FAIL - should not have called this function", 656 __func__); 657} 658 659 660static void reopen_pipefd2(struct test_eloop *t) 661{ 662 if (t->pipefd2[0] < 0) { 663 wpa_printf(MSG_INFO, "pipefd2 had been closed"); 664 } else { 665 int res; 666 667 wpa_printf(MSG_INFO, "close pipefd2"); 668 eloop_unregister_read_sock(t->pipefd2[0]); 669 close(t->pipefd2[0]); 670 t->pipefd2[0] = -1; 671 close(t->pipefd2[1]); 672 t->pipefd2[1] = -1; 673 674 res = pipe(t->pipefd2); 675 if (res < 0) { 676 wpa_printf(MSG_INFO, "pipe: %s", strerror(errno)); 677 t->pipefd2[0] = -1; 678 t->pipefd2[1] = -1; 679 return; 680 } 681 682 wpa_printf(MSG_INFO, 683 "re-register pipefd2 with new sockets %d,%d", 684 t->pipefd2[0], t->pipefd2[1]); 685 eloop_register_read_sock(t->pipefd2[0], eloop_test_read_2_wrong, 686 t, NULL); 687 } 688} 689 690 691static void eloop_test_read_1(int sock, void *eloop_ctx, void *sock_ctx) 692{ 693 struct test_eloop *t = eloop_ctx; 694 ssize_t res; 695 char buf[10]; 696 697 wpa_printf(MSG_INFO, "%s: sock=%d", __func__, sock); 698 699 if (t->magic != 0x12345678) { 700 wpa_printf(MSG_INFO, "%s: unexpected magic 0x%x", 701 __func__, t->magic); 702 } 703 704 if (t->pipefd1[0] != sock) { 705 wpa_printf(MSG_INFO, "%s: unexpected sock %d != %d", 706 __func__, sock, t->pipefd1[0]); 707 } 708 709 res = read(sock, buf, sizeof(buf)); 710 wpa_printf(MSG_INFO, "%s: sock=%d --> res=%d", 711 __func__, sock, (int) res); 712 713 if (!t->close_in_timeout) 714 reopen_pipefd2(t); 715} 716 717 718static void eloop_test_cb(void *eloop_data, void *user_ctx) 719{ 720 struct test_eloop *t = eloop_data; 721 722 wpa_printf(MSG_INFO, "%s", __func__); 723 724 if (t->magic != 0x12345678) { 725 wpa_printf(MSG_INFO, "%s: unexpected magic 0x%x", 726 __func__, t->magic); 727 } 728 729 if (t->close_in_timeout) 730 reopen_pipefd2(t); 731} 732 733 734static void eloop_test_timeout(void *eloop_data, void *user_ctx) 735{ 736 struct test_eloop *t = eloop_data; 737 int next_run = 0; 738 739 wpa_printf(MSG_INFO, "%s", __func__); 740 741 if (t->magic != 0x12345678) { 742 wpa_printf(MSG_INFO, "%s: unexpected magic 0x%x", 743 __func__, t->magic); 744 } 745 746 if (t->pipefd1[0] >= 0) { 747 wpa_printf(MSG_INFO, "pipefd1 had not been closed"); 748 eloop_unregister_read_sock(t->pipefd1[0]); 749 close(t->pipefd1[0]); 750 t->pipefd1[0] = -1; 751 close(t->pipefd1[1]); 752 t->pipefd1[1] = -1; 753 } 754 755 if (t->pipefd2[0] >= 0) { 756 wpa_printf(MSG_INFO, "pipefd2 had not been closed"); 757 eloop_unregister_read_sock(t->pipefd2[0]); 758 close(t->pipefd2[0]); 759 t->pipefd2[0] = -1; 760 close(t->pipefd2[1]); 761 t->pipefd2[1] = -1; 762 } 763 764 next_run = t->close_in_timeout; 765 t->magic = 0; 766 wpa_printf(MSG_INFO, "%s - free(%p)", __func__, t); 767 os_free(t); 768 769 if (next_run) 770 eloop_tests_start(0); 771} 772 773 774static void eloop_tests_start(int close_in_timeout) 775{ 776 struct test_eloop *t; 777 int res; 778 779 t = os_zalloc(sizeof(*t)); 780 if (!t) 781 return; 782 t->magic = 0x12345678; 783 t->close_in_timeout = close_in_timeout; 784 785 wpa_printf(MSG_INFO, "starting eloop tests (%p) (close_in_timeout=%d)", 786 t, close_in_timeout); 787 788 res = pipe(t->pipefd1); 789 if (res < 0) { 790 wpa_printf(MSG_INFO, "pipe: %s", strerror(errno)); 791 os_free(t); 792 return; 793 } 794 795 res = pipe(t->pipefd2); 796 if (res < 0) { 797 wpa_printf(MSG_INFO, "pipe: %s", strerror(errno)); 798 close(t->pipefd1[0]); 799 close(t->pipefd1[1]); 800 os_free(t); 801 return; 802 } 803 804 wpa_printf(MSG_INFO, "pipe fds: %d,%d %d,%d", 805 t->pipefd1[0], t->pipefd1[1], 806 t->pipefd2[0], t->pipefd2[1]); 807 808 eloop_register_read_sock(t->pipefd1[0], eloop_test_read_1, t, NULL); 809 eloop_register_read_sock(t->pipefd2[0], eloop_test_read_2, t, NULL); 810 eloop_register_timeout(0, 0, eloop_test_cb, t, NULL); 811 eloop_register_timeout(0, 200000, eloop_test_timeout, t, NULL); 812 813 if (write(t->pipefd1[1], "HELLO", 5) < 0) 814 wpa_printf(MSG_INFO, "write: %s", strerror(errno)); 815 if (write(t->pipefd2[1], "TEST", 4) < 0) 816 wpa_printf(MSG_INFO, "write: %s", strerror(errno)); 817 os_sleep(0, 50000); 818 wpa_printf(MSG_INFO, "waiting for eloop callbacks"); 819} 820 821 822static void eloop_tests_run(void *eloop_data, void *user_ctx) 823{ 824 eloop_tests_start(1); 825} 826 827 828static int eloop_tests(void) 829{ 830 wpa_printf(MSG_INFO, "schedule eloop tests to be run"); 831 832 /* 833 * Cannot return error from these without a significant design change, 834 * so for now, run the tests from a scheduled timeout and require 835 * separate verification of the results from the debug log. 836 */ 837 eloop_register_timeout(0, 0, eloop_tests_run, NULL, NULL); 838 839 return 0; 840} 841 842 843#ifdef CONFIG_JSON 844struct json_test_data { 845 const char *json; 846 const char *tree; 847}; 848 849static const struct json_test_data json_test_cases[] = { 850 { "{}", "[1:OBJECT:]" }, 851 { "[]", "[1:ARRAY:]" }, 852 { "{", NULL }, 853 { "[", NULL }, 854 { "}", NULL }, 855 { "]", NULL }, 856 { "[[]]", "[1:ARRAY:][2:ARRAY:]" }, 857 { "{\"t\":\"test\"}", "[1:OBJECT:][2:STRING:t]" }, 858 { "{\"t\":123}", "[1:OBJECT:][2:NUMBER:t]" }, 859 { "{\"t\":true}", "[1:OBJECT:][2:BOOLEAN:t]" }, 860 { "{\"t\":false}", "[1:OBJECT:][2:BOOLEAN:t]" }, 861 { "{\"t\":null}", "[1:OBJECT:][2:NULL:t]" }, 862 { "{\"t\":truetrue}", NULL }, 863 { "\"test\"", "[1:STRING:]" }, 864 { "123", "[1:NUMBER:]" }, 865 { "true", "[1:BOOLEAN:]" }, 866 { "false", "[1:BOOLEAN:]" }, 867 { "null", "[1:NULL:]" }, 868 { "truetrue", NULL }, 869 { " {\t\n\r\"a\"\n:\r1\n,\n\"b\":3\n}\n", 870 "[1:OBJECT:][2:NUMBER:a][2:NUMBER:b]" }, 871 { ",", NULL }, 872 { "{,}", NULL }, 873 { "[,]", NULL }, 874 { ":", NULL }, 875 { "{:}", NULL }, 876 { "[:]", NULL }, 877 { "{ \"\\u005c\" : \"\\u005c\" }", "[1:OBJECT:][2:STRING:\\]" }, 878 { "[{},{}]", "[1:ARRAY:][2:OBJECT:][2:OBJECT:]" }, 879 { "[1,2]", "[1:ARRAY:][2:NUMBER:][2:NUMBER:]" }, 880 { "[\"1\",\"2\"]", "[1:ARRAY:][2:STRING:][2:STRING:]" }, 881 { "[true,false]", "[1:ARRAY:][2:BOOLEAN:][2:BOOLEAN:]" }, 882}; 883#endif /* CONFIG_JSON */ 884 885 886static int json_tests(void) 887{ 888#ifdef CONFIG_JSON 889 unsigned int i; 890 struct json_token *root; 891 char buf[1000]; 892 893 wpa_printf(MSG_INFO, "JSON tests"); 894 895 for (i = 0; i < ARRAY_SIZE(json_test_cases); i++) { 896 const struct json_test_data *test = &json_test_cases[i]; 897 int res = 0; 898 899 root = json_parse(test->json, os_strlen(test->json)); 900 if ((root && !test->tree) || (!root && test->tree)) { 901 wpa_printf(MSG_INFO, "JSON test %u failed", i); 902 res = -1; 903 } else if (root) { 904 json_print_tree(root, buf, sizeof(buf)); 905 if (os_strcmp(buf, test->tree) != 0) { 906 wpa_printf(MSG_INFO, 907 "JSON test %u tree mismatch: %s %s", 908 i, buf, test->tree); 909 res = -1; 910 } 911 } 912 json_free(root); 913 if (res < 0) 914 return -1; 915 916 } 917#endif /* CONFIG_JSON */ 918 return 0; 919} 920 921 922int utils_module_tests(void) 923{ 924 int ret = 0; 925 926 wpa_printf(MSG_INFO, "utils module tests"); 927 928 if (printf_encode_decode_tests() < 0 || 929 ext_password_tests() < 0 || 930 trace_tests() < 0 || 931 bitfield_tests() < 0 || 932 base64_tests() < 0 || 933 common_tests() < 0 || 934 os_tests() < 0 || 935 wpabuf_tests() < 0 || 936 ip_addr_tests() < 0 || 937 eloop_tests() < 0 || 938 json_tests() < 0 || 939 int_array_tests() < 0) 940 ret = -1; 941 942 return ret; 943} 944