Convert and expand free_active_base/event_base_new tests to avoid dbl-free. Patch from Zack Weinberg

svn:r1342
This commit is contained in:
Nick Mathewson 2009-07-14 18:49:42 +00:00
parent 6b4b77a265
commit e224321c64
2 changed files with 96 additions and 27 deletions

View File

@ -99,6 +99,13 @@ static struct timeval tcalled;
#define read(fd,buf,len) recv((fd),(buf),(len),0)
#endif
struct basic_cb_args
{
struct event_base *eb;
struct event *ev;
unsigned int callcount;
};
static void
simple_read_cb(int fd, short event, void *arg)
{
@ -118,6 +125,45 @@ simple_read_cb(int fd, short event, void *arg)
called++;
}
static void
basic_read_cb(int fd, short event, void *data)
{
char buf[256];
int len;
struct basic_cb_args *arg = data;
len = read(fd, buf, sizeof(buf));
if (len < 0) {
tt_fail_perror("read (callback)");
} else {
switch (arg->callcount++) {
case 0: /* first call: expect to read data; cycle */
if (len > 0)
return;
tt_fail_msg("EOF before data read");
break;
case 1: /* second call: expect EOF; stop */
if (len > 0)
tt_fail_msg("not all data read on first cycle");
break;
default: /* third call: should not happen */
tt_fail_msg("too many cycles");
}
}
event_del(arg->ev);
event_base_loopexit(arg->eb, NULL);
}
static void
dummy_read_cb(int fd, short event, void *arg)
{
}
static void
simple_write_cb(int fd, short event, void *arg)
{
@ -893,43 +939,62 @@ test_signal_while_processing(void)
#endif
static void
test_free_active_base(void)
test_free_active_base(void *ptr)
{
struct basic_test_data *data = ptr;
struct event_base *base1;
struct event ev1;
setup_test("Free active base: ");
base1 = event_init();
event_set(&ev1, pair[1], EV_READ, simple_read_cb, &ev1);
event_base_set(base1, &ev1);
event_add(&ev1, NULL);
/* event_del(&ev1); */
event_base_free(base1);
test_ok = 1;
cleanup_test();
event_base_free(global_base);
global_base = event_init();
if (base1) {
struct event ev1;
event_assign(&ev1, base1, data->pair[1], EV_READ,
dummy_read_cb, NULL);
event_add(&ev1, NULL);
event_base_free(base1); /* should not crash */
} else {
tt_fail_msg("failed to create event_base for test");
}
}
static void
test_event_base_new(void)
test_event_base_new(void *ptr)
{
struct event_base *base;
struct basic_test_data *data = ptr;
struct event_base *base = 0;
struct event ev1;
setup_test("Event base new: ");
struct basic_cb_args args;
write(pair[0], TEST1, strlen(TEST1)+1);
shutdown(pair[0], SHUT_WR);
int towrite = strlen(TEST1)+1;
int len = write(data->pair[0], TEST1, towrite);
if (len < 0)
tt_abort_perror("initial write");
else if (len != towrite)
tt_abort_printf(("initial write fell short (%d of %d bytes)",
len, towrite));
if (shutdown(data->pair[0], SHUT_WR))
tt_abort_perror("initial write shutdown");
base = event_base_new();
event_set(&ev1, pair[1], EV_READ, simple_read_cb, &ev1);
event_base_set(base, &ev1);
event_add(&ev1, NULL);
if (!base)
tt_abort_msg("failed to create event base");
event_base_dispatch(base);
args.eb = base;
args.ev = &ev1;
args.callcount = 0;
event_assign(&ev1, base, data->pair[1],
EV_READ|EV_PERSIST, basic_read_cb, &args);
event_base_free(base);
test_ok = 1;
cleanup_test();
if (event_add(&ev1, NULL))
tt_abort_perror("initial event_add");
if (event_base_loop(base, 0))
tt_abort_msg("unsuccessful exit from event loop");
end:
if (base)
event_base_free(base);
}
static void
@ -1484,6 +1549,7 @@ test_base_environ(void *arg)
tt_assert(base);
defaultname = event_base_get_method(base);
TT_BLATHER(("default is <%s>", defaultname));
event_base_free(base);
base = NULL;
@ -1676,13 +1742,13 @@ struct testcase_t main_testcases[] = {
{ "base_features", test_base_features, TT_FORK, NULL, NULL },
{ "base_environ", test_base_environ, TT_FORK, NULL, NULL },
BASIC(event_base_new, TT_FORK|TT_NEED_SOCKETPAIR),
BASIC(free_active_base, TT_FORK|TT_NEED_SOCKETPAIR),
/* These are still using the old API */
LEGACY(persistent_timeout, TT_FORK|TT_NEED_BASE),
LEGACY(priorities, TT_FORK|TT_NEED_BASE),
LEGACY(free_active_base, TT_FORK|TT_NEED_BASE|TT_NEED_SOCKETPAIR),
LEGACY(event_base_new, TT_FORK|TT_NEED_SOCKETPAIR),
/* These legacy tests may not all need all of these flags. */
LEGACY(simpleread, TT_ISOLATED),
LEGACY(simpleread_multiple, TT_ISOLATED),

View File

@ -79,6 +79,9 @@ 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 }
#define LEGACY(name,flags) \
{ #name, run_legacy_test_fn, flags|TT_LEGACY, &legacy_setup, \
test_## name }