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