Home | History | Annotate | Download | only in utils
      1 /*
      2  * utils module tests
      3  * Copyright (c) 2014-2015, Jouni Malinen <j (at) 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 
     23 struct printf_test_data {
     24 	u8 *data;
     25 	size_t len;
     26 	char *encoded;
     27 };
     28 
     29 static 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 
     44 static 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 
    127 static 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 
    221 static 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 
    252 static 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 
    283 static 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 
    294 static 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 
    357 static 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 
    446 static 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 
    511 static 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 
    567 static 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 
    598 struct test_eloop {
    599 	unsigned int magic;
    600 	int close_in_timeout;
    601 	int pipefd1[2];
    602 	int pipefd2[2];
    603 };
    604 
    605 
    606 static void eloop_tests_start(int close_in_timeout);
    607 
    608 
    609 static 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 
    633 static 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 
    660 static 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 
    691 static 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 
    718 static 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 
    734 static 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 
    774 static 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 
    822 static void eloop_tests_run(void *eloop_data, void *user_ctx)
    823 {
    824 	eloop_tests_start(1);
    825 }
    826 
    827 
    828 static 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
    844 struct json_test_data {
    845 	const char *json;
    846 	const char *tree;
    847 };
    848 
    849 static 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 
    886 static 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 
    922 int 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