]> arthur.barton.de Git - netatalk.git/blob - libevent/test/regress.c
Add libevent
[netatalk.git] / libevent / test / regress.c
1 /*
2  * Copyright (c) 2003-2007 Niels Provos <provos@citi.umich.edu>
3  * Copyright (c) 2007-2010 Niels Provos and Nick Mathewson
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. The name of the author may not be used to endorse or promote products
14  *    derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 #ifdef WIN32
29 #include <winsock2.h>
30 #include <windows.h>
31 #endif
32
33 #include "event2/event-config.h"
34
35 #include <sys/types.h>
36 #include <sys/stat.h>
37 #ifdef _EVENT_HAVE_SYS_TIME_H
38 #include <sys/time.h>
39 #endif
40 #include <sys/queue.h>
41 #ifndef WIN32
42 #include <sys/socket.h>
43 #include <sys/wait.h>
44 #include <signal.h>
45 #include <unistd.h>
46 #include <netdb.h>
47 #endif
48 #include <fcntl.h>
49 #include <signal.h>
50 #include <stdlib.h>
51 #include <stdio.h>
52 #include <string.h>
53 #include <errno.h>
54 #include <assert.h>
55 #include <ctype.h>
56
57 #include "event2/event.h"
58 #include "event2/event_struct.h"
59 #include "event2/event_compat.h"
60 #include "event2/tag.h"
61 #include "event2/buffer.h"
62 #include "event2/buffer_compat.h"
63 #include "event2/util.h"
64 #include "event-internal.h"
65 #include "evthread-internal.h"
66 #include "util-internal.h"
67 #include "log-internal.h"
68
69 #include "regress.h"
70
71 #ifndef WIN32
72 #include "regress.gen.h"
73 #endif
74
75 evutil_socket_t pair[2];
76 int test_ok;
77 int called;
78 struct event_base *global_base;
79
80 static char wbuf[4096];
81 static char rbuf[4096];
82 static int woff;
83 static int roff;
84 static int usepersist;
85 static struct timeval tset;
86 static struct timeval tcalled;
87
88
89 #define TEST1   "this is a test"
90 #define SECONDS 1
91
92 #ifndef SHUT_WR
93 #define SHUT_WR 1
94 #endif
95
96 #ifdef WIN32
97 #define write(fd,buf,len) send((fd),(buf),(int)(len),0)
98 #define read(fd,buf,len) recv((fd),(buf),(int)(len),0)
99 #endif
100
101 struct basic_cb_args
102 {
103         struct event_base *eb;
104         struct event *ev;
105         unsigned int callcount;
106 };
107
108 static void
109 simple_read_cb(evutil_socket_t fd, short event, void *arg)
110 {
111         char buf[256];
112         int len;
113
114         len = read(fd, buf, sizeof(buf));
115
116         if (len) {
117                 if (!called) {
118                         if (event_add(arg, NULL) == -1)
119                                 exit(1);
120                 }
121         } else if (called == 1)
122                 test_ok = 1;
123
124         called++;
125 }
126
127 static void
128 basic_read_cb(evutil_socket_t fd, short event, void *data)
129 {
130         char buf[256];
131         int len;
132         struct basic_cb_args *arg = data;
133
134         len = read(fd, buf, sizeof(buf));
135
136         if (len < 0) {
137                 tt_fail_perror("read (callback)");
138         } else {
139                 switch (arg->callcount++) {
140                 case 0:  /* first call: expect to read data; cycle */
141                         if (len > 0)
142                                 return;
143
144                         tt_fail_msg("EOF before data read");
145                         break;
146
147                 case 1:  /* second call: expect EOF; stop */
148                         if (len > 0)
149                                 tt_fail_msg("not all data read on first cycle");
150                         break;
151
152                 default:  /* third call: should not happen */
153                         tt_fail_msg("too many cycles");
154                 }
155         }
156
157         event_del(arg->ev);
158         event_base_loopexit(arg->eb, NULL);
159 }
160
161 static void
162 dummy_read_cb(evutil_socket_t fd, short event, void *arg)
163 {
164 }
165
166 static void
167 simple_write_cb(evutil_socket_t fd, short event, void *arg)
168 {
169         int len;
170
171         len = write(fd, TEST1, strlen(TEST1) + 1);
172         if (len == -1)
173                 test_ok = 0;
174         else
175                 test_ok = 1;
176 }
177
178 static void
179 multiple_write_cb(evutil_socket_t fd, short event, void *arg)
180 {
181         struct event *ev = arg;
182         int len;
183
184         len = 128;
185         if (woff + len >= (int)sizeof(wbuf))
186                 len = sizeof(wbuf) - woff;
187
188         len = write(fd, wbuf + woff, len);
189         if (len == -1) {
190                 fprintf(stderr, "%s: write\n", __func__);
191                 if (usepersist)
192                         event_del(ev);
193                 return;
194         }
195
196         woff += len;
197
198         if (woff >= (int)sizeof(wbuf)) {
199                 shutdown(fd, SHUT_WR);
200                 if (usepersist)
201                         event_del(ev);
202                 return;
203         }
204
205         if (!usepersist) {
206                 if (event_add(ev, NULL) == -1)
207                         exit(1);
208         }
209 }
210
211 static void
212 multiple_read_cb(evutil_socket_t fd, short event, void *arg)
213 {
214         struct event *ev = arg;
215         int len;
216
217         len = read(fd, rbuf + roff, sizeof(rbuf) - roff);
218         if (len == -1)
219                 fprintf(stderr, "%s: read\n", __func__);
220         if (len <= 0) {
221                 if (usepersist)
222                         event_del(ev);
223                 return;
224         }
225
226         roff += len;
227         if (!usepersist) {
228                 if (event_add(ev, NULL) == -1)
229                         exit(1);
230         }
231 }
232
233 static void
234 timeout_cb(evutil_socket_t fd, short event, void *arg)
235 {
236         struct timeval tv;
237         int diff;
238
239         evutil_gettimeofday(&tcalled, NULL);
240         if (evutil_timercmp(&tcalled, &tset, >))
241                 evutil_timersub(&tcalled, &tset, &tv);
242         else
243                 evutil_timersub(&tset, &tcalled, &tv);
244
245         diff = tv.tv_sec*1000 + tv.tv_usec/1000 - SECONDS * 1000;
246         if (diff < 0)
247                 diff = -diff;
248
249         if (diff < 100)
250                 test_ok = 1;
251 }
252
253 struct both {
254         struct event ev;
255         int nread;
256 };
257
258 static void
259 combined_read_cb(evutil_socket_t fd, short event, void *arg)
260 {
261         struct both *both = arg;
262         char buf[128];
263         int len;
264
265         len = read(fd, buf, sizeof(buf));
266         if (len == -1)
267                 fprintf(stderr, "%s: read\n", __func__);
268         if (len <= 0)
269                 return;
270
271         both->nread += len;
272         if (event_add(&both->ev, NULL) == -1)
273                 exit(1);
274 }
275
276 static void
277 combined_write_cb(evutil_socket_t fd, short event, void *arg)
278 {
279         struct both *both = arg;
280         char buf[128];
281         int len;
282
283         len = sizeof(buf);
284         if (len > both->nread)
285                 len = both->nread;
286
287         memset(buf, 'q', len);
288
289         len = write(fd, buf, len);
290         if (len == -1)
291                 fprintf(stderr, "%s: write\n", __func__);
292         if (len <= 0) {
293                 shutdown(fd, SHUT_WR);
294                 return;
295         }
296
297         both->nread -= len;
298         if (event_add(&both->ev, NULL) == -1)
299                 exit(1);
300 }
301
302 /* These macros used to replicate the work of the legacy test wrapper code */
303 #define setup_test(x) do {                                              \
304         if (!in_legacy_test_wrapper) {                                  \
305                 TT_FAIL(("Legacy test %s not wrapped properly", x));    \
306                 return;                                                 \
307         }                                                               \
308         } while (0)
309 #define cleanup_test() setup_test("cleanup")
310
311 static void
312 test_simpleread(void)
313 {
314         struct event ev;
315
316         /* Very simple read test */
317         setup_test("Simple read: ");
318
319         write(pair[0], TEST1, strlen(TEST1)+1);
320         shutdown(pair[0], SHUT_WR);
321
322         event_set(&ev, pair[1], EV_READ, simple_read_cb, &ev);
323         if (event_add(&ev, NULL) == -1)
324                 exit(1);
325         event_dispatch();
326
327         cleanup_test();
328 }
329
330 static void
331 test_simplewrite(void)
332 {
333         struct event ev;
334
335         /* Very simple write test */
336         setup_test("Simple write: ");
337
338         event_set(&ev, pair[0], EV_WRITE, simple_write_cb, &ev);
339         if (event_add(&ev, NULL) == -1)
340                 exit(1);
341         event_dispatch();
342
343         cleanup_test();
344 }
345
346 static void
347 simpleread_multiple_cb(evutil_socket_t fd, short event, void *arg)
348 {
349         if (++called == 2)
350                 test_ok = 1;
351 }
352
353 static void
354 test_simpleread_multiple(void)
355 {
356         struct event one, two;
357
358         /* Very simple read test */
359         setup_test("Simple read to multiple evens: ");
360
361         write(pair[0], TEST1, strlen(TEST1)+1);
362         shutdown(pair[0], SHUT_WR);
363
364         event_set(&one, pair[1], EV_READ, simpleread_multiple_cb, NULL);
365         if (event_add(&one, NULL) == -1)
366                 exit(1);
367         event_set(&two, pair[1], EV_READ, simpleread_multiple_cb, NULL);
368         if (event_add(&two, NULL) == -1)
369                 exit(1);
370         event_dispatch();
371
372         cleanup_test();
373 }
374
375 static int have_closed = 0;
376 static int premature_event = 0;
377 static void
378 simpleclose_close_fd_cb(evutil_socket_t s, short what, void *ptr)
379 {
380         evutil_socket_t **fds = ptr;
381         TT_BLATHER(("Closing"));
382         evutil_closesocket(*fds[0]);
383         evutil_closesocket(*fds[1]);
384         *fds[0] = -1;
385         *fds[1] = -1;
386         have_closed = 1;
387 }
388
389 static void
390 record_event_cb(evutil_socket_t s, short what, void *ptr)
391 {
392         short *whatp = ptr;
393         if (!have_closed)
394                 premature_event = 1;
395         *whatp = what;
396         TT_BLATHER(("Recorded %d on socket %d", (int)what, (int)s));
397 }
398
399 static void
400 test_simpleclose(void *ptr)
401 {
402         /* Test that a close of FD is detected as a read and as a write. */
403         struct event_base *base = event_base_new();
404         evutil_socket_t pair1[2]={-1,-1}, pair2[2] = {-1, -1};
405         evutil_socket_t *to_close[2];
406         struct event *rev=NULL, *wev=NULL, *closeev=NULL;
407         struct timeval tv;
408         short got_read_on_close = 0, got_write_on_close = 0;
409         char buf[1024];
410         memset(buf, 99, sizeof(buf));
411 #ifdef WIN32
412 #define LOCAL_SOCKETPAIR_AF AF_INET
413 #else
414 #define LOCAL_SOCKETPAIR_AF AF_UNIX
415 #endif
416         if (evutil_socketpair(LOCAL_SOCKETPAIR_AF, SOCK_STREAM, 0, pair1)<0)
417                 TT_DIE(("socketpair: %s", strerror(errno)));
418         if (evutil_socketpair(LOCAL_SOCKETPAIR_AF, SOCK_STREAM, 0, pair2)<0)
419                 TT_DIE(("socketpair: %s", strerror(errno)));
420         if (evutil_make_socket_nonblocking(pair1[1]) < 0)
421                 TT_DIE(("make_socket_nonblocking"));
422         if (evutil_make_socket_nonblocking(pair2[1]) < 0)
423                 TT_DIE(("make_socket_nonblocking"));
424
425         /** Stuff pair2[1] full of data, until write fails */
426         while (1) {
427                 int r = write(pair2[1], buf, sizeof(buf));
428                 if (r<0) {
429                         int err = evutil_socket_geterror(pair2[1]);
430                         if (! EVUTIL_ERR_RW_RETRIABLE(err))
431                                 TT_DIE(("write failed strangely: %s",
432                                         evutil_socket_error_to_string(err)));
433                         break;
434                 }
435         }
436         to_close[0] = &pair1[0];
437         to_close[1] = &pair2[0];
438
439         closeev = event_new(base, -1, EV_TIMEOUT, simpleclose_close_fd_cb,
440             to_close);
441         rev = event_new(base, pair1[1], EV_READ, record_event_cb,
442             &got_read_on_close);
443         TT_BLATHER(("Waiting for read on %d", (int)pair1[1]));
444         wev = event_new(base, pair2[1], EV_WRITE, record_event_cb,
445             &got_write_on_close);
446         TT_BLATHER(("Waiting for write on %d", (int)pair2[1]));
447         tv.tv_sec = 0;
448         tv.tv_usec = 100*1000; /* Close pair1[0] after a little while, and make
449                                * sure we get a read event. */
450         event_add(closeev, &tv);
451         event_add(rev, NULL);
452         event_add(wev, NULL);
453         /* Don't let the test go on too long. */
454         tv.tv_sec = 0;
455         tv.tv_usec = 200*1000;
456         event_base_loopexit(base, &tv);
457         event_base_loop(base, 0);
458
459         tt_int_op(got_read_on_close, ==, EV_READ);
460         tt_int_op(got_write_on_close, ==, EV_WRITE);
461         tt_int_op(premature_event, ==, 0);
462
463 end:
464         if (pair1[0] >= 0)
465                 evutil_closesocket(pair1[0]);
466         if (pair1[1] >= 0)
467                 evutil_closesocket(pair1[1]);
468         if (pair2[0] >= 0)
469                 evutil_closesocket(pair2[0]);
470         if (pair2[1] >= 0)
471                 evutil_closesocket(pair2[1]);
472         if (rev)
473                 event_free(rev);
474         if (wev)
475                 event_free(wev);
476         if (closeev)
477                 event_free(closeev);
478         if (base)
479                 event_base_free(base);
480 }
481
482
483 static void
484 test_multiple(void)
485 {
486         struct event ev, ev2;
487         int i;
488
489         /* Multiple read and write test */
490         setup_test("Multiple read/write: ");
491         memset(rbuf, 0, sizeof(rbuf));
492         for (i = 0; i < (int)sizeof(wbuf); i++)
493                 wbuf[i] = i;
494
495         roff = woff = 0;
496         usepersist = 0;
497
498         event_set(&ev, pair[0], EV_WRITE, multiple_write_cb, &ev);
499         if (event_add(&ev, NULL) == -1)
500                 exit(1);
501         event_set(&ev2, pair[1], EV_READ, multiple_read_cb, &ev2);
502         if (event_add(&ev2, NULL) == -1)
503                 exit(1);
504         event_dispatch();
505
506         if (roff == woff)
507                 test_ok = memcmp(rbuf, wbuf, sizeof(wbuf)) == 0;
508
509         cleanup_test();
510 }
511
512 static void
513 test_persistent(void)
514 {
515         struct event ev, ev2;
516         int i;
517
518         /* Multiple read and write test with persist */
519         setup_test("Persist read/write: ");
520         memset(rbuf, 0, sizeof(rbuf));
521         for (i = 0; i < (int)sizeof(wbuf); i++)
522                 wbuf[i] = i;
523
524         roff = woff = 0;
525         usepersist = 1;
526
527         event_set(&ev, pair[0], EV_WRITE|EV_PERSIST, multiple_write_cb, &ev);
528         if (event_add(&ev, NULL) == -1)
529                 exit(1);
530         event_set(&ev2, pair[1], EV_READ|EV_PERSIST, multiple_read_cb, &ev2);
531         if (event_add(&ev2, NULL) == -1)
532                 exit(1);
533         event_dispatch();
534
535         if (roff == woff)
536                 test_ok = memcmp(rbuf, wbuf, sizeof(wbuf)) == 0;
537
538         cleanup_test();
539 }
540
541 static void
542 test_combined(void)
543 {
544         struct both r1, r2, w1, w2;
545
546         setup_test("Combined read/write: ");
547         memset(&r1, 0, sizeof(r1));
548         memset(&r2, 0, sizeof(r2));
549         memset(&w1, 0, sizeof(w1));
550         memset(&w2, 0, sizeof(w2));
551
552         w1.nread = 4096;
553         w2.nread = 8192;
554
555         event_set(&r1.ev, pair[0], EV_READ, combined_read_cb, &r1);
556         event_set(&w1.ev, pair[0], EV_WRITE, combined_write_cb, &w1);
557         event_set(&r2.ev, pair[1], EV_READ, combined_read_cb, &r2);
558         event_set(&w2.ev, pair[1], EV_WRITE, combined_write_cb, &w2);
559         tt_assert(event_add(&r1.ev, NULL) != -1);
560         tt_assert(!event_add(&w1.ev, NULL));
561         tt_assert(!event_add(&r2.ev, NULL));
562         tt_assert(!event_add(&w2.ev, NULL));
563         event_dispatch();
564
565         if (r1.nread == 8192 && r2.nread == 4096)
566                 test_ok = 1;
567
568 end:
569         cleanup_test();
570 }
571
572 static void
573 test_simpletimeout(void)
574 {
575         struct timeval tv;
576         struct event ev;
577
578         setup_test("Simple timeout: ");
579
580         tv.tv_usec = 0;
581         tv.tv_sec = SECONDS;
582         evtimer_set(&ev, timeout_cb, NULL);
583         evtimer_add(&ev, &tv);
584
585         evutil_gettimeofday(&tset, NULL);
586         event_dispatch();
587
588         cleanup_test();
589 }
590
591 static void
592 periodic_timeout_cb(evutil_socket_t fd, short event, void *arg)
593 {
594         int *count = arg;
595
596         (*count)++;
597         if (*count == 6) {
598                 /* call loopexit only once - on slow machines(?), it is
599                  * apparently possible for this to get called twice. */
600                 test_ok = 1;
601                 event_base_loopexit(global_base, NULL);
602         }
603 }
604
605 static void
606 test_persistent_timeout(void)
607 {
608         struct timeval tv;
609         struct event ev;
610         int count = 0;
611
612         evutil_timerclear(&tv);
613         tv.tv_usec = 10000;
614
615         event_assign(&ev, global_base, -1, EV_TIMEOUT|EV_PERSIST,
616             periodic_timeout_cb, &count);
617         event_add(&ev, &tv);
618
619         event_dispatch();
620
621         event_del(&ev);
622 }
623
624 struct persist_active_timeout_called {
625         int n;
626         short events[16];
627         struct timeval tvs[16];
628 };
629
630 static void
631 activate_cb(evutil_socket_t fd, short event, void *arg)
632 {
633         struct event *ev = arg;
634         event_active(ev, EV_READ, 1);
635 }
636
637 static void
638 persist_active_timeout_cb(evutil_socket_t fd, short event, void *arg)
639 {
640         struct persist_active_timeout_called *c = arg;
641         if (c->n < 15) {
642                 c->events[c->n] = event;
643                 evutil_gettimeofday(&c->tvs[c->n], NULL);
644                 ++c->n;
645         }
646 }
647
648 static void
649 test_persistent_active_timeout(void *ptr)
650 {
651         struct timeval tv, tv2, tv_exit, start;
652         struct event ev;
653         struct persist_active_timeout_called res;
654
655         struct basic_test_data *data = ptr;
656         struct event_base *base = data->base;
657
658         memset(&res, 0, sizeof(res));
659
660         tv.tv_sec = 0;
661         tv.tv_usec = 200 * 1000;
662         event_assign(&ev, base, -1, EV_TIMEOUT|EV_PERSIST,
663             persist_active_timeout_cb, &res);
664         event_add(&ev, &tv);
665
666         tv2.tv_sec = 0;
667         tv2.tv_usec = 100 * 1000;
668         event_base_once(base, -1, EV_TIMEOUT, activate_cb, &ev, &tv2);
669
670         tv_exit.tv_sec = 0;
671         tv_exit.tv_usec = 600 * 1000;
672         event_base_loopexit(base, &tv_exit);
673
674         evutil_gettimeofday(&start, NULL);
675
676         event_base_dispatch(base);
677
678         tt_int_op(res.n, ==, 3);
679         tt_int_op(res.events[0], ==, EV_READ);
680         tt_int_op(res.events[1], ==, EV_TIMEOUT);
681         tt_int_op(res.events[2], ==, EV_TIMEOUT);
682         test_timeval_diff_eq(&start, &res.tvs[0], 100);
683         test_timeval_diff_eq(&start, &res.tvs[1], 300);
684         test_timeval_diff_eq(&start, &res.tvs[2], 500);
685 end:
686         event_del(&ev);
687 }
688
689 struct common_timeout_info {
690         struct event ev;
691         struct timeval called_at;
692         int which;
693         int count;
694 };
695
696 static void
697 common_timeout_cb(evutil_socket_t fd, short event, void *arg)
698 {
699         struct common_timeout_info *ti = arg;
700         ++ti->count;
701         evutil_gettimeofday(&ti->called_at, NULL);
702         if (ti->count >= 6)
703                 event_del(&ti->ev);
704 }
705
706 static void
707 test_common_timeout(void *ptr)
708 {
709         struct basic_test_data *data = ptr;
710
711         struct event_base *base = data->base;
712         int i;
713         struct common_timeout_info info[100];
714
715         struct timeval now;
716         struct timeval tmp_100_ms = { 0, 100*1000 };
717         struct timeval tmp_200_ms = { 0, 200*1000 };
718
719         const struct timeval *ms_100, *ms_200;
720
721         ms_100 = event_base_init_common_timeout(base, &tmp_100_ms);
722         ms_200 = event_base_init_common_timeout(base, &tmp_200_ms);
723         tt_assert(ms_100);
724         tt_assert(ms_200);
725         tt_ptr_op(event_base_init_common_timeout(base, &tmp_200_ms),
726             ==, ms_200);
727         tt_int_op(ms_100->tv_sec, ==, 0);
728         tt_int_op(ms_200->tv_sec, ==, 0);
729         tt_int_op(ms_100->tv_usec, ==, 100000|0x50000000);
730         tt_int_op(ms_200->tv_usec, ==, 200000|0x50100000);
731
732         memset(info, 0, sizeof(info));
733
734         for (i=0; i<100; ++i) {
735                 info[i].which = i;
736                 event_assign(&info[i].ev, base, -1, EV_TIMEOUT|EV_PERSIST,
737                     common_timeout_cb, &info[i]);
738                 if (i % 2) {
739                         event_add(&info[i].ev, ms_100);
740                 } else {
741                         event_add(&info[i].ev, ms_200);
742                 }
743         }
744
745         event_base_dispatch(base);
746
747         evutil_gettimeofday(&now, NULL);
748
749         for (i=0; i<10; ++i) {
750                 struct timeval tmp;
751                 int ms_diff;
752                 tt_int_op(info[i].count, ==, 6);
753                 evutil_timersub(&now, &info[i].called_at, &tmp);
754                 ms_diff = tmp.tv_usec/1000 + tmp.tv_sec*1000;
755                 if (i % 2) {
756                         tt_int_op(ms_diff, >, 500);
757                         tt_int_op(ms_diff, <, 700);
758                 } else {
759                         tt_int_op(ms_diff, >, -100);
760                         tt_int_op(ms_diff, <, 100);
761                 }
762         }
763
764         /* Make sure we can free the base with some events in. */
765         for (i=0; i<100; ++i) {
766                 if (i % 2) {
767                         event_add(&info[i].ev, ms_100);
768                 } else {
769                         event_add(&info[i].ev, ms_200);
770                 }
771         }
772
773 end:
774         event_base_free(data->base); /* need to do this here before info is
775                                       * out-of-scope */
776         data->base = NULL;
777 }
778
779 #ifndef WIN32
780 static void signal_cb(evutil_socket_t fd, short event, void *arg);
781
782 #define current_base event_global_current_base_
783 extern struct event_base *current_base;
784
785 static void
786 child_signal_cb(evutil_socket_t fd, short event, void *arg)
787 {
788         struct timeval tv;
789         int *pint = arg;
790
791         *pint = 1;
792
793         tv.tv_usec = 500000;
794         tv.tv_sec = 0;
795         event_loopexit(&tv);
796 }
797
798 static void
799 test_fork(void)
800 {
801         int status, got_sigchld = 0;
802         struct event ev, sig_ev;
803         pid_t pid;
804
805         setup_test("After fork: ");
806
807         tt_assert(current_base);
808         evthread_make_base_notifiable(current_base);
809
810         write(pair[0], TEST1, strlen(TEST1)+1);
811
812         event_set(&ev, pair[1], EV_READ, simple_read_cb, &ev);
813         if (event_add(&ev, NULL) == -1)
814                 exit(1);
815
816         evsignal_set(&sig_ev, SIGCHLD, child_signal_cb, &got_sigchld);
817         evsignal_add(&sig_ev, NULL);
818
819         if ((pid = fork()) == 0) {
820                 /* in the child */
821                 if (event_reinit(current_base) == -1) {
822                         fprintf(stdout, "FAILED (reinit)\n");
823                         exit(1);
824                 }
825
826                 evsignal_del(&sig_ev);
827
828                 called = 0;
829
830                 event_dispatch();
831
832                 event_base_free(current_base);
833
834                 /* we do not send an EOF; simple_read_cb requires an EOF
835                  * to set test_ok.  we just verify that the callback was
836                  * called. */
837                 exit(test_ok != 0 || called != 2 ? -2 : 76);
838         }
839
840         /* wait for the child to read the data */
841         sleep(1);
842
843         write(pair[0], TEST1, strlen(TEST1)+1);
844
845         if (waitpid(pid, &status, 0) == -1) {
846                 fprintf(stdout, "FAILED (fork)\n");
847                 exit(1);
848         }
849
850         if (WEXITSTATUS(status) != 76) {
851                 fprintf(stdout, "FAILED (exit): %d\n", WEXITSTATUS(status));
852                 exit(1);
853         }
854
855         /* test that the current event loop still works */
856         write(pair[0], TEST1, strlen(TEST1)+1);
857         shutdown(pair[0], SHUT_WR);
858
859         event_dispatch();
860
861         if (!got_sigchld) {
862                 fprintf(stdout, "FAILED (sigchld)\n");
863                 exit(1);
864         }
865
866         evsignal_del(&sig_ev);
867
868         end:
869         cleanup_test();
870 }
871
872 static void
873 signal_cb_sa(int sig)
874 {
875         test_ok = 2;
876 }
877
878 static void
879 signal_cb(evutil_socket_t fd, short event, void *arg)
880 {
881         struct event *ev = arg;
882
883         evsignal_del(ev);
884         test_ok = 1;
885 }
886
887 static void
888 test_simplesignal(void)
889 {
890         struct event ev;
891         struct itimerval itv;
892
893         setup_test("Simple signal: ");
894         evsignal_set(&ev, SIGALRM, signal_cb, &ev);
895         evsignal_add(&ev, NULL);
896         /* find bugs in which operations are re-ordered */
897         evsignal_del(&ev);
898         evsignal_add(&ev, NULL);
899
900         memset(&itv, 0, sizeof(itv));
901         itv.it_value.tv_sec = 1;
902         if (setitimer(ITIMER_REAL, &itv, NULL) == -1)
903                 goto skip_simplesignal;
904
905         event_dispatch();
906  skip_simplesignal:
907         if (evsignal_del(&ev) == -1)
908                 test_ok = 0;
909
910         cleanup_test();
911 }
912
913 static void
914 test_multiplesignal(void)
915 {
916         struct event ev_one, ev_two;
917         struct itimerval itv;
918
919         setup_test("Multiple signal: ");
920
921         evsignal_set(&ev_one, SIGALRM, signal_cb, &ev_one);
922         evsignal_add(&ev_one, NULL);
923
924         evsignal_set(&ev_two, SIGALRM, signal_cb, &ev_two);
925         evsignal_add(&ev_two, NULL);
926
927         memset(&itv, 0, sizeof(itv));
928         itv.it_value.tv_sec = 1;
929         if (setitimer(ITIMER_REAL, &itv, NULL) == -1)
930                 goto skip_simplesignal;
931
932         event_dispatch();
933
934  skip_simplesignal:
935         if (evsignal_del(&ev_one) == -1)
936                 test_ok = 0;
937         if (evsignal_del(&ev_two) == -1)
938                 test_ok = 0;
939
940         cleanup_test();
941 }
942
943 static void
944 test_immediatesignal(void)
945 {
946         struct event ev;
947
948         test_ok = 0;
949         evsignal_set(&ev, SIGUSR1, signal_cb, &ev);
950         evsignal_add(&ev, NULL);
951         raise(SIGUSR1);
952         event_loop(EVLOOP_NONBLOCK);
953         evsignal_del(&ev);
954         cleanup_test();
955 }
956
957 static void
958 test_signal_dealloc(void)
959 {
960         /* make sure that evsignal_event is event_del'ed and pipe closed */
961         struct event ev;
962         struct event_base *base = event_init();
963         evsignal_set(&ev, SIGUSR1, signal_cb, &ev);
964         evsignal_add(&ev, NULL);
965         evsignal_del(&ev);
966         event_base_free(base);
967         /* If we got here without asserting, we're fine. */
968         test_ok = 1;
969         cleanup_test();
970 }
971
972 static void
973 test_signal_pipeloss(void)
974 {
975         /* make sure that the base1 pipe is closed correctly. */
976         struct event_base *base1, *base2;
977         int pipe1;
978         test_ok = 0;
979         base1 = event_init();
980         pipe1 = base1->sig.ev_signal_pair[0];
981         base2 = event_init();
982         event_base_free(base2);
983         event_base_free(base1);
984         if (close(pipe1) != -1 || errno!=EBADF) {
985                 /* fd must be closed, so second close gives -1, EBADF */
986                 printf("signal pipe not closed. ");
987                 test_ok = 0;
988         } else {
989                 test_ok = 1;
990         }
991         cleanup_test();
992 }
993
994 /*
995  * make two bases to catch signals, use both of them.  this only works
996  * for event mechanisms that use our signal pipe trick.  kqueue handles
997  * signals internally, and all interested kqueues get all the signals.
998  */
999 static void
1000 test_signal_switchbase(void)
1001 {
1002         struct event ev1, ev2;
1003         struct event_base *base1, *base2;
1004         int is_kqueue;
1005         test_ok = 0;
1006         base1 = event_init();
1007         base2 = event_init();
1008         is_kqueue = !strcmp(event_get_method(),"kqueue");
1009         evsignal_set(&ev1, SIGUSR1, signal_cb, &ev1);
1010         evsignal_set(&ev2, SIGUSR1, signal_cb, &ev2);
1011         if (event_base_set(base1, &ev1) ||
1012             event_base_set(base2, &ev2) ||
1013             event_add(&ev1, NULL) ||
1014             event_add(&ev2, NULL)) {
1015                 fprintf(stderr, "%s: cannot set base, add\n", __func__);
1016                 exit(1);
1017         }
1018
1019         tt_ptr_op(event_get_base(&ev1), ==, base1);
1020         tt_ptr_op(event_get_base(&ev2), ==, base2);
1021
1022         test_ok = 0;
1023         /* can handle signal before loop is called */
1024         raise(SIGUSR1);
1025         event_base_loop(base2, EVLOOP_NONBLOCK);
1026         if (is_kqueue) {
1027                 if (!test_ok)
1028                         goto end;
1029                 test_ok = 0;
1030         }
1031         event_base_loop(base1, EVLOOP_NONBLOCK);
1032         if (test_ok && !is_kqueue) {
1033                 test_ok = 0;
1034
1035                 /* set base1 to handle signals */
1036                 event_base_loop(base1, EVLOOP_NONBLOCK);
1037                 raise(SIGUSR1);
1038                 event_base_loop(base1, EVLOOP_NONBLOCK);
1039                 event_base_loop(base2, EVLOOP_NONBLOCK);
1040         }
1041 end:
1042         event_base_free(base1);
1043         event_base_free(base2);
1044         cleanup_test();
1045 }
1046
1047 /*
1048  * assert that a signal event removed from the event queue really is
1049  * removed - with no possibility of it's parent handler being fired.
1050  */
1051 static void
1052 test_signal_assert(void)
1053 {
1054         struct event ev;
1055         struct event_base *base = event_init();
1056         test_ok = 0;
1057         /* use SIGCONT so we don't kill ourselves when we signal to nowhere */
1058         evsignal_set(&ev, SIGCONT, signal_cb, &ev);
1059         evsignal_add(&ev, NULL);
1060         /*
1061          * if evsignal_del() fails to reset the handler, it's current handler
1062          * will still point to evsig_handler().
1063          */
1064         evsignal_del(&ev);
1065
1066         raise(SIGCONT);
1067 #if 0
1068         /* only way to verify we were in evsig_handler() */
1069         /* XXXX Now there's no longer a good way. */
1070         if (base->sig.evsig_caught)
1071                 test_ok = 0;
1072         else
1073                 test_ok = 1;
1074 #else
1075         test_ok = 1;
1076 #endif
1077
1078         event_base_free(base);
1079         cleanup_test();
1080         return;
1081 }
1082
1083 /*
1084  * assert that we restore our previous signal handler properly.
1085  */
1086 static void
1087 test_signal_restore(void)
1088 {
1089         struct event ev;
1090         struct event_base *base = event_init();
1091 #ifdef _EVENT_HAVE_SIGACTION
1092         struct sigaction sa;
1093 #endif
1094
1095         test_ok = 0;
1096 #ifdef _EVENT_HAVE_SIGACTION
1097         sa.sa_handler = signal_cb_sa;
1098         sa.sa_flags = 0x0;
1099         sigemptyset(&sa.sa_mask);
1100         if (sigaction(SIGUSR1, &sa, NULL) == -1)
1101                 goto out;
1102 #else
1103         if (signal(SIGUSR1, signal_cb_sa) == SIG_ERR)
1104                 goto out;
1105 #endif
1106         evsignal_set(&ev, SIGUSR1, signal_cb, &ev);
1107         evsignal_add(&ev, NULL);
1108         evsignal_del(&ev);
1109
1110         raise(SIGUSR1);
1111         /* 1 == signal_cb, 2 == signal_cb_sa, we want our previous handler */
1112         if (test_ok != 2)
1113                 test_ok = 0;
1114 out:
1115         event_base_free(base);
1116         cleanup_test();
1117         return;
1118 }
1119
1120 static void
1121 signal_cb_swp(int sig, short event, void *arg)
1122 {
1123         called++;
1124         if (called < 5)
1125                 raise(sig);
1126         else
1127                 event_loopexit(NULL);
1128 }
1129 static void
1130 timeout_cb_swp(evutil_socket_t fd, short event, void *arg)
1131 {
1132         if (called == -1) {
1133                 struct timeval tv = {5, 0};
1134
1135                 called = 0;
1136                 evtimer_add((struct event *)arg, &tv);
1137                 raise(SIGUSR1);
1138                 return;
1139         }
1140         test_ok = 0;
1141         event_loopexit(NULL);
1142 }
1143
1144 static void
1145 test_signal_while_processing(void)
1146 {
1147         struct event_base *base = event_init();
1148         struct event ev, ev_timer;
1149         struct timeval tv = {0, 0};
1150
1151         setup_test("Receiving a signal while processing other signal: ");
1152
1153         called = -1;
1154         test_ok = 1;
1155         signal_set(&ev, SIGUSR1, signal_cb_swp, NULL);
1156         signal_add(&ev, NULL);
1157         evtimer_set(&ev_timer, timeout_cb_swp, &ev_timer);
1158         evtimer_add(&ev_timer, &tv);
1159         event_dispatch();
1160
1161         event_base_free(base);
1162         cleanup_test();
1163         return;
1164 }
1165 #endif
1166
1167 static void
1168 test_free_active_base(void *ptr)
1169 {
1170         struct basic_test_data *data = ptr;
1171         struct event_base *base1;
1172         struct event ev1;
1173
1174         base1 = event_init();
1175         if (base1) {
1176                 event_assign(&ev1, base1, data->pair[1], EV_READ,
1177                              dummy_read_cb, NULL);
1178                 event_add(&ev1, NULL);
1179                 event_base_free(base1);  /* should not crash */
1180         } else {
1181                 tt_fail_msg("failed to create event_base for test");
1182         }
1183
1184         base1 = event_init();
1185         tt_assert(base1);
1186         event_assign(&ev1, base1, 0, 0, dummy_read_cb, NULL);
1187         event_active(&ev1, EV_READ, 1);
1188         event_base_free(base1);
1189 end:
1190         ;
1191 }
1192
1193 static void
1194 test_manipulate_active_events(void *ptr)
1195 {
1196         struct basic_test_data *data = ptr;
1197         struct event_base *base = data->base;
1198         struct event ev1;
1199
1200         event_assign(&ev1, base, -1, EV_TIMEOUT, dummy_read_cb, NULL);
1201
1202         /* Make sure an active event is pending. */
1203         event_active(&ev1, EV_READ, 1);
1204         tt_int_op(event_pending(&ev1, EV_READ|EV_TIMEOUT|EV_WRITE, NULL),
1205             ==, EV_READ);
1206
1207         /* Make sure that activating an event twice works. */
1208         event_active(&ev1, EV_WRITE, 1);
1209         tt_int_op(event_pending(&ev1, EV_READ|EV_TIMEOUT|EV_WRITE, NULL),
1210             ==, EV_READ|EV_WRITE);
1211
1212 end:
1213         event_del(&ev1);
1214 }
1215
1216 static void
1217 test_bad_assign(void *ptr)
1218 {
1219         struct event ev;
1220         int r;
1221         /* READ|SIGNAL is not allowed */
1222         r = event_assign(&ev, NULL, -1, EV_SIGNAL|EV_READ, dummy_read_cb, NULL);
1223         tt_int_op(r,==,-1);
1224
1225 end:
1226         ;
1227 }
1228
1229 static int reentrant_cb_run = 0;
1230
1231 static void
1232 bad_reentrant_run_loop_cb(evutil_socket_t fd, short what, void *ptr)
1233 {
1234         struct event_base *base = ptr;
1235         int r;
1236         reentrant_cb_run = 1;
1237         /* This reentrant call to event_base_loop should be detected and
1238          * should fail */
1239         r = event_base_loop(base, 0);
1240         tt_int_op(r, ==, -1);
1241 end:
1242         ;
1243 }
1244
1245 static void
1246 test_bad_reentrant(void *ptr)
1247 {
1248         struct basic_test_data *data = ptr;
1249         struct event_base *base = data->base;
1250         struct event ev;
1251         int r;
1252         event_assign(&ev, base, -1,
1253             0, bad_reentrant_run_loop_cb, base);
1254
1255         event_active(&ev, EV_WRITE, 1);
1256         r = event_base_loop(base, 0);
1257         tt_int_op(r, ==, 1);
1258         tt_int_op(reentrant_cb_run, ==, 1);
1259 end:
1260         ;
1261 }
1262
1263 static void
1264 test_event_base_new(void *ptr)
1265 {
1266         struct basic_test_data *data = ptr;
1267         struct event_base *base = 0;
1268         struct event ev1;
1269         struct basic_cb_args args;
1270
1271         int towrite = (int)strlen(TEST1)+1;
1272         int len = write(data->pair[0], TEST1, towrite);
1273
1274         if (len < 0)
1275                 tt_abort_perror("initial write");
1276         else if (len != towrite)
1277                 tt_abort_printf(("initial write fell short (%d of %d bytes)",
1278                                  len, towrite));
1279
1280         if (shutdown(data->pair[0], SHUT_WR))
1281                 tt_abort_perror("initial write shutdown");
1282
1283         base = event_base_new();
1284         if (!base)
1285                 tt_abort_msg("failed to create event base");
1286
1287         args.eb = base;
1288         args.ev = &ev1;
1289         args.callcount = 0;
1290         event_assign(&ev1, base, data->pair[1],
1291                      EV_READ|EV_PERSIST, basic_read_cb, &args);
1292
1293         if (event_add(&ev1, NULL))
1294                 tt_abort_perror("initial event_add");
1295
1296         if (event_base_loop(base, 0))
1297                 tt_abort_msg("unsuccessful exit from event loop");
1298
1299 end:
1300         if (base)
1301                 event_base_free(base);
1302 }
1303
1304 static void
1305 test_loopexit(void)
1306 {
1307         struct timeval tv, tv_start, tv_end;
1308         struct event ev;
1309
1310         setup_test("Loop exit: ");
1311
1312         tv.tv_usec = 0;
1313         tv.tv_sec = 60*60*24;
1314         evtimer_set(&ev, timeout_cb, NULL);
1315         evtimer_add(&ev, &tv);
1316
1317         tv.tv_usec = 0;
1318         tv.tv_sec = 1;
1319         event_loopexit(&tv);
1320
1321         evutil_gettimeofday(&tv_start, NULL);
1322         event_dispatch();
1323         evutil_gettimeofday(&tv_end, NULL);
1324         evutil_timersub(&tv_end, &tv_start, &tv_end);
1325
1326         evtimer_del(&ev);
1327
1328         tt_assert(event_base_got_exit(global_base));
1329         tt_assert(!event_base_got_break(global_base));
1330
1331         if (tv.tv_sec < 2)
1332                 test_ok = 1;
1333
1334 end:
1335         cleanup_test();
1336 }
1337
1338 static void
1339 test_loopexit_multiple(void)
1340 {
1341         struct timeval tv;
1342         struct event_base *base;
1343
1344         setup_test("Loop Multiple exit: ");
1345
1346         base = event_base_new();
1347
1348         tv.tv_usec = 0;
1349         tv.tv_sec = 1;
1350         event_base_loopexit(base, &tv);
1351
1352         tv.tv_usec = 0;
1353         tv.tv_sec = 2;
1354         event_base_loopexit(base, &tv);
1355
1356         event_base_dispatch(base);
1357
1358         tt_assert(event_base_got_exit(base));
1359         tt_assert(!event_base_got_break(base));
1360
1361         event_base_free(base);
1362
1363         test_ok = 1;
1364
1365 end:
1366         cleanup_test();
1367 }
1368
1369 static void
1370 break_cb(evutil_socket_t fd, short events, void *arg)
1371 {
1372         test_ok = 1;
1373         event_loopbreak();
1374 }
1375
1376 static void
1377 fail_cb(evutil_socket_t fd, short events, void *arg)
1378 {
1379         test_ok = 0;
1380 }
1381
1382 static void
1383 test_loopbreak(void)
1384 {
1385         struct event ev1, ev2;
1386         struct timeval tv;
1387
1388         setup_test("Loop break: ");
1389
1390         tv.tv_sec = 0;
1391         tv.tv_usec = 0;
1392         evtimer_set(&ev1, break_cb, NULL);
1393         evtimer_add(&ev1, &tv);
1394         evtimer_set(&ev2, fail_cb, NULL);
1395         evtimer_add(&ev2, &tv);
1396
1397         event_dispatch();
1398
1399         tt_assert(!event_base_got_exit(global_base));
1400         tt_assert(event_base_got_break(global_base));
1401
1402         evtimer_del(&ev1);
1403         evtimer_del(&ev2);
1404
1405 end:
1406         cleanup_test();
1407 }
1408
1409 static struct event *readd_test_event_last_added = NULL;
1410 static void
1411 re_add_read_cb(evutil_socket_t fd, short event, void *arg)
1412 {
1413         char buf[256];
1414         struct event *ev_other = arg;
1415         readd_test_event_last_added = ev_other;
1416         (void) read(fd, buf, sizeof(buf));
1417         event_add(ev_other, NULL);
1418         ++test_ok;
1419 }
1420
1421 static void
1422 test_nonpersist_readd(void)
1423 {
1424         struct event ev1, ev2;
1425
1426         setup_test("Re-add nonpersistent events: ");
1427         event_set(&ev1, pair[0], EV_READ, re_add_read_cb, &ev2);
1428         event_set(&ev2, pair[1], EV_READ, re_add_read_cb, &ev1);
1429         (void) write(pair[0], "Hello", 5);
1430         (void) write(pair[1], "Hello", 5);
1431         if (event_add(&ev1, NULL) == -1 ||
1432             event_add(&ev2, NULL) == -1) {
1433                 test_ok = 0;
1434         }
1435         if (test_ok != 0)
1436                 exit(1);
1437         event_loop(EVLOOP_ONCE);
1438         if (test_ok != 2)
1439                 exit(1);
1440         /* At this point, we executed both callbacks.  Whichever one got
1441          * called first added the second, but the second then immediately got
1442          * deleted before its callback was called.  At this point, though, it
1443          * re-added the first.
1444          */
1445         if (!readd_test_event_last_added) {
1446                 test_ok = 0;
1447         } else if (readd_test_event_last_added == &ev1) {
1448                 if (!event_pending(&ev1, EV_READ, NULL) ||
1449                     event_pending(&ev2, EV_READ, NULL))
1450                         test_ok = 0;
1451         } else {
1452                 if (event_pending(&ev1, EV_READ, NULL) ||
1453                     !event_pending(&ev2, EV_READ, NULL))
1454                         test_ok = 0;
1455         }
1456
1457         event_del(&ev1);
1458         event_del(&ev2);
1459
1460         cleanup_test();
1461 }
1462
1463 struct test_pri_event {
1464         struct event ev;
1465         int count;
1466 };
1467
1468 static void
1469 test_priorities_cb(evutil_socket_t fd, short what, void *arg)
1470 {
1471         struct test_pri_event *pri = arg;
1472         struct timeval tv;
1473
1474         if (pri->count == 3) {
1475                 event_loopexit(NULL);
1476                 return;
1477         }
1478
1479         pri->count++;
1480
1481         evutil_timerclear(&tv);
1482         event_add(&pri->ev, &tv);
1483 }
1484
1485 static void
1486 test_priorities_impl(int npriorities)
1487 {
1488         struct test_pri_event one, two;
1489         struct timeval tv;
1490
1491         TT_BLATHER(("Testing Priorities %d: ", npriorities));
1492
1493         event_base_priority_init(global_base, npriorities);
1494
1495         memset(&one, 0, sizeof(one));
1496         memset(&two, 0, sizeof(two));
1497
1498         timeout_set(&one.ev, test_priorities_cb, &one);
1499         if (event_priority_set(&one.ev, 0) == -1) {
1500                 fprintf(stderr, "%s: failed to set priority", __func__);
1501                 exit(1);
1502         }
1503
1504         timeout_set(&two.ev, test_priorities_cb, &two);
1505         if (event_priority_set(&two.ev, npriorities - 1) == -1) {
1506                 fprintf(stderr, "%s: failed to set priority", __func__);
1507                 exit(1);
1508         }
1509
1510         evutil_timerclear(&tv);
1511
1512         if (event_add(&one.ev, &tv) == -1)
1513                 exit(1);
1514         if (event_add(&two.ev, &tv) == -1)
1515                 exit(1);
1516
1517         event_dispatch();
1518
1519         event_del(&one.ev);
1520         event_del(&two.ev);
1521
1522         if (npriorities == 1) {
1523                 if (one.count == 3 && two.count == 3)
1524                         test_ok = 1;
1525         } else if (npriorities == 2) {
1526                 /* Two is called once because event_loopexit is priority 1 */
1527                 if (one.count == 3 && two.count == 1)
1528                         test_ok = 1;
1529         } else {
1530                 if (one.count == 3 && two.count == 0)
1531                         test_ok = 1;
1532         }
1533 }
1534
1535 static void
1536 test_priorities(void)
1537 {
1538         test_priorities_impl(1);
1539         if (test_ok)
1540                 test_priorities_impl(2);
1541         if (test_ok)
1542                 test_priorities_impl(3);
1543 }
1544
1545
1546 static void
1547 test_multiple_cb(evutil_socket_t fd, short event, void *arg)
1548 {
1549         if (event & EV_READ)
1550                 test_ok |= 1;
1551         else if (event & EV_WRITE)
1552                 test_ok |= 2;
1553 }
1554
1555 static void
1556 test_multiple_events_for_same_fd(void)
1557 {
1558    struct event e1, e2;
1559
1560    setup_test("Multiple events for same fd: ");
1561
1562    event_set(&e1, pair[0], EV_READ, test_multiple_cb, NULL);
1563    event_add(&e1, NULL);
1564    event_set(&e2, pair[0], EV_WRITE, test_multiple_cb, NULL);
1565    event_add(&e2, NULL);
1566    event_loop(EVLOOP_ONCE);
1567    event_del(&e2);
1568    write(pair[1], TEST1, strlen(TEST1)+1);
1569    event_loop(EVLOOP_ONCE);
1570    event_del(&e1);
1571
1572    if (test_ok != 3)
1573            test_ok = 0;
1574
1575    cleanup_test();
1576 }
1577
1578 int evtag_decode_int(ev_uint32_t *pnumber, struct evbuffer *evbuf);
1579 int evtag_decode_int64(ev_uint64_t *pnumber, struct evbuffer *evbuf);
1580 int evtag_encode_tag(struct evbuffer *evbuf, ev_uint32_t number);
1581 int evtag_decode_tag(ev_uint32_t *pnumber, struct evbuffer *evbuf);
1582
1583 static void
1584 read_once_cb(evutil_socket_t fd, short event, void *arg)
1585 {
1586         char buf[256];
1587         int len;
1588
1589         len = read(fd, buf, sizeof(buf));
1590
1591         if (called) {
1592                 test_ok = 0;
1593         } else if (len) {
1594                 /* Assumes global pair[0] can be used for writing */
1595                 write(pair[0], TEST1, strlen(TEST1)+1);
1596                 test_ok = 1;
1597         }
1598
1599         called++;
1600 }
1601
1602 static void
1603 test_want_only_once(void)
1604 {
1605         struct event ev;
1606         struct timeval tv;
1607
1608         /* Very simple read test */
1609         setup_test("Want read only once: ");
1610
1611         write(pair[0], TEST1, strlen(TEST1)+1);
1612
1613         /* Setup the loop termination */
1614         evutil_timerclear(&tv);
1615         tv.tv_sec = 1;
1616         event_loopexit(&tv);
1617
1618         event_set(&ev, pair[1], EV_READ, read_once_cb, &ev);
1619         if (event_add(&ev, NULL) == -1)
1620                 exit(1);
1621         event_dispatch();
1622
1623         cleanup_test();
1624 }
1625
1626 #define TEST_MAX_INT    6
1627
1628 static void
1629 evtag_int_test(void *ptr)
1630 {
1631         struct evbuffer *tmp = evbuffer_new();
1632         ev_uint32_t integers[TEST_MAX_INT] = {
1633                 0xaf0, 0x1000, 0x1, 0xdeadbeef, 0x00, 0xbef000
1634         };
1635         ev_uint32_t integer;
1636         ev_uint64_t big_int;
1637         int i;
1638
1639         evtag_init();
1640
1641         for (i = 0; i < TEST_MAX_INT; i++) {
1642                 int oldlen, newlen;
1643                 oldlen = (int)EVBUFFER_LENGTH(tmp);
1644                 evtag_encode_int(tmp, integers[i]);
1645                 newlen = (int)EVBUFFER_LENGTH(tmp);
1646                 TT_BLATHER(("encoded 0x%08x with %d bytes",
1647                         (unsigned)integers[i], newlen - oldlen));
1648                 big_int = integers[i];
1649                 big_int *= 1000000000; /* 1 billion */
1650                 evtag_encode_int64(tmp, big_int);
1651         }
1652
1653         for (i = 0; i < TEST_MAX_INT; i++) {
1654                 tt_int_op(evtag_decode_int(&integer, tmp), !=, -1);
1655                 tt_uint_op(integer, ==, integers[i]);
1656                 tt_int_op(evtag_decode_int64(&big_int, tmp), !=, -1);
1657                 tt_assert((big_int / 1000000000) == integers[i]);
1658         }
1659
1660         tt_uint_op(EVBUFFER_LENGTH(tmp), ==, 0);
1661 end:
1662         evbuffer_free(tmp);
1663 }
1664
1665 static void
1666 evtag_fuzz(void *ptr)
1667 {
1668         u_char buffer[4096];
1669         struct evbuffer *tmp = evbuffer_new();
1670         struct timeval tv;
1671         int i, j;
1672
1673         int not_failed = 0;
1674
1675         evtag_init();
1676
1677         for (j = 0; j < 100; j++) {
1678                 for (i = 0; i < (int)sizeof(buffer); i++)
1679                         buffer[i] = rand();
1680                 evbuffer_drain(tmp, -1);
1681                 evbuffer_add(tmp, buffer, sizeof(buffer));
1682
1683                 if (evtag_unmarshal_timeval(tmp, 0, &tv) != -1)
1684                         not_failed++;
1685         }
1686
1687         /* The majority of decodes should fail */
1688         tt_int_op(not_failed, <, 10);
1689
1690         /* Now insert some corruption into the tag length field */
1691         evbuffer_drain(tmp, -1);
1692         evutil_timerclear(&tv);
1693         tv.tv_sec = 1;
1694         evtag_marshal_timeval(tmp, 0, &tv);
1695         evbuffer_add(tmp, buffer, sizeof(buffer));
1696
1697         ((char *)EVBUFFER_DATA(tmp))[1] = '\xff';
1698         if (evtag_unmarshal_timeval(tmp, 0, &tv) != -1) {
1699                 tt_abort_msg("evtag_unmarshal_timeval should have failed");
1700         }
1701
1702 end:
1703         evbuffer_free(tmp);
1704 }
1705
1706 static void
1707 evtag_tag_encoding(void *ptr)
1708 {
1709         struct evbuffer *tmp = evbuffer_new();
1710         ev_uint32_t integers[TEST_MAX_INT] = {
1711                 0xaf0, 0x1000, 0x1, 0xdeadbeef, 0x00, 0xbef000
1712         };
1713         ev_uint32_t integer;
1714         int i;
1715
1716         evtag_init();
1717
1718         for (i = 0; i < TEST_MAX_INT; i++) {
1719                 int oldlen, newlen;
1720                 oldlen = (int)EVBUFFER_LENGTH(tmp);
1721                 evtag_encode_tag(tmp, integers[i]);
1722                 newlen = (int)EVBUFFER_LENGTH(tmp);
1723                 TT_BLATHER(("encoded 0x%08x with %d bytes",
1724                         (unsigned)integers[i], newlen - oldlen));
1725         }
1726
1727         for (i = 0; i < TEST_MAX_INT; i++) {
1728                 tt_int_op(evtag_decode_tag(&integer, tmp), !=, -1);
1729                 tt_uint_op(integer, ==, integers[i]);
1730         }
1731
1732         tt_uint_op(EVBUFFER_LENGTH(tmp), ==, 0);
1733
1734 end:
1735         evbuffer_free(tmp);
1736 }
1737
1738 static void
1739 evtag_test_peek(void *ptr)
1740 {
1741         struct evbuffer *tmp = evbuffer_new();
1742         ev_uint32_t u32;
1743
1744         evtag_marshal_int(tmp, 30, 0);
1745         evtag_marshal_string(tmp, 40, "Hello world");
1746
1747         tt_int_op(evtag_peek(tmp, &u32), ==, 1);
1748         tt_int_op(u32, ==, 30);
1749         tt_int_op(evtag_peek_length(tmp, &u32), ==, 0);
1750         tt_int_op(u32, ==, 1+1+1);
1751         tt_int_op(evtag_consume(tmp), ==, 0);
1752
1753         tt_int_op(evtag_peek(tmp, &u32), ==, 1);
1754         tt_int_op(u32, ==, 40);
1755         tt_int_op(evtag_peek_length(tmp, &u32), ==, 0);
1756         tt_int_op(u32, ==, 1+1+11);
1757         tt_int_op(evtag_payload_length(tmp, &u32), ==, 0);
1758         tt_int_op(u32, ==, 11);
1759
1760 end:
1761         evbuffer_free(tmp);
1762 }
1763
1764
1765 static void
1766 test_methods(void *ptr)
1767 {
1768         const char **methods = event_get_supported_methods();
1769         struct event_config *cfg = NULL;
1770         struct event_base *base = NULL;
1771         const char *backend;
1772         int n_methods = 0;
1773
1774         tt_assert(methods);
1775
1776         backend = methods[0];
1777         while (*methods != NULL) {
1778                 TT_BLATHER(("Support method: %s", *methods));
1779                 ++methods;
1780                 ++n_methods;
1781         }
1782
1783         cfg = event_config_new();
1784         assert(cfg != NULL);
1785
1786         tt_int_op(event_config_avoid_method(cfg, backend), ==, 0);
1787         event_config_set_flag(cfg, EVENT_BASE_FLAG_IGNORE_ENV);
1788
1789         base = event_base_new_with_config(cfg);
1790         if (n_methods > 1) {
1791                 tt_assert(base);
1792                 tt_str_op(backend, !=, event_base_get_method(base));
1793         } else {
1794                 tt_assert(base == NULL);
1795         }
1796
1797 end:
1798         if (base)
1799                 event_base_free(base);
1800         if (cfg)
1801                 event_config_free(cfg);
1802 }
1803
1804 static void
1805 test_version(void *arg)
1806 {
1807         const char *vstr;
1808         ev_uint32_t vint;
1809         int major, minor, patch, n;
1810
1811         vstr = event_get_version();
1812         vint = event_get_version_number();
1813
1814         tt_assert(vstr);
1815         tt_assert(vint);
1816
1817         tt_str_op(vstr, ==, LIBEVENT_VERSION);
1818         tt_int_op(vint, ==, LIBEVENT_VERSION_NUMBER);
1819
1820         n = sscanf(vstr, "%d.%d.%d", &major, &minor, &patch);
1821         tt_assert(3 == n);
1822         tt_int_op((vint&0xffffff00), ==, ((major<<24)|(minor<<16)|(patch<<8)));
1823 end:
1824         ;
1825 }
1826
1827 static void
1828 test_base_features(void *arg)
1829 {
1830         struct event_base *base = NULL;
1831         struct event_config *cfg = NULL;
1832
1833         cfg = event_config_new();
1834
1835         tt_assert(0 == event_config_require_features(cfg, EV_FEATURE_ET));
1836
1837         base = event_base_new_with_config(cfg);
1838         if (base) {
1839                 tt_int_op(EV_FEATURE_ET, ==,
1840                     event_base_get_features(base) & EV_FEATURE_ET);
1841         } else {
1842                 base = event_base_new();
1843                 tt_int_op(0, ==, event_base_get_features(base) & EV_FEATURE_ET);
1844         }
1845
1846 end:
1847         if (base)
1848                 event_base_free(base);
1849         if (cfg)
1850                 event_config_free(cfg);
1851 }
1852
1853 #ifdef _EVENT_HAVE_SETENV
1854 #define SETENV_OK
1855 #elif !defined(_EVENT_HAVE_SETENV) && defined(_EVENT_HAVE_PUTENV)
1856 static void setenv(const char *k, const char *v, int _o)
1857 {
1858         char b[256];
1859         evutil_snprintf(b, sizeof(b), "%s=%s",k,v);
1860         putenv(b);
1861 }
1862 #define SETENV_OK
1863 #endif
1864
1865 #ifdef _EVENT_HAVE_UNSETENV
1866 #define UNSETENV_OK
1867 #elif !defined(_EVENT_HAVE_UNSETENV) && defined(_EVENT_HAVE_PUTENV)
1868 static void unsetenv(const char *k)
1869 {
1870         char b[256];
1871         evutil_snprintf(b, sizeof(b), "%s=",k);
1872         putenv(b);
1873 }
1874 #define UNSETENV_OK
1875 #endif
1876
1877 #if defined(SETENV_OK) && defined(UNSETENV_OK)
1878 static void
1879 methodname_to_envvar(const char *mname, char *buf, size_t buflen)
1880 {
1881         char *cp;
1882         evutil_snprintf(buf, buflen, "EVENT_NO%s", mname);
1883         for (cp = buf; *cp; ++cp) {
1884                 *cp = EVUTIL_TOUPPER(*cp);
1885         }
1886 }
1887 #endif
1888
1889 static void
1890 test_base_environ(void *arg)
1891 {
1892         struct event_base *base = NULL;
1893         struct event_config *cfg = NULL;
1894
1895 #if defined(SETENV_OK) && defined(UNSETENV_OK)
1896         const char **basenames;
1897         int i, n_methods=0;
1898         char varbuf[128];
1899         const char *defaultname, *ignoreenvname;
1900
1901         /* See if unsetenv works before we rely on it. */
1902         setenv("EVENT_NOWAFFLES", "1", 1);
1903         unsetenv("EVENT_NOWAFFLES");
1904         if (getenv("EVENT_NOWAFFLES") != NULL) {
1905 #ifndef _EVENT_HAVE_UNSETENV
1906                 TT_DECLARE("NOTE", ("Can't fake unsetenv; skipping test"));
1907 #else
1908                 TT_DECLARE("NOTE", ("unsetenv doesn't work; skipping test"));
1909 #endif
1910                 tt_skip();
1911         }
1912
1913         basenames = event_get_supported_methods();
1914         for (i = 0; basenames[i]; ++i) {
1915                 methodname_to_envvar(basenames[i], varbuf, sizeof(varbuf));
1916                 unsetenv(varbuf);
1917                 ++n_methods;
1918         }
1919
1920         base = event_base_new();
1921         tt_assert(base);
1922
1923         defaultname = event_base_get_method(base);
1924         TT_BLATHER(("default is <%s>", defaultname));
1925         event_base_free(base);
1926         base = NULL;
1927
1928         /* Can we disable the method with EVENT_NOfoo ? */
1929         if (!strcmp(defaultname, "epoll (with changelist)")) {
1930                 setenv("EVENT_NOEPOLL", "1", 1);
1931                 ignoreenvname = "epoll";
1932         } else {
1933                 methodname_to_envvar(defaultname, varbuf, sizeof(varbuf));
1934                 setenv(varbuf, "1", 1);
1935                 ignoreenvname = defaultname;
1936         }
1937
1938         /* Use an empty cfg rather than NULL so a failure doesn't exit() */
1939         cfg = event_config_new();
1940         base = event_base_new_with_config(cfg);
1941         event_config_free(cfg);
1942         cfg = NULL;
1943         if (n_methods == 1) {
1944                 tt_assert(!base);
1945         } else {
1946                 tt_assert(base);
1947                 tt_str_op(defaultname, !=, event_base_get_method(base));
1948                 event_base_free(base);
1949                 base = NULL;
1950         }
1951
1952         /* Can we disable looking at the environment with IGNORE_ENV ? */
1953         cfg = event_config_new();
1954         event_config_set_flag(cfg, EVENT_BASE_FLAG_IGNORE_ENV);
1955         base = event_base_new_with_config(cfg);
1956         tt_assert(base);
1957         tt_str_op(ignoreenvname, ==, event_base_get_method(base));
1958 #else
1959         tt_skip();
1960 #endif
1961
1962 end:
1963         if (base)
1964                 event_base_free(base);
1965         if (cfg)
1966                 event_config_free(cfg);
1967 }
1968
1969 static void
1970 read_called_once_cb(evutil_socket_t fd, short event, void *arg)
1971 {
1972         tt_int_op(event, ==, EV_READ);
1973         called += 1;
1974 end:
1975         ;
1976 }
1977
1978 static void
1979 timeout_called_once_cb(evutil_socket_t fd, short event, void *arg)
1980 {
1981         tt_int_op(event, ==, EV_TIMEOUT);
1982         called += 100;
1983 end:
1984         ;
1985 }
1986
1987 static void
1988 test_event_once(void *ptr)
1989 {
1990         struct basic_test_data *data = ptr;
1991         struct timeval tv;
1992         int r;
1993
1994         tv.tv_sec = 0;
1995         tv.tv_usec = 50*1000;
1996         called = 0;
1997         r = event_base_once(data->base, data->pair[0], EV_READ,
1998             read_called_once_cb, NULL, NULL);
1999         tt_int_op(r, ==, 0);
2000         r = event_base_once(data->base, -1, EV_TIMEOUT,
2001             timeout_called_once_cb, NULL, &tv);
2002         tt_int_op(r, ==, 0);
2003         r = event_base_once(data->base, -1, 0, NULL, NULL, NULL);
2004         tt_int_op(r, <, 0);
2005
2006         write(data->pair[1], TEST1, strlen(TEST1)+1);
2007         shutdown(data->pair[1], SHUT_WR);
2008
2009         event_base_dispatch(data->base);
2010
2011         tt_int_op(called, ==, 101);
2012 end:
2013         ;
2014 }
2015
2016 static void
2017 test_event_pending(void *ptr)
2018 {
2019         struct basic_test_data *data = ptr;
2020         struct event *r=NULL, *w=NULL, *t=NULL;
2021         struct timeval tv, now, tv2, diff;
2022
2023         tv.tv_sec = 0;
2024         tv.tv_usec = 500 * 1000;
2025         r = event_new(data->base, data->pair[0], EV_READ, simple_read_cb,
2026             NULL);
2027         w = event_new(data->base, data->pair[1], EV_WRITE, simple_write_cb,
2028             NULL);
2029         t = evtimer_new(data->base, timeout_cb, NULL);
2030
2031         evutil_gettimeofday(&now, NULL);
2032         event_add(r, NULL);
2033         event_add(t, &tv);
2034
2035         tt_assert( event_pending(r, EV_READ, NULL));
2036         tt_assert(!event_pending(w, EV_WRITE, NULL));
2037         tt_assert(!event_pending(r, EV_WRITE, NULL));
2038         tt_assert( event_pending(r, EV_READ|EV_WRITE, NULL));
2039         tt_assert(!event_pending(r, EV_TIMEOUT, NULL));
2040         tt_assert( event_pending(t, EV_TIMEOUT, NULL));
2041         tt_assert( event_pending(t, EV_TIMEOUT, &tv2));
2042
2043         tt_assert(evutil_timercmp(&tv2, &now, >));
2044         evutil_timeradd(&now, &tv, &tv);
2045         evutil_timersub(&tv2, &tv, &diff);
2046         tt_int_op(diff.tv_sec, ==, 0);
2047         tt_int_op(labs(diff.tv_usec), <, 1000);
2048
2049 end:
2050         if (r) {
2051                 event_del(r);
2052                 event_free(r);
2053         }
2054         if (w) {
2055                 event_del(w);
2056                 event_free(w);
2057         }
2058         if (t) {
2059                 event_del(t);
2060                 event_free(t);
2061         }
2062 }
2063
2064 #ifndef WIN32
2065 /* You can't do this test on windows, since dup2 doesn't work on sockets */
2066
2067 static void
2068 dfd_cb(evutil_socket_t fd, short e, void *data)
2069 {
2070         *(int*)data = (int)e;
2071 }
2072
2073 /* Regression test for our workaround for a fun epoll/linux related bug
2074  * where fd2 = dup(fd1); add(fd2); close(fd2); dup2(fd1,fd2); add(fd2)
2075  * will get you an EEXIST */
2076 static void
2077 test_dup_fd(void *arg)
2078 {
2079         struct basic_test_data *data = arg;
2080         struct event_base *base = data->base;
2081         struct event *ev1=NULL, *ev2=NULL;
2082         int fd, dfd=-1;
2083         int ev1_got, ev2_got;
2084
2085         tt_int_op(write(data->pair[0], "Hello world",
2086                 strlen("Hello world")), >, 0);
2087         fd = data->pair[1];
2088
2089         dfd = dup(fd);
2090         tt_int_op(dfd, >=, 0);
2091
2092         ev1 = event_new(base, fd, EV_READ|EV_PERSIST, dfd_cb, &ev1_got);
2093         ev2 = event_new(base, dfd, EV_READ|EV_PERSIST, dfd_cb, &ev2_got);
2094         ev1_got = ev2_got = 0;
2095         event_add(ev1, NULL);
2096         event_add(ev2, NULL);
2097         event_base_loop(base, EVLOOP_ONCE);
2098         tt_int_op(ev1_got, ==, EV_READ);
2099         tt_int_op(ev2_got, ==, EV_READ);
2100
2101         /* Now close and delete dfd then dispatch.  We need to do the
2102          * dispatch here so that when we add it later, we think there
2103          * was an intermediate delete. */
2104         close(dfd);
2105         event_del(ev2);
2106         ev1_got = ev2_got = 0;
2107         event_base_loop(base, EVLOOP_ONCE);
2108         tt_want_int_op(ev1_got, ==, EV_READ);
2109         tt_int_op(ev2_got, ==, 0);
2110
2111         /* Re-duplicate the fd.  We need to get the same duplicated
2112          * value that we closed to provoke the epoll quirk.  Also, we
2113          * need to change the events to write, or else the old lingering
2114          * read event will make the test pass whether the change was
2115          * successful or not. */
2116         tt_int_op(dup2(fd, dfd), ==, dfd);
2117         event_free(ev2);
2118         ev2 = event_new(base, dfd, EV_WRITE|EV_PERSIST, dfd_cb, &ev2_got);
2119         event_add(ev2, NULL);
2120         ev1_got = ev2_got = 0;
2121         event_base_loop(base, EVLOOP_ONCE);
2122         tt_want_int_op(ev1_got, ==, EV_READ);
2123         tt_int_op(ev2_got, ==, EV_WRITE);
2124
2125 end:
2126         if (ev1)
2127                 event_free(ev1);
2128         if (ev2)
2129                 event_free(ev2);
2130         close(dfd);
2131 }
2132 #endif
2133
2134 #ifdef _EVENT_DISABLE_MM_REPLACEMENT
2135 static void
2136 test_mm_functions(void *arg)
2137 {
2138         _tinytest_set_test_skipped();
2139 }
2140 #else
2141 static int
2142 check_dummy_mem_ok(void *_mem)
2143 {
2144         char *mem = _mem;
2145         mem -= 16;
2146         return !memcmp(mem, "{[<guardedram>]}", 16);
2147 }
2148
2149 static void *
2150 dummy_malloc(size_t len)
2151 {
2152         char *mem = malloc(len+16);
2153         memcpy(mem, "{[<guardedram>]}", 16);
2154         return mem+16;
2155 }
2156
2157 static void *
2158 dummy_realloc(void *_mem, size_t len)
2159 {
2160         char *mem = _mem;
2161         if (!mem)
2162                 return dummy_malloc(len);
2163         tt_want(check_dummy_mem_ok(_mem));
2164         mem -= 16;
2165         mem = realloc(mem, len+16);
2166         return mem+16;
2167 }
2168
2169 static void
2170 dummy_free(void *_mem)
2171 {
2172         char *mem = _mem;
2173         tt_want(check_dummy_mem_ok(_mem));
2174         mem -= 16;
2175         free(mem);
2176 }
2177
2178 static void
2179 test_mm_functions(void *arg)
2180 {
2181         struct event_base *b = NULL;
2182         struct event_config *cfg = NULL;
2183         event_set_mem_functions(dummy_malloc, dummy_realloc, dummy_free);
2184         cfg = event_config_new();
2185         event_config_avoid_method(cfg, "Nonesuch");
2186         b = event_base_new_with_config(cfg);
2187         tt_assert(b);
2188         tt_assert(check_dummy_mem_ok(b));
2189 end:
2190         if (cfg)
2191                 event_config_free(cfg);
2192         if (b)
2193                 event_base_free(b);
2194 }
2195 #endif
2196
2197 static void
2198 many_event_cb(evutil_socket_t fd, short event, void *arg)
2199 {
2200         int *calledp = arg;
2201         *calledp += 1;
2202 }
2203
2204 static void
2205 test_many_events(void *arg)
2206 {
2207         /* Try 70 events that should all be aready at once.  This will
2208          * exercise the "resize" code on most of the backends, and will make
2209          * sure that we can get past the 64-handle limit of some windows
2210          * functions. */
2211 #define MANY 70
2212
2213         struct basic_test_data *data = arg;
2214         struct event_base *base = data->base;
2215         evutil_socket_t sock[MANY];
2216         struct event *ev[MANY];
2217         int called[MANY];
2218         int i;
2219
2220         memset(sock, 0xff, sizeof(sock));
2221         memset(ev, 0, sizeof(ev));
2222         memset(called, 0, sizeof(called));
2223
2224         for (i = 0; i < MANY; ++i) {
2225                 /* We need an event that will hit the backend, and that will
2226                  * be ready immediately.  "Send a datagram" is an easy
2227                  * instance of that. */
2228                 sock[i] = socket(AF_INET, SOCK_DGRAM, 0);
2229                 tt_assert(sock[i] >= 0);
2230                 called[i] = 0;
2231                 ev[i] = event_new(base, sock[i], EV_WRITE, many_event_cb,
2232                     &called[i]);
2233                 event_add(ev[i], NULL);
2234         }
2235
2236         event_base_loop(base, EVLOOP_NONBLOCK);
2237
2238         for (i = 0; i < MANY; ++i) {
2239                 tt_int_op(called[i], ==, 1);
2240         }
2241
2242 end:
2243         for (i = 0; i < MANY; ++i) {
2244                 if (ev[i])
2245                         event_free(ev[i]);
2246                 if (sock[i] >= 0)
2247                         evutil_closesocket(sock[i]);
2248         }
2249 #undef MANY
2250 }
2251
2252 static void
2253 test_struct_event_size(void *arg)
2254 {
2255         tt_int_op(event_get_struct_event_size(), <=, sizeof(struct event));
2256 end:
2257         ;
2258 }
2259
2260 struct testcase_t main_testcases[] = {
2261         /* Some converted-over tests */
2262         { "methods", test_methods, TT_FORK, NULL, NULL },
2263         { "version", test_version, 0, NULL, NULL },
2264         BASIC(base_features, TT_FORK|TT_NO_LOGS),
2265         { "base_environ", test_base_environ, TT_FORK, NULL, NULL },
2266
2267         BASIC(event_base_new, TT_FORK|TT_NEED_SOCKETPAIR),
2268         BASIC(free_active_base, TT_FORK|TT_NEED_SOCKETPAIR),
2269
2270         BASIC(manipulate_active_events, TT_FORK|TT_NEED_BASE),
2271
2272         BASIC(bad_assign, TT_FORK|TT_NEED_BASE|TT_NO_LOGS),
2273         BASIC(bad_reentrant, TT_FORK|TT_NEED_BASE|TT_NO_LOGS),
2274
2275         /* These are still using the old API */
2276         LEGACY(persistent_timeout, TT_FORK|TT_NEED_BASE),
2277         { "persistent_active_timeout", test_persistent_active_timeout,
2278           TT_FORK|TT_NEED_BASE, &basic_setup, NULL },
2279         LEGACY(priorities, TT_FORK|TT_NEED_BASE),
2280         { "common_timeout", test_common_timeout, TT_FORK|TT_NEED_BASE,
2281           &basic_setup, NULL },
2282
2283         /* These legacy tests may not all need all of these flags. */
2284         LEGACY(simpleread, TT_ISOLATED),
2285         LEGACY(simpleread_multiple, TT_ISOLATED),
2286         LEGACY(simplewrite, TT_ISOLATED),
2287         { "simpleclose", test_simpleclose, TT_FORK, &basic_setup,
2288           NULL },
2289         LEGACY(multiple, TT_ISOLATED),
2290         LEGACY(persistent, TT_ISOLATED),
2291         LEGACY(combined, TT_ISOLATED),
2292         LEGACY(simpletimeout, TT_ISOLATED),
2293         LEGACY(loopbreak, TT_ISOLATED),
2294         LEGACY(loopexit, TT_ISOLATED),
2295         LEGACY(loopexit_multiple, TT_ISOLATED),
2296         LEGACY(nonpersist_readd, TT_ISOLATED),
2297         LEGACY(multiple_events_for_same_fd, TT_ISOLATED),
2298         LEGACY(want_only_once, TT_ISOLATED),
2299         { "event_once", test_event_once, TT_ISOLATED, &basic_setup, NULL },
2300         { "event_pending", test_event_pending, TT_ISOLATED, &basic_setup,
2301           NULL },
2302 #ifndef WIN32
2303         { "dup_fd", test_dup_fd, TT_ISOLATED, &basic_setup, NULL },
2304 #endif
2305         { "mm_functions", test_mm_functions, TT_FORK, NULL, NULL },
2306         BASIC(many_events, TT_ISOLATED),
2307
2308         { "struct_event_size", test_struct_event_size, 0, NULL, NULL },
2309
2310 #ifndef WIN32
2311         LEGACY(fork, TT_ISOLATED),
2312 #endif
2313         END_OF_TESTCASES
2314 };
2315
2316 struct testcase_t evtag_testcases[] = {
2317         { "int", evtag_int_test, TT_FORK, NULL, NULL },
2318         { "fuzz", evtag_fuzz, TT_FORK, NULL, NULL },
2319         { "encoding", evtag_tag_encoding, TT_FORK, NULL, NULL },
2320         { "peek", evtag_test_peek, 0, NULL, NULL },
2321
2322         END_OF_TESTCASES
2323 };
2324
2325 struct testcase_t signal_testcases[] = {
2326 #ifndef WIN32
2327         LEGACY(simplesignal, TT_ISOLATED),
2328         LEGACY(multiplesignal, TT_ISOLATED),
2329         LEGACY(immediatesignal, TT_ISOLATED),
2330         LEGACY(signal_dealloc, TT_ISOLATED),
2331         LEGACY(signal_pipeloss, TT_ISOLATED),
2332         LEGACY(signal_switchbase, TT_ISOLATED|TT_NO_LOGS),
2333         LEGACY(signal_restore, TT_ISOLATED),
2334         LEGACY(signal_assert, TT_ISOLATED),
2335         LEGACY(signal_while_processing, TT_ISOLATED),
2336 #endif
2337         END_OF_TESTCASES
2338 };
2339