[asterisk-commits] mmichelson: branch group/dns r432509 - /team/group/dns/tests/test_dns.c
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Thu Mar 5 16:04:47 CST 2015
Author: mmichelson
Date: Thu Mar 5 16:04:46 2015
New Revision: 432509
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=432509
Log:
Add nominal synchronous and asynchronous tests.
These tests do a bare-bones synchronous and asynchronous
resolution to be sure the resolver is called into as expected.
Modified:
team/group/dns/tests/test_dns.c
Modified: team/group/dns/tests/test_dns.c
URL: http://svnview.digium.com/svn/asterisk/team/group/dns/tests/test_dns.c?view=diff&rev=432509&r1=432508&r2=432509
==============================================================================
--- team/group/dns/tests/test_dns.c (original)
+++ team/group/dns/tests/test_dns.c Thu Mar 5 16:04:46 2015
@@ -587,6 +587,235 @@
return AST_TEST_PASS;
}
+static struct resolver_data {
+ int resolve_called;
+ int cancel_called;
+ int resolution_complete;
+} test_resolver_data;
+
+static void *resolution_thread(void *dns_query)
+{
+ struct ast_dns_query *query = dns_query;
+
+ static const char *V4 = "127.0.0.1";
+ static const size_t V4_BUFSIZE = sizeof(struct in_addr);
+ char v4_buf[V4_BUFSIZE];
+
+ ast_dns_resolver_set_result(query, 0, 0, 0, 0, "asterisk.org");
+
+ inet_pton(AF_INET, V4, v4_buf);
+
+ ast_dns_resolver_add_record(query, ns_t_a, ns_c_in, 12345, v4_buf, V4_BUFSIZE);
+ test_resolver_data.resolution_complete = 1;
+ ast_dns_resolver_completed(query);
+
+ ao2_ref(query, -1);
+ return NULL;
+}
+
+static int test_resolve(struct ast_dns_query *query)
+{
+ pthread_t resolver_thread;
+
+ test_resolver_data.resolve_called = 1;
+ return ast_pthread_create_detached(&resolver_thread, NULL, resolution_thread, ao2_bump(query));
+}
+
+static int test_cancel(struct ast_dns_query *query)
+{
+ test_resolver_data.cancel_called = 1;
+ return 0;
+}
+
+static void resolver_data_init(void)
+{
+ test_resolver_data.resolve_called = 0;
+ test_resolver_data.cancel_called = 0;
+ test_resolver_data.resolution_complete = 0;
+}
+
+static struct ast_dns_resolver test_resolver = {
+ .name = "test",
+ .priority = 0,
+ .resolve = test_resolve,
+ .cancel = test_cancel,
+};
+
+AST_TEST_DEFINE(resolver_resolve_sync)
+{
+ RAII_VAR(struct ast_dns_result *, result, NULL, ast_dns_result_free);
+ enum ast_test_result_state res = AST_TEST_PASS;
+
+ switch (cmd) {
+ case TEST_INIT:
+ info->name = "resolver_resolve_sync";
+ info->category = "/main/dns/";
+ info->summary = "Test a nominal synchronous DNS resolution";
+ info->description =
+ "This test performs a synchronous DNS resolution of a domain. The goal of this\n"
+ "test is not to check the records for accuracy. Rather, the goal is to ensure that\n"
+ "the resolver is called into as expected, that the query completes entirely before\n"
+ "returning from the synchronous resolution, and to ensure that nothing tried to\n"
+ "cancel the resolution.";
+ return AST_TEST_NOT_RUN;
+ case TEST_EXECUTE:
+ break;
+ }
+
+ if (ast_dns_resolver_register(&test_resolver)) {
+ ast_test_status_update(test, "Unable to register test resolver\n");
+ return AST_TEST_FAIL;
+ }
+
+ resolver_data_init();
+
+ if (ast_dns_resolve("asterisk.org", ns_t_a, ns_c_in, &result)) {
+ ast_test_status_update(test, "Resolution of address failed\n");
+ res = AST_TEST_FAIL;
+ goto cleanup;
+ }
+
+ if (!result) {
+ ast_test_status_update(test, "DNS resolution returned a NULL result\n");
+ res = AST_TEST_FAIL;
+ goto cleanup;
+ }
+
+ if (!test_resolver_data.resolve_called) {
+ ast_test_status_update(test, "DNS resolution did not call resolver's resolve() method\n");
+ res = AST_TEST_FAIL;
+ goto cleanup;
+ }
+
+ if (test_resolver_data.cancel_called) {
+ ast_test_status_update(test, "Resolver's cancel() method called for no reason\n");
+ res = AST_TEST_FAIL;
+ goto cleanup;
+ }
+
+ if (!test_resolver_data.resolution_complete) {
+ ast_test_status_update(test, "Synchronous resolution completed early?\n");
+ res = AST_TEST_FAIL;
+ goto cleanup;
+ }
+
+cleanup:
+ ast_dns_resolver_unregister(&test_resolver);
+ return res;
+}
+
+struct async_resolution_data {
+ int complete;
+ ast_mutex_t lock;
+ ast_cond_t cond;
+};
+
+static void async_data_destructor(void *obj)
+{
+ struct async_resolution_data *async_data = obj;
+
+ ast_mutex_destroy(&async_data->lock);
+ ast_cond_destroy(&async_data->cond);
+}
+
+static struct async_resolution_data *async_data_alloc(void)
+{
+ struct async_resolution_data *async_data;
+
+ async_data = ao2_alloc(sizeof(*async_data), async_data_destructor);
+ if (!async_data) {
+ return NULL;
+ }
+
+ async_data->complete = 0;
+ ast_mutex_init(&async_data->lock);
+ ast_cond_init(&async_data->cond, NULL);
+
+ return async_data;
+}
+
+static void async_callback(const struct ast_dns_query *query)
+{
+ struct async_resolution_data *async_data = ast_dns_query_get_data(query);
+
+ ast_mutex_lock(&async_data->lock);
+ async_data->complete = 1;
+ ast_cond_signal(&async_data->cond);
+ ast_mutex_unlock(&async_data->lock);
+}
+
+AST_TEST_DEFINE(resolver_resolve_async)
+{
+ RAII_VAR(struct ast_dns_result *, result, NULL, ast_dns_result_free);
+ RAII_VAR(struct async_resolution_data *, async_data, NULL, ao2_cleanup);
+ RAII_VAR(struct ast_dns_query *, query, NULL, ao2_cleanup);
+ enum ast_test_result_state res = AST_TEST_PASS;
+
+ switch (cmd) {
+ case TEST_INIT:
+ info->name = "resolver_resolve_async";
+ info->category = "/main/dns/";
+ info->summary = "Test a nominal asynchronous DNS resolution";
+ info->description =
+ "This test performs an asynchronous DNS resolution of a domain. The goal of this\n"
+ "test is not to check the records for accuracy. Rather, the goal is to ensure that\n"
+ "the resolver is called into as expected, that we regain control before the query\n"
+ "is completed, and to ensure that nothing tried to cancel the resolution.";
+ return AST_TEST_NOT_RUN;
+ case TEST_EXECUTE:
+ break;
+ }
+
+ if (ast_dns_resolver_register(&test_resolver)) {
+ ast_test_status_update(test, "Unable to register test resolver\n");
+ return AST_TEST_FAIL;
+ }
+
+ resolver_data_init();
+
+ async_data = async_data_alloc();
+ if (!async_data) {
+ ast_test_status_update(test, "Failed to allocate asynchronous data\n");
+ res = AST_TEST_FAIL;
+ goto cleanup;
+ }
+
+ query = ast_dns_resolve_async("asterisk.org", ns_t_a, ns_c_in, async_callback, async_data);
+ if (!query) {
+ ast_test_status_update(test, "Asynchronous resolution of address failed\n");
+ res = AST_TEST_FAIL;
+ goto cleanup;
+ }
+
+ if (!test_resolver_data.resolve_called) {
+ ast_test_status_update(test, "DNS resolution did not call resolver's resolve() method\n");
+ res = AST_TEST_FAIL;
+ goto cleanup;
+ }
+
+ if (test_resolver_data.cancel_called) {
+ ast_test_status_update(test, "Resolver's cancel() method called for no reason\n");
+ res = AST_TEST_FAIL;
+ goto cleanup;
+ }
+
+ ast_mutex_lock(&async_data->lock);
+ while (!async_data->complete) {
+ ast_cond_wait(&async_data->cond, &async_data->lock);
+ }
+ ast_mutex_unlock(&async_data->lock);
+
+ if (!test_resolver_data.resolution_complete) {
+ ast_test_status_update(test, "Asynchronous resolution completed early?\n");
+ res = AST_TEST_FAIL;
+ goto cleanup;
+ }
+
+cleanup:
+ ast_dns_resolver_unregister(&test_resolver);
+ return res;
+}
+
static int unload_module(void)
{
AST_TEST_UNREGISTER(resolver_register_unregister);
@@ -597,6 +826,8 @@
AST_TEST_UNREGISTER(resolver_set_result_off_nominal);
AST_TEST_UNREGISTER(resolver_add_record);
AST_TEST_UNREGISTER(resolver_add_record_off_nominal);
+ AST_TEST_UNREGISTER(resolver_resolve_sync);
+ AST_TEST_UNREGISTER(resolver_resolve_async);
return 0;
}
@@ -611,6 +842,8 @@
AST_TEST_REGISTER(resolver_set_result_off_nominal);
AST_TEST_REGISTER(resolver_add_record);
AST_TEST_REGISTER(resolver_add_record_off_nominal);
+ AST_TEST_REGISTER(resolver_resolve_sync);
+ AST_TEST_REGISTER(resolver_resolve_async);
return AST_MODULE_LOAD_SUCCESS;
}
More information about the asterisk-commits
mailing list