mirror of
https://github.com/cuberite/libevent.git
synced 2025-09-15 15:25:09 -04:00
Add a stress test for getaddrinfo_cancel
This commit is contained in:
parent
d51b2fc655
commit
da1bf52811
@ -1543,6 +1543,136 @@ end:
|
||||
evdns_base_free(dns_base, 0);
|
||||
}
|
||||
|
||||
struct gaic_request_status {
|
||||
int magic;
|
||||
struct event_base *base;
|
||||
struct evdns_base *dns_base;
|
||||
struct evdns_getaddrinfo_request *request;
|
||||
struct event cancel_event;
|
||||
int canceled;
|
||||
};
|
||||
|
||||
#define GAIC_MAGIC 0x1234abcd
|
||||
|
||||
static int pending = 0;
|
||||
|
||||
static void
|
||||
gaic_cancel_request_cb(evutil_socket_t fd, short what, void *arg)
|
||||
{
|
||||
struct gaic_request_status *status = arg;
|
||||
|
||||
tt_assert(status->magic == GAIC_MAGIC);
|
||||
status->canceled = 1;
|
||||
evdns_getaddrinfo_cancel(status->request);
|
||||
return;
|
||||
end:
|
||||
event_base_loopexit(status->base, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gaic_server_cb(struct evdns_server_request *req, void *arg)
|
||||
{
|
||||
ev_uint32_t answer = 0x7f000001;
|
||||
tt_assert(req->nquestions);
|
||||
evdns_server_request_add_a_reply(req, req->questions[0]->name, 1,
|
||||
&answer, 100);
|
||||
evdns_server_request_respond(req, 0);
|
||||
return;
|
||||
end:
|
||||
evdns_server_request_respond(req, DNS_ERR_REFUSED);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gaic_getaddrinfo_cb(int result, struct evutil_addrinfo *res, void *arg)
|
||||
{
|
||||
struct gaic_request_status *status = arg;
|
||||
struct event_base *base = status->base;
|
||||
tt_assert(status->magic == GAIC_MAGIC);
|
||||
|
||||
if (result == EVUTIL_EAI_CANCEL) {
|
||||
tt_assert(status->canceled);
|
||||
}
|
||||
event_del(&status->cancel_event);
|
||||
|
||||
memset(status, 0xf0, sizeof(*status));
|
||||
free(status);
|
||||
|
||||
end:
|
||||
if (--pending <= 0)
|
||||
event_base_loopexit(base, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gaic_launch(struct event_base *base, struct evdns_base *dns_base)
|
||||
{
|
||||
struct gaic_request_status *status = calloc(1,sizeof(*status));
|
||||
struct timeval tv = { 0, 10000 };
|
||||
status->magic = GAIC_MAGIC;
|
||||
status->base = base;
|
||||
status->dns_base = dns_base;
|
||||
event_assign(&status->cancel_event, base, -1, 0, gaic_cancel_request_cb,
|
||||
status);
|
||||
status->request = evdns_getaddrinfo(dns_base,
|
||||
"foobar.bazquux.example.com", "80", NULL, gaic_getaddrinfo_cb,
|
||||
status);
|
||||
event_add(&status->cancel_event, &tv);
|
||||
++pending;
|
||||
}
|
||||
|
||||
static void
|
||||
test_getaddrinfo_async_cancel_stress(void *arg)
|
||||
{
|
||||
struct basic_test_data *data = arg;
|
||||
struct event_base *base = data->base;
|
||||
struct evdns_base *dns_base = NULL;
|
||||
struct evdns_server_port *server = NULL;
|
||||
evutil_socket_t fd = -1;
|
||||
struct sockaddr_in sin;
|
||||
struct sockaddr_storage ss;
|
||||
ev_socklen_t slen;
|
||||
int i;
|
||||
|
||||
base = event_base_new();
|
||||
dns_base = evdns_base_new(base, 0);
|
||||
|
||||
memset(&sin, 0, sizeof(sin));
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_port = 0;
|
||||
sin.sin_addr.s_addr = htonl(0x7f000001);
|
||||
if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
|
||||
tt_abort_perror("socket");
|
||||
}
|
||||
evutil_make_socket_nonblocking(fd);
|
||||
if (bind(fd, (struct sockaddr*)&sin, sizeof(sin))<0) {
|
||||
tt_abort_perror("bind");
|
||||
}
|
||||
server = evdns_add_server_port_with_base(base, fd, 0, gaic_server_cb,
|
||||
base);
|
||||
|
||||
memset(&ss, 0, sizeof(ss));
|
||||
slen = sizeof(ss);
|
||||
if (getsockname(fd, (struct sockaddr*)&ss, &slen)<0) {
|
||||
tt_abort_perror("getsockname");
|
||||
}
|
||||
evdns_base_nameserver_sockaddr_add(dns_base,
|
||||
(struct sockaddr*)&ss, slen, 0);
|
||||
|
||||
for (i = 0; i < 1000; ++i) {
|
||||
gaic_launch(base, dns_base);
|
||||
}
|
||||
|
||||
event_base_dispatch(base);
|
||||
|
||||
end:
|
||||
if (dns_base)
|
||||
evdns_base_free(dns_base, 1);
|
||||
if (server)
|
||||
evdns_close_server_port(server);
|
||||
if (fd >= 0)
|
||||
evutil_closesocket(fd);
|
||||
}
|
||||
|
||||
|
||||
#define DNS_LEGACY(name, flags) \
|
||||
{ #name, run_legacy_test_fn, flags|TT_LEGACY, &legacy_setup, \
|
||||
@ -1565,6 +1695,8 @@ struct testcase_t dns_testcases[] = {
|
||||
|
||||
{ "getaddrinfo_async", test_getaddrinfo_async,
|
||||
TT_FORK|TT_NEED_BASE, &basic_setup, (char*)"" },
|
||||
{ "getaddrinfo_cancel_stress", test_getaddrinfo_async_cancel_stress,
|
||||
TT_FORK|TT_NEED_BASE, &basic_setup, (char*)"" },
|
||||
|
||||
END_OF_TESTCASES
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user