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