Author: mmichelson
Date: Tue Mar 10 12:42:45 2015
New Revision: 432690

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=432690
Log:
Add recurring DNS cancel tests.

There are two tests, one that attempts to cancel a recurring query between
lookups, and one that attempts to cancel a recurring query during a lookup.

The test that cancels between lookups works just fine. The test that cancels
during a lookup currently fails and throws out some FRACKs.


Modified:
    team/group/dns/tests/test_dns_recurring.c

Modified: team/group/dns/tests/test_dns_recurring.c
URL: 
http://svnview.digium.com/svn/asterisk/team/group/dns/tests/test_dns_recurring.c?view=diff&rev=432690&r1=432689&r2=432690
==============================================================================
--- team/group/dns/tests/test_dns_recurring.c (original)
+++ team/group/dns/tests/test_dns_recurring.c Tue Mar 10 12:42:45 2015
@@ -44,6 +44,12 @@
        int complete_resolutions;
        /*! Number of times resolve() method has been called */
        int resolves;
+       /*! Indicates that the query is expected to be canceled */
+       int cancel_expected;
+       /*! Indicates that the query is ready to be canceled */
+       int cancel_ready;
+       /*! Indicates that the query has been canceled */
+       int canceled;
        ast_mutex_t lock;
        ast_cond_t cond;
 };
@@ -88,6 +94,25 @@
 
        ast_assert(rdata != NULL);
 
+       /* Canceling is an interesting dance. This thread needs to signal that 
it is
+        * ready to be canceled. Then it needs to wait until the query is 
actually canceled.
+        */
+       if (rdata->cancel_expected) {
+               ast_mutex_lock(&rdata->lock);
+               rdata->cancel_ready = 1;
+               ast_cond_signal(&rdata->cond);
+
+               while (!rdata->canceled) {
+                       ast_cond_wait(&rdata->cond, &rdata->lock);
+               }
+               ast_mutex_unlock(&rdata->lock);
+
+               ast_dns_resolver_completed(query);
+               ao2_ref(query, -1);
+
+               return NULL;
+       }
+
        ast_dns_resolver_set_result(query, 0, 0, ns_r_noerror, "asterisk.org");
 
        inet_pton(AF_INET, ADDR1, addr1_buf);
@@ -117,7 +142,14 @@
 
 static int recurring_cancel(struct ast_dns_query *query)
 {
-       /* XXX STUB */
+       struct ast_dns_query_recurring *recurring = 
ast_dns_query_get_data(query);
+       struct recurring_data *rdata = recurring->user_data;
+
+       ast_mutex_lock(&rdata->lock);
+       rdata->canceled = 1;
+       ast_cond_signal(&rdata->cond);
+       ast_mutex_unlock(&rdata->lock);
+
        return 0;
 }
 
@@ -368,10 +400,184 @@
        return res;
 }
 
