]> granicus.if.org Git - libevent/commitdiff
Add a "many events" regression test.
authorNick Mathewson <nickm@torproject.org>
Fri, 30 Oct 2009 22:43:30 +0000 (22:43 +0000)
committerNick Mathewson <nickm@torproject.org>
Fri, 30 Oct 2009 22:43:30 +0000 (22:43 +0000)
This is a glass-box test to get more coverage on the event loop
backends.  We've run into bugs here before with fencepost errors, and
it turns out that none of our unit tests had enough events to
exercise the resize code.

Most of the backends have some kind of logic that resizes an array
when:
    - The highest fd is too high
    - The number of events added since the last iteration of the loop
      is too high
    - The number of active events is too high.

This test hits all 3 cases, and increases coverage in select.c by 7%,
in poll by 1%, and in kqueue by 9%.

svn:r1482

test/regress.c

index b34bb7444b1d7572f35e8374652d026b23844352..c5927b70879f6b1b5b1d2246ac56014718d45258 100644 (file)
@@ -1812,6 +1812,59 @@ end:
                event_base_free(b);
 }
 
+static void
+many_event_cb(int fd, short event, void *arg)
+{
+       int *calledp = arg;
+       *calledp += 1;
+}
+
+static void
+test_many_events(void *arg)
+{
+       /* Try 64 events that should all be aready at once.  This will
+        * exercise the "resize" code on most of the backends. */
+#define MANY 64
+
+       struct basic_test_data *data = arg;
+       struct event_base *base = data->base;
+       evutil_socket_t sock[MANY];
+       struct event *ev[MANY];
+       int called[MANY];
+       int i;
+
+       memset(sock, 0xff, sizeof(sock));
+       memset(ev, 0, sizeof(ev));
+       memset(called, 0, sizeof(called));
+
+       for (i = 0; i < MANY; ++i) {
+               /* We need an event that will hit the backend, and that will
+                * be ready immediately.  "Send a datagram" is an easy
+                * instance of that. */
+               sock[i] = socket(AF_INET, SOCK_DGRAM, 0);
+               tt_assert(sock[i] >= 0);
+               called[i] = 0;
+               ev[i] = event_new(base, sock[i], EV_WRITE, many_event_cb,
+                   &called[i]);
+               event_add(ev[i], NULL);
+       }
+
+       event_base_loop(base, EVLOOP_NONBLOCK);
+
+       for (i = 0; i < MANY; ++i) {
+               tt_int_op(called[i], ==, 1);
+       }
+
+end:
+       for (i = 0; i < MANY; ++i) {
+               if (ev[i])
+                       event_free(ev[i]);
+               if (sock[i] >= 0)
+                       EVUTIL_CLOSESOCKET(sock[i]);
+       }
+#undef MANY
+}
+
 struct testcase_t main_testcases[] = {
         /* Some converted-over tests */
         { "methods", test_methods, TT_FORK, NULL, NULL },
@@ -1848,6 +1901,7 @@ struct testcase_t main_testcases[] = {
        { "event_pending", test_event_pending, TT_ISOLATED, &basic_setup,
          NULL },
        { "mm_functions", test_mm_functions, TT_FORK, NULL, NULL },
+       BASIC(many_events, TT_ISOLATED),
 
 #ifndef WIN32
         LEGACY(fork, TT_ISOLATED),