Skip to content

Commit f7841bf

Browse files
darkknmathewson
authored andcommitted
Test for commit aff6ba1
1 parent 21a08d6 commit f7841bf

File tree

1 file changed

+116
-0
lines changed

1 file changed

+116
-0
lines changed

test/regress_dns.c

+116
Original file line numberDiff line numberDiff line change
@@ -1637,6 +1637,119 @@ gaic_launch(struct event_base *base, struct evdns_base *dns_base)
16371637
++pending;
16381638
}
16391639

1640+
static int allocated_chunks = 0;
1641+
1642+
static void*
1643+
cnt_malloc(size_t sz)
1644+
{
1645+
allocated_chunks += 1;
1646+
return malloc(sz);
1647+
}
1648+
1649+
static void*
1650+
cnt_realloc(void *old, size_t sz)
1651+
{
1652+
if (!old)
1653+
allocated_chunks += 1;
1654+
if (!sz)
1655+
allocated_chunks -= 1;
1656+
return realloc(old, sz);
1657+
}
1658+
1659+
static void
1660+
cnt_free(void *ptr)
1661+
{
1662+
allocated_chunks -= 1;
1663+
return free(ptr);
1664+
}
1665+
1666+
struct testleak_env_t {
1667+
struct event_base* base;
1668+
struct evdns_base* dns_base;
1669+
struct evdns_request* req;
1670+
struct generic_dns_callback_result r;
1671+
};
1672+
1673+
static void*
1674+
testleak_setup(const struct testcase_t *testcase)
1675+
{
1676+
struct testleak_env_t* env;
1677+
1678+
allocated_chunks = 0;
1679+
event_set_mem_functions(cnt_malloc, cnt_realloc, cnt_free);
1680+
event_enable_debug_mode();
1681+
1682+
env = calloc(1, sizeof(struct testleak_env_t));
1683+
env->base = event_base_new();
1684+
env->dns_base = evdns_base_new(env->base, 0);
1685+
env->req = evdns_base_resolve_ipv4(
1686+
env->dns_base, "example.com", DNS_QUERY_NO_SEARCH,
1687+
generic_dns_callback, &env->r);
1688+
return env;
1689+
}
1690+
1691+
static int
1692+
testleak_cleanup(const struct testcase_t *testcase, void *env_)
1693+
{
1694+
int ok = 0;
1695+
struct testleak_env_t* env = env_;
1696+
/* FIXME: that's `1' because of event_debug_map_HT_GROW */
1697+
tt_int_op(allocated_chunks, ==, 1);
1698+
ok = 1;
1699+
end:
1700+
if (env->dns_base)
1701+
evdns_base_free(env->dns_base, 0);
1702+
if (env->base)
1703+
event_base_free(env->base);
1704+
if (env)
1705+
free(env);
1706+
return ok;
1707+
}
1708+
1709+
static struct testcase_setup_t testleak_funcs = {
1710+
testleak_setup, testleak_cleanup
1711+
};
1712+
1713+
static void
1714+
test_dbg_leak_cancel(void *env_)
1715+
{
1716+
/* cancel, loop, free/dns, free/base */
1717+
struct testleak_env_t* env = env_;
1718+
int send_err_shutdown = 1;
1719+
evdns_cancel_request(env->dns_base, env->req);
1720+
env->req = 0;
1721+
1722+
/* `req` is freed in callback, that's why one loop is required. */
1723+
event_base_loop(env->base, EVLOOP_NONBLOCK);
1724+
1725+
/* send_err_shutdown means nothing as soon as our request is
1726+
* already canceled */
1727+
evdns_base_free(env->dns_base, send_err_shutdown);
1728+
env->dns_base = 0;
1729+
event_base_free(env->base);
1730+
env->base = 0;
1731+
}
1732+
1733+
static void
1734+
test_dbg_leak_shutdown(void *env_)
1735+
{
1736+
/* free/dns, loop, free/base */
1737+
struct testleak_env_t* env = env_;
1738+
int send_err_shutdown = 1;
1739+
1740+
/* `req` is freed both with `send_err_shutdown` and without it,
1741+
* the only difference is `evdns_callback` call */
1742+
env->req = 0;
1743+
1744+
evdns_base_free(env->dns_base, send_err_shutdown);
1745+
env->dns_base = 0;
1746+
1747+
/* `req` is freed in callback, that's why one loop is required */
1748+
event_base_loop(env->base, EVLOOP_NONBLOCK);
1749+
event_base_free(env->base);
1750+
env->base = 0;
1751+
}
1752+
16401753
static void
16411754
test_getaddrinfo_async_cancel_stress(void *ptr)
16421755
{
@@ -1714,6 +1827,9 @@ struct testcase_t dns_testcases[] = {
17141827
{ "getaddrinfo_cancel_stress", test_getaddrinfo_async_cancel_stress,
17151828
TT_FORK, NULL, NULL },
17161829

1830+
{ "leak_shutdown", test_dbg_leak_shutdown, TT_FORK, &testleak_funcs, NULL },
1831+
{ "leak_cancel", test_dbg_leak_cancel, TT_FORK, &testleak_funcs, NULL },
1832+
17171833
END_OF_TESTCASES
17181834
};
17191835

0 commit comments

Comments
 (0)