+AST_TEST_DEFINE(recurring_query_cancel_between)
+{
+       RAII_VAR(struct ast_dns_query_recurring *, recurring_query, NULL, 
ao2_cleanup);
+       RAII_VAR(struct recurring_data *, rdata, NULL, ao2_cleanup);
+
+       enum ast_test_result_state res = AST_TEST_PASS;
+       struct timespec timeout;
+
+       switch (cmd) {
+       case TEST_INIT:
+               info->name = "recurring_query_cancel_between";
+               info->category = "/main/dns/recurring/";
+               info->summary = "Test canceling a recurring DNS query during 
the downtime between queries\n";
+               info->description = "This test does the following:\n"
+                       "\t* Issue a recurring DNS query.\n"
+                       "\t* Once results have been returned, cancel the 
recurring query.\n"
+                       "\t* Wait a while to ensure that no more queries are 
occurring.\n";
+               return AST_TEST_NOT_RUN;
+       case TEST_EXECUTE:
+               break;
+       }
+
+       if (ast_dns_resolver_register(&recurring_resolver)) {
+               ast_test_status_update(test, "Failed to register recurring DNS 
resolver\n");
+               return AST_TEST_FAIL;
+       }
+
+       rdata = recurring_data_alloc();
+       if (!rdata) {
+               ast_test_status_update(test, "Failed to allocate data necessary 
for recurring test\n");
+               res = AST_TEST_FAIL;
+               goto cleanup;
+       }
+
+       rdata->ttl1 = 5;
+       rdata->ttl2 = 20;
+
+       recurring_query = ast_dns_resolve_recurring("asterisk.org", ns_t_a, 
ns_c_in, async_callback, rdata);
+       if (!recurring_query) {
+               ast_test_status_update(test, "Unable to make recurring 
query\n");
+               res = AST_TEST_FAIL;
+               goto cleanup;
+       }
+
+       if (wait_for_resolution(test, rdata, 0, 1)) {
+               res = AST_TEST_FAIL;
+               goto cleanup;
+       }
+
+       if (ast_dns_resolve_recurring_cancel(recurring_query)) {
+               ast_test_status_update(test, "Failed to cancel recurring 
query\n");
+               res = AST_TEST_FAIL;
+               goto cleanup;
+       }
+
+       /* Query has been canceled, so let's wait to make sure that we don't get
+        * told another query has occurred.
+        */
+       clock_gettime(CLOCK_REALTIME, &timeout);
+       timeout.tv_sec += 10;
+
+       ast_mutex_lock(&rdata->lock);
+       while (!rdata->query_complete) {
+               if (ast_cond_timedwait(&rdata->cond, &rdata->lock, &timeout) == 
ETIMEDOUT) {
+                       break;
+               }
+       }
+       ast_mutex_unlock(&rdata->lock);
+
+       if (rdata->query_complete) {
+               ast_test_status_update(test, "Recurring query occurred after 
cancellation\n");
+               res = AST_TEST_FAIL;
+               goto cleanup;
+       }
+
+cleanup:
+       ast_dns_resolver_unregister(&recurring_resolver);
+       return res;
+}
+
+AST_TEST_DEFINE(recurring_query_cancel_during)
+{
+
+       RAII_VAR(struct ast_dns_query_recurring *, recurring_query, NULL, 
ao2_cleanup);
+       RAII_VAR(struct recurring_data *, rdata, NULL, ao2_cleanup);
+
+       enum ast_test_result_state res = AST_TEST_PASS;
+       struct timespec timeout;
+
+       switch (cmd) {
+       case TEST_INIT:
+               info->name = "recurring_query_cancel_during";
+               info->category = "/main/dns/recurring/";
+               info->summary = "Cancel a recurring DNS query while a query is 
actually happening\n";
+               info->description = "This test does the following:\n"
+                       "\t* Initiate a recurring DNS query.\n"
+                       "\t* Allow the initial query to complete, and a second 
query to start\n"
+                       "\t* Cancel the recurring query while the second query 
is executing\n"
+                       "\t* Ensure that the resolver's cancel() method was 
called\n"
+                       "\t* Wait a while to make sure that recurring queries 
are no longer occurring\n";
+               return AST_TEST_NOT_RUN;
+       case TEST_EXECUTE:
+               break;
+       }
+
+       if (ast_dns_resolver_register(&recurring_resolver)) {
+               ast_test_status_update(test, "Failed to register recurring DNS 
resolver\n");
+               return AST_TEST_FAIL;
+       }
+
+       rdata = recurring_data_alloc();
+       if (!rdata) {
+               ast_test_status_update(test, "Failed to allocate data necessary 
for recurring test\n");
+               res = AST_TEST_FAIL;
+               goto cleanup;
+       }
+
+       rdata->ttl1 = 5;
+       rdata->ttl2 = 20;
+
+       recurring_query = ast_dns_resolve_recurring("asterisk.org", ns_t_a, 
ns_c_in, async_callback, rdata);
+       if (!recurring_query) {
+               ast_test_status_update(test, "Failed to make recurring DNS 
query\n");
+               res = AST_TEST_FAIL;
+               goto cleanup;
+       }
+
+       if (wait_for_resolution(test, rdata, 0, 1)) {
+               res = AST_TEST_FAIL;
+               goto cleanup;
+       }
+
+       /* Initial query has completed. Now let's make the next query expect a 
cancelation */
+       rdata->cancel_expected = 1;
+
+       /* Wait to be told that the query should be canceled  */
+       ast_mutex_lock(&rdata->lock);
+       while (!rdata->cancel_ready) {
+               ast_cond_wait(&rdata->cond, &rdata->lock);
+       }
+       rdata->cancel_expected = 0;
+       ast_mutex_unlock(&rdata->lock);
+
+       if (ast_dns_resolve_recurring_cancel(recurring_query)) {
+               ast_test_status_update(test, "Failed to cancel recurring DNS 
query\n");
+               res = AST_TEST_FAIL;
+               goto cleanup;
+       }
+
+       /* Query has been canceled. Now wait to make sure there are no more 
recurring queries */
+       clock_gettime(CLOCK_REALTIME, &timeout);
+       timeout.tv_sec += 10;
+
+       ast_mutex_lock(&rdata->lock);
+       while (!rdata->query_complete) {
+               if (ast_cond_timedwait(&rdata->cond, &rdata->lock, &timeout) == 
ETIMEDOUT) {
+                       break;
+               }
+       }
+       ast_mutex_unlock(&rdata->lock);
+
+       if (rdata->query_complete) {
+               ast_test_status_update(test, "Recurring query occurred after 
cancellation\n");
+               res = AST_TEST_FAIL;
+               goto cleanup;
+       }
+
+cleanup:
+       ast_dns_resolver_unregister(&recurring_resolver);
+       return res;
+}
+
 static int unload_module(void)
 {
        AST_TEST_UNREGISTER(recurring_query);
        AST_TEST_UNREGISTER(recurring_query_off_nominal);
+       AST_TEST_UNREGISTER(recurring_query_cancel_between);
+       AST_TEST_UNREGISTER(recurring_query_cancel_during);
 
        return 0;
 }
@@ -380,6 +586,7 @@
 {
        AST_TEST_REGISTER(recurring_query);
        AST_TEST_REGISTER(recurring_query_off_nominal);
+       AST_TEST_REGISTER(recurring_query_cancel_during);
 
        return AST_MODULE_LOAD_SUCCESS;
 }


-- 
_____________________________________________________________________
-- Bandwidth and Colocation Provided by http://www.api-digital.com --

svn-commits mailing list
To UNSUBSCRIBE or update options visit:
   http://lists.digium.com/mailman/listinfo/svn-commits

Reply via email to