task_test.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2011, 2012  Internet Systems Consortium, Inc. ("ISC")
00003  *
00004  * Permission to use, copy, modify, and/or distribute this software for any
00005  * purpose with or without fee is hereby granted, provided that the above
00006  * copyright notice and this permission notice appear in all copies.
00007  *
00008  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
00009  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
00010  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
00011  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
00012  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
00013  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
00014  * PERFORMANCE OF THIS SOFTWARE.
00015  */
00016 
00017 /* $Id$ */
00018 
00019 /*! \file */
00020 
00021 #include <config.h>
00022 
00023 #include <atf-c.h>
00024 
00025 #include <unistd.h>
00026 
00027 #include <isc/task.h>
00028 #include <isc/util.h>
00029 
00030 #include "../task_p.h"
00031 #include "isctest.h"
00032 
00033 /*
00034  * Helper functions
00035  */
00036 
00037 /* task event handler, sets a boolean to true */
00038 int counter = 0;
00039 isc_mutex_t set_lock;
00040 
00041 static void
00042 set(isc_task_t *task, isc_event_t *event) {
00043         int *value = (int *) event->ev_arg;
00044 
00045         UNUSED(task);
00046 
00047         isc_event_free(&event);
00048         LOCK(&set_lock);
00049         *value = counter++;
00050         UNLOCK(&set_lock);
00051 }
00052 
00053 static void
00054 set_and_drop(isc_task_t *task, isc_event_t *event) {
00055         int *value = (int *) event->ev_arg;
00056 
00057         UNUSED(task);
00058 
00059         isc_event_free(&event);
00060         LOCK(&set_lock);
00061         *value = (int) isc_taskmgr_mode(taskmgr);
00062         counter++;
00063         UNLOCK(&set_lock);
00064         isc_taskmgr_setmode(taskmgr, isc_taskmgrmode_normal);
00065 }
00066 
00067 /*
00068  * Individual unit tests
00069  */
00070 
00071 /* Create a task */
00072 ATF_TC(create_task);
00073 ATF_TC_HEAD(create_task, tc) {
00074         atf_tc_set_md_var(tc, "descr", "create and destroy a task");
00075 }
00076 ATF_TC_BODY(create_task, tc) {
00077         isc_result_t result;
00078         isc_task_t *task = NULL;
00079 
00080         UNUSED(tc);
00081 
00082         result = isc_test_begin(NULL, ISC_TRUE);
00083         ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
00084 
00085         result = isc_task_create(taskmgr, 0, &task);
00086         ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
00087 
00088         isc_task_destroy(&task);
00089         ATF_REQUIRE_EQ(task, NULL);
00090 
00091         isc_test_end();
00092 }
00093 
00094 /* Process events */
00095 ATF_TC(all_events);
00096 ATF_TC_HEAD(all_events, tc) {
00097         atf_tc_set_md_var(tc, "descr", "process task events");
00098 }
00099 ATF_TC_BODY(all_events, tc) {
00100         isc_result_t result;
00101         isc_task_t *task = NULL;
00102         isc_event_t *event;
00103         int a = 0, b = 0;
00104         int i = 0;
00105 
00106         UNUSED(tc);
00107 
00108         counter = 1;
00109 
00110         result = isc_mutex_init(&set_lock);
00111         ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
00112 
00113         result = isc_test_begin(NULL, ISC_TRUE);
00114         ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
00115 
00116         result = isc_task_create(taskmgr, 0, &task);
00117         ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
00118 
00119         /* First event */
00120         event = isc_event_allocate(mctx, task, ISC_TASKEVENT_TEST,
00121                                    set, &a, sizeof (isc_event_t));
00122         ATF_REQUIRE(event != NULL);
00123 
00124         ATF_CHECK_EQ(a, 0);
00125         isc_task_send(task, &event);
00126 
00127         event = isc_event_allocate(mctx, task, ISC_TASKEVENT_TEST,
00128                                    set, &b, sizeof (isc_event_t));
00129         ATF_REQUIRE(event != NULL);
00130 
00131         ATF_CHECK_EQ(b, 0);
00132         isc_task_send(task, &event);
00133 
00134         while ((a == 0 || b == 0) && i++ < 5000) {
00135 #ifndef ISC_PLATFORM_USETHREADS
00136                 while (isc__taskmgr_ready(taskmgr))
00137                         isc__taskmgr_dispatch(taskmgr);
00138 #endif
00139                 isc_test_nap(1000);
00140         }
00141 
00142         ATF_CHECK(a != 0);
00143         ATF_CHECK(b != 0);
00144 
00145         isc_task_destroy(&task);
00146         ATF_REQUIRE_EQ(task, NULL);
00147 
00148         isc_test_end();
00149 }
00150 
00151 /* Privileged events */
00152 ATF_TC(privileged_events);
00153 ATF_TC_HEAD(privileged_events, tc) {
00154         atf_tc_set_md_var(tc, "descr", "process privileged events");
00155 }
00156 ATF_TC_BODY(privileged_events, tc) {
00157         isc_result_t result;
00158         isc_task_t *task1 = NULL, *task2 = NULL;
00159         isc_event_t *event;
00160         int a = 0, b = 0, c = 0, d = 0, e = 0;
00161         int i = 0;
00162 
00163         UNUSED(tc);
00164 
00165         counter = 1;
00166         result = isc_mutex_init(&set_lock);
00167         ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
00168 
00169         result = isc_test_begin(NULL, ISC_TRUE);
00170         ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
00171 
00172 #ifdef ISC_PLATFORM_USETHREADS
00173         /*
00174          * Pause the task manager so we can fill up the work queue
00175          * without things happening while we do it.
00176          */
00177         isc__taskmgr_pause(taskmgr);
00178 #endif
00179 
00180         result = isc_task_create(taskmgr, 0, &task1);
00181         ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
00182         isc_task_setname(task1, "privileged", NULL);
00183         ATF_CHECK(!isc_task_privilege(task1));
00184         isc_task_setprivilege(task1, ISC_TRUE);
00185         ATF_CHECK(isc_task_privilege(task1));
00186 
00187         result = isc_task_create(taskmgr, 0, &task2);
00188         ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
00189         isc_task_setname(task2, "normal", NULL);
00190         ATF_CHECK(!isc_task_privilege(task2));
00191 
00192         /* First event: privileged */
00193         event = isc_event_allocate(mctx, task1, ISC_TASKEVENT_TEST,
00194                                    set, &a, sizeof (isc_event_t));
00195         ATF_REQUIRE(event != NULL);
00196 
00197         ATF_CHECK_EQ(a, 0);
00198         isc_task_send(task1, &event);
00199 
00200         /* Second event: not privileged */
00201         event = isc_event_allocate(mctx, task2, ISC_TASKEVENT_TEST,
00202                                    set, &b, sizeof (isc_event_t));
00203         ATF_REQUIRE(event != NULL);
00204 
00205         ATF_CHECK_EQ(b, 0);
00206         isc_task_send(task2, &event);
00207 
00208         /* Third event: privileged */
00209         event = isc_event_allocate(mctx, task1, ISC_TASKEVENT_TEST,
00210                                    set, &c, sizeof (isc_event_t));
00211         ATF_REQUIRE(event != NULL);
00212 
00213         ATF_CHECK_EQ(c, 0);
00214         isc_task_send(task1, &event);
00215 
00216         /* Fourth event: privileged */
00217         event = isc_event_allocate(mctx, task1, ISC_TASKEVENT_TEST,
00218                                    set, &d, sizeof (isc_event_t));
00219         ATF_REQUIRE(event != NULL);
00220 
00221         ATF_CHECK_EQ(d, 0);
00222         isc_task_send(task1, &event);
00223 
00224         /* Fifth event: not privileged */
00225         event = isc_event_allocate(mctx, task2, ISC_TASKEVENT_TEST,
00226                                    set, &e, sizeof (isc_event_t));
00227         ATF_REQUIRE(event != NULL);
00228 
00229         ATF_CHECK_EQ(e, 0);
00230         isc_task_send(task2, &event);
00231 
00232         ATF_CHECK_EQ(isc_taskmgr_mode(taskmgr), isc_taskmgrmode_normal);
00233         isc_taskmgr_setmode(taskmgr, isc_taskmgrmode_privileged);
00234         ATF_CHECK_EQ(isc_taskmgr_mode(taskmgr), isc_taskmgrmode_privileged);
00235 
00236 #ifdef ISC_PLATFORM_USETHREADS
00237         isc__taskmgr_resume(taskmgr);
00238 #endif
00239 
00240         /* We're waiting for *all* variables to be set */
00241         while ((a == 0 || b == 0 || c == 0 || d == 0 || e == 0) && i++ < 5000) {
00242 #ifndef ISC_PLATFORM_USETHREADS
00243                 while (isc__taskmgr_ready(taskmgr))
00244                         isc__taskmgr_dispatch(taskmgr);
00245 #endif
00246                 isc_test_nap(1000);
00247         }
00248 
00249         /*
00250          * We can't guarantee what order the events fire, but
00251          * we do know the privileged tasks that set a, c, and d
00252          * would have fired first.
00253          */
00254         ATF_CHECK(a <= 3);
00255         ATF_CHECK(c <= 3);
00256         ATF_CHECK(d <= 3);
00257 
00258         /* ...and the non-privileged tasks that set b and e, last */
00259         ATF_CHECK(b >= 4);
00260         ATF_CHECK(e >= 4);
00261 
00262         ATF_CHECK_EQ(counter, 6);
00263 
00264         isc_task_setprivilege(task1, ISC_FALSE);
00265         ATF_CHECK(!isc_task_privilege(task1));
00266 
00267         ATF_CHECK_EQ(isc_taskmgr_mode(taskmgr), isc_taskmgrmode_normal);
00268 
00269         isc_task_destroy(&task1);
00270         ATF_REQUIRE_EQ(task1, NULL);
00271         isc_task_destroy(&task2);
00272         ATF_REQUIRE_EQ(task2, NULL);
00273 
00274         isc_test_end();
00275 }
00276 
00277 /*
00278  * Edge case: this tests that the task manager behaves as expected when
00279  * we explicitly set it into normal mode *while* running privileged.
00280  */
00281 ATF_TC(privilege_drop);
00282 ATF_TC_HEAD(privilege_drop, tc) {
00283         atf_tc_set_md_var(tc, "descr", "process privileged events");
00284 }
00285 ATF_TC_BODY(privilege_drop, tc) {
00286         isc_result_t result;
00287         isc_task_t *task1 = NULL, *task2 = NULL;
00288         isc_event_t *event;
00289         int a = -1, b = -1, c = -1, d = -1, e = -1;     /* non valid states */
00290         int i = 0;
00291 
00292         UNUSED(tc);
00293 
00294         counter = 1;
00295         result = isc_mutex_init(&set_lock);
00296         ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
00297 
00298         result = isc_test_begin(NULL, ISC_TRUE);
00299         ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
00300 
00301 #ifdef ISC_PLATFORM_USETHREADS
00302         /*
00303          * Pause the task manager so we can fill up the work queue
00304          * without things happening while we do it.
00305          */
00306         isc__taskmgr_pause(taskmgr);
00307 #endif
00308 
00309         result = isc_task_create(taskmgr, 0, &task1);
00310         ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
00311         isc_task_setname(task1, "privileged", NULL);
00312         ATF_CHECK(!isc_task_privilege(task1));
00313         isc_task_setprivilege(task1, ISC_TRUE);
00314         ATF_CHECK(isc_task_privilege(task1));
00315 
00316         result = isc_task_create(taskmgr, 0, &task2);
00317         ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
00318         isc_task_setname(task2, "normal", NULL);
00319         ATF_CHECK(!isc_task_privilege(task2));
00320 
00321         /* First event: privileged */
00322         event = isc_event_allocate(mctx, task1, ISC_TASKEVENT_TEST,
00323                                    set_and_drop, &a, sizeof (isc_event_t));
00324         ATF_REQUIRE(event != NULL);
00325 
00326         ATF_CHECK_EQ(a, -1);
00327         isc_task_send(task1, &event);
00328 
00329         /* Second event: not privileged */
00330         event = isc_event_allocate(mctx, task2, ISC_TASKEVENT_TEST,
00331                                    set_and_drop, &b, sizeof (isc_event_t));
00332         ATF_REQUIRE(event != NULL);
00333 
00334         ATF_CHECK_EQ(b, -1);
00335         isc_task_send(task2, &event);
00336 
00337         /* Third event: privileged */
00338         event = isc_event_allocate(mctx, task1, ISC_TASKEVENT_TEST,
00339                                    set_and_drop, &c, sizeof (isc_event_t));
00340         ATF_REQUIRE(event != NULL);
00341 
00342         ATF_CHECK_EQ(c, -1);
00343         isc_task_send(task1, &event);
00344 
00345         /* Fourth event: privileged */
00346         event = isc_event_allocate(mctx, task1, ISC_TASKEVENT_TEST,
00347                                    set_and_drop, &d, sizeof (isc_event_t));
00348         ATF_REQUIRE(event != NULL);
00349 
00350         ATF_CHECK_EQ(d, -1);
00351         isc_task_send(task1, &event);
00352 
00353         /* Fifth event: not privileged */
00354         event = isc_event_allocate(mctx, task2, ISC_TASKEVENT_TEST,
00355                                    set_and_drop, &e, sizeof (isc_event_t));
00356         ATF_REQUIRE(event != NULL);
00357 
00358         ATF_CHECK_EQ(e, -1);
00359         isc_task_send(task2, &event);
00360 
00361         ATF_CHECK_EQ(isc_taskmgr_mode(taskmgr), isc_taskmgrmode_normal);
00362         isc_taskmgr_setmode(taskmgr, isc_taskmgrmode_privileged);
00363         ATF_CHECK_EQ(isc_taskmgr_mode(taskmgr), isc_taskmgrmode_privileged);
00364 
00365 #ifdef ISC_PLATFORM_USETHREADS
00366         isc__taskmgr_resume(taskmgr);
00367 #endif
00368 
00369         /* We're waiting for all variables to be set. */
00370         while ((a == -1 || b == -1 || c == -1 || d == -1 || e == -1) &&
00371                i++ < 5000) {
00372 #ifndef ISC_PLATFORM_USETHREADS
00373                 while (isc__taskmgr_ready(taskmgr))
00374                         isc__taskmgr_dispatch(taskmgr);
00375 #endif
00376                 isc_test_nap(1000);
00377         }
00378 
00379         /*
00380          * We can't guarantee what order the events fire, but
00381          * we do know *exactly one* of the privileged tasks will
00382          * have run in privileged mode...
00383          */
00384         ATF_CHECK(a == isc_taskmgrmode_privileged ||
00385                   c == isc_taskmgrmode_privileged ||
00386                   d == isc_taskmgrmode_privileged);
00387         ATF_CHECK(a + c + d == isc_taskmgrmode_privileged);
00388 
00389         /* ...and neither of the non-privileged tasks did... */
00390         ATF_CHECK(b == isc_taskmgrmode_normal || e == isc_taskmgrmode_normal);
00391 
00392         /* ...but all five of them did run. */
00393         ATF_CHECK_EQ(counter, 6);
00394 
00395         ATF_CHECK_EQ(isc_taskmgr_mode(taskmgr), isc_taskmgrmode_normal);
00396 
00397         isc_task_destroy(&task1);
00398         ATF_REQUIRE_EQ(task1, NULL);
00399         isc_task_destroy(&task2);
00400         ATF_REQUIRE_EQ(task2, NULL);
00401 
00402         isc_test_end();
00403 }
00404 
00405 /*
00406  * Main
00407  */
00408 ATF_TP_ADD_TCS(tp) {
00409         ATF_TP_ADD_TC(tp, create_task);
00410         ATF_TP_ADD_TC(tp, all_events);
00411         ATF_TP_ADD_TC(tp, privileged_events);
00412         ATF_TP_ADD_TC(tp, privilege_drop);
00413 
00414         return (atf_no_error());
00415 }
00416 

Generated on Tue Apr 28 17:41:05 2015 by Doxygen 1.5.4 for BIND9 Internals 9.11.0pre-alpha