From: Nick Mathewson Date: Wed, 24 Feb 2010 04:55:32 +0000 (-0500) Subject: Add test for periodic timers that get activated for other reasons X-Git-Tag: release-2.0.4-alpha~10 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8fcb7a1b0419b275bd1570044f0e2024723fe4dd;p=libevent Add test for periodic timers that get activated for other reasons This was already independently verified by the new bufferevent timeout tests, but it's good to explicitly check that our code does what it should. --- diff --git a/test/regress.c b/test/regress.c index 0f4a6876..3afe2e66 100644 --- a/test/regress.c +++ b/test/regress.c @@ -549,6 +549,71 @@ test_persistent_timeout(void) event_del(&ev); } +struct persist_active_timeout_called { + int n; + short events[16]; + struct timeval tvs[16]; +}; + +static void +activate_cb(int fd, short event, void *arg) +{ + struct event *ev = arg; + event_active(ev, EV_READ, 1); +} + +static void +persist_active_timeout_cb(int fd, short event, void *arg) +{ + struct persist_active_timeout_called *c = arg; + if (c->n < 15) { + c->events[c->n] = event; + evutil_gettimeofday(&c->tvs[c->n], NULL); + ++c->n; + } +} + +static void +test_persistent_active_timeout(void *ptr) +{ + struct timeval tv, tv2, tv_exit, start; + struct event ev; + struct persist_active_timeout_called res; + + struct basic_test_data *data = ptr; + struct event_base *base = data->base; + + memset(&res, 0, sizeof(res)); + + tv.tv_sec = 0; + tv.tv_usec = 200 * 1000; + event_assign(&ev, base, -1, EV_TIMEOUT|EV_PERSIST, + persist_active_timeout_cb, &res); + event_add(&ev, &tv); + + tv2.tv_sec = 0; + tv2.tv_usec = 100 * 1000; + event_base_once(base, -1, EV_TIMEOUT, activate_cb, &ev, &tv2); + + tv_exit.tv_sec = 0; + tv_exit.tv_usec = 600 * 1000; + event_base_loopexit(base, &tv_exit); + + evutil_gettimeofday(&start, NULL); + + event_base_dispatch(base); + + tt_int_op(res.n, ==, 3); + tt_int_op(res.events[0], ==, EV_READ); + tt_int_op(res.events[1], ==, EV_TIMEOUT); + tt_int_op(res.events[2], ==, EV_TIMEOUT); + test_timeval_diff_eq(&start, &res.tvs[0], 100); + test_timeval_diff_eq(&start, &res.tvs[1], 300); + test_timeval_diff_eq(&start, &res.tvs[2], 500); +end: + ; +} + static int total_common_counts; struct common_timeout_info { @@ -2006,6 +2071,8 @@ struct testcase_t main_testcases[] = { /* These are still using the old API */ LEGACY(persistent_timeout, TT_FORK|TT_NEED_BASE), + { "persistent_active_timeout", test_persistent_active_timeout, + TT_FORK|TT_NEED_BASE, &basic_setup, NULL }, LEGACY(priorities, TT_FORK|TT_NEED_BASE), { "common_timeout", test_common_timeout, TT_FORK|TT_NEED_BASE, &basic_setup, NULL }, diff --git a/test/regress.h b/test/regress.h index 6ebff89e..8a20225c 100644 --- a/test/regress.h +++ b/test/regress.h @@ -90,6 +90,7 @@ void run_legacy_test_fn(void *ptr); /* All the flags that a legacy test needs. */ #define TT_ISOLATED TT_FORK|TT_NEED_SOCKETPAIR|TT_NEED_BASE + #define BASIC(name,flags) \ { #name, test_## name, flags, &basic_setup, NULL } @@ -108,6 +109,10 @@ int _test_ai_eq(const struct evutil_addrinfo *ai, const char *sockaddr_port, goto end; \ } while(0) +#define test_timeval_diff_eq(tv1, tv2, diff) \ + tt_int_op(abs(timeval_msec_diff((tv1), (tv2)) - diff), <=, 30) + +long timeval_msec_diff(const struct timeval *start, const struct timeval *end); #ifdef __cplusplus } diff --git a/test/regress_main.c b/test/regress_main.c index 4e733e18..1ba73f2b 100644 --- a/test/regress_main.c +++ b/test/regress_main.c @@ -76,6 +76,15 @@ #include "tinytest_macros.h" #include "../iocp-internal.h" +long +timeval_msec_diff(const struct timeval *start, const struct timeval *end) +{ + long ms = end->tv_sec - start->tv_sec; + ms *= 1000; + ms += ((end->tv_usec - start->tv_usec)+500) / 1000; + return ms; + +} /* ============================================================ */ /* Code to wrap up old legacy test cases that used setup() and cleanup().