1 /* $NetBSD: zt_test.c,v 1.1.1.4 2014/12/10 03:34:43 christos Exp $ */ 2 3 /* 4 * Copyright (C) 2011, 2012 Internet Systems Consortium, Inc. ("ISC") 5 * 6 * Permission to use, copy, modify, and/or distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 11 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 12 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 13 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 14 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 15 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 * PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 /* Id */ 20 21 /*! \file */ 22 23 #include <config.h> 24 25 #include <atf-c.h> 26 27 #include <unistd.h> 28 29 #include <isc/app.h> 30 #include <isc/buffer.h> 31 #include <isc/task.h> 32 #include <isc/timer.h> 33 34 #include <dns/db.h> 35 #include <dns/name.h> 36 #include <dns/view.h> 37 #include <dns/zone.h> 38 #include <dns/zt.h> 39 40 #include "dnstest.h" 41 42 struct args { 43 void *arg1; 44 void *arg2; 45 }; 46 47 /* 48 * Helper functions 49 */ 50 static isc_result_t 51 count_zone(dns_zone_t *zone, void *uap) { 52 int *nzones = (int *)uap; 53 54 UNUSED(zone); 55 56 *nzones += 1; 57 return (ISC_R_SUCCESS); 58 } 59 60 static isc_result_t 61 load_done(dns_zt_t *zt, dns_zone_t *zone, isc_task_t *task) { 62 /* We treat zt as a pointer to a boolean for testing purposes */ 63 isc_boolean_t *done = (isc_boolean_t *) zt; 64 65 UNUSED(zone); 66 UNUSED(task); 67 68 *done = ISC_TRUE; 69 isc_app_shutdown(); 70 return (ISC_R_SUCCESS); 71 } 72 73 static isc_result_t 74 all_done(void *arg) { 75 isc_boolean_t *done = (isc_boolean_t *) arg; 76 77 *done = ISC_TRUE; 78 isc_app_shutdown(); 79 return (ISC_R_SUCCESS); 80 } 81 82 static void 83 start_zt_asyncload(isc_task_t *task, isc_event_t *event) { 84 struct args *args = (struct args *)(event->ev_arg); 85 86 UNUSED(task); 87 88 dns_zt_asyncload(args->arg1, all_done, args->arg2); 89 90 isc_event_free(&event); 91 } 92 93 static void 94 start_zone_asyncload(isc_task_t *task, isc_event_t *event) { 95 struct args *args = (struct args *)(event->ev_arg); 96 97 UNUSED(task); 98 99 dns_zone_asyncload(args->arg1, load_done, args->arg2); 100 isc_event_free(&event); 101 } 102 103 /* 104 * Individual unit tests 105 */ 106 ATF_TC(apply); 107 ATF_TC_HEAD(apply, tc) { 108 atf_tc_set_md_var(tc, "descr", "apply a function to a zone table"); 109 } 110 ATF_TC_BODY(apply, tc) { 111 isc_result_t result; 112 dns_zone_t *zone = NULL; 113 dns_view_t *view = NULL; 114 int nzones = 0; 115 116 UNUSED(tc); 117 118 result = dns_test_begin(NULL, ISC_TRUE); 119 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); 120 121 result = dns_test_makezone("foo", &zone, NULL, ISC_TRUE); 122 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); 123 124 view = dns_zone_getview(zone); 125 ATF_REQUIRE(view->zonetable != NULL); 126 127 ATF_CHECK_EQ(0, nzones); 128 result = dns_zt_apply(view->zonetable, ISC_FALSE, count_zone, &nzones); 129 ATF_CHECK_EQ(result, ISC_R_SUCCESS); 130 ATF_CHECK_EQ(1, nzones); 131 132 /* These steps are necessary so the zone can be detached properly */ 133 result = dns_test_setupzonemgr(); 134 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); 135 result = dns_test_managezone(zone); 136 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); 137 dns_test_releasezone(zone); 138 dns_test_closezonemgr(); 139 140 /* The view was left attached in dns_test_makezone() */ 141 dns_view_detach(&view); 142 dns_zone_detach(&zone); 143 144 dns_test_end(); 145 } 146 147 ATF_TC(asyncload_zone); 148 ATF_TC_HEAD(asyncload_zone, tc) { 149 atf_tc_set_md_var(tc, "descr", "asynchronous zone load"); 150 } 151 ATF_TC_BODY(asyncload_zone, tc) { 152 isc_result_t result; 153 dns_zone_t *zone = NULL; 154 dns_view_t *view = NULL; 155 dns_db_t *db = NULL; 156 isc_boolean_t done = ISC_FALSE; 157 int i = 0; 158 struct args args; 159 160 UNUSED(tc); 161 162 result = dns_test_begin(NULL, ISC_TRUE); 163 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); 164 165 result = dns_test_makezone("foo", &zone, NULL, ISC_TRUE); 166 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); 167 168 result = dns_test_setupzonemgr(); 169 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); 170 result = dns_test_managezone(zone); 171 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); 172 173 view = dns_zone_getview(zone); 174 ATF_REQUIRE(view->zonetable != NULL); 175 176 ATF_CHECK(!dns__zone_loadpending(zone)); 177 ATF_CHECK(!done); 178 dns_zone_setfile(zone, "testdata/zt/zone1.db"); 179 180 args.arg1 = zone; 181 args.arg2 = &done; 182 isc_app_onrun(mctx, maintask, start_zone_asyncload, &args); 183 184 isc_app_run(); 185 while (dns__zone_loadpending(zone) && i++ < 5000) 186 dns_test_nap(1000); 187 ATF_CHECK(done); 188 189 /* The zone should now be loaded; test it */ 190 result = dns_zone_getdb(zone, &db); 191 ATF_CHECK_EQ(result, ISC_R_SUCCESS); 192 ATF_CHECK(db != NULL); 193 if (db != NULL) 194 dns_db_detach(&db); 195 196 dns_test_releasezone(zone); 197 dns_test_closezonemgr(); 198 199 dns_zone_detach(&zone); 200 dns_view_detach(&view); 201 202 dns_test_end(); 203 } 204 205 ATF_TC(asyncload_zt); 206 ATF_TC_HEAD(asyncload_zt, tc) { 207 atf_tc_set_md_var(tc, "descr", "asynchronous zone table load"); 208 } 209 ATF_TC_BODY(asyncload_zt, tc) { 210 isc_result_t result; 211 dns_zone_t *zone1 = NULL, *zone2 = NULL, *zone3 = NULL; 212 dns_view_t *view; 213 dns_zt_t *zt; 214 dns_db_t *db = NULL; 215 isc_boolean_t done = ISC_FALSE; 216 int i = 0; 217 struct args args; 218 219 UNUSED(tc); 220 221 result = dns_test_begin(NULL, ISC_TRUE); 222 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); 223 224 result = dns_test_makezone("foo", &zone1, NULL, ISC_TRUE); 225 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); 226 dns_zone_setfile(zone1, "testdata/zt/zone1.db"); 227 view = dns_zone_getview(zone1); 228 229 result = dns_test_makezone("bar", &zone2, view, ISC_TRUE); 230 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); 231 dns_zone_setfile(zone2, "testdata/zt/zone1.db"); 232 233 /* This one will fail to load */ 234 result = dns_test_makezone("fake", &zone3, view, ISC_TRUE); 235 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); 236 dns_zone_setfile(zone3, "testdata/zt/nonexistent.db"); 237 238 zt = view->zonetable; 239 ATF_REQUIRE(zt != NULL); 240 241 result = dns_test_setupzonemgr(); 242 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); 243 result = dns_test_managezone(zone1); 244 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); 245 result = dns_test_managezone(zone2); 246 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); 247 result = dns_test_managezone(zone3); 248 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); 249 250 ATF_CHECK(!dns__zone_loadpending(zone1)); 251 ATF_CHECK(!dns__zone_loadpending(zone2)); 252 ATF_CHECK(!done); 253 254 args.arg1 = zt; 255 args.arg2 = &done; 256 isc_app_onrun(mctx, maintask, start_zt_asyncload, &args); 257 258 isc_app_run(); 259 while (!done && i++ < 5000) 260 dns_test_nap(1000); 261 ATF_CHECK(done); 262 263 /* Both zones should now be loaded; test them */ 264 result = dns_zone_getdb(zone1, &db); 265 ATF_CHECK_EQ(result, ISC_R_SUCCESS); 266 ATF_CHECK(db != NULL); 267 if (db != NULL) 268 dns_db_detach(&db); 269 270 result = dns_zone_getdb(zone2, &db); 271 ATF_CHECK_EQ(result, ISC_R_SUCCESS); 272 ATF_CHECK(db != NULL); 273 if (db != NULL) 274 dns_db_detach(&db); 275 276 dns_test_releasezone(zone3); 277 dns_test_releasezone(zone2); 278 dns_test_releasezone(zone1); 279 dns_test_closezonemgr(); 280 281 dns_zone_detach(&zone1); 282 dns_zone_detach(&zone2); 283 dns_zone_detach(&zone3); 284 dns_view_detach(&view); 285 286 dns_test_end(); 287 } 288 289 /* 290 * Main 291 */ 292 ATF_TP_ADD_TCS(tp) { 293 ATF_TP_ADD_TC(tp, apply); 294 ATF_TP_ADD_TC(tp, asyncload_zone); 295 ATF_TP_ADD_TC(tp, asyncload_zt); 296 return (atf_no_error()); 297 } 298