]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - src/utils/utils_module_tests.c
Import wpa_supplicant/hostapd 2.7
[FreeBSD/FreeBSD.git] / src / utils / utils_module_tests.c
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
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 }