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.
This commit is contained in:
Nick Mathewson 2010-02-23 23:55:32 -05:00
parent c02bfe12f8
commit 8fcb7a1b04
3 changed files with 81 additions and 0 deletions

View File

@ -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 },

View File

@ -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
}

View File

@ -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().