dnstest.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2011-2015  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 <time.h>
00024 #include <unistd.h>
00025 
00026 #include <isc/app.h>
00027 #include <isc/buffer.h>
00028 #include <isc/entropy.h>
00029 #include <isc/hash.h>
00030 #include <isc/mem.h>
00031 #include <isc/os.h>
00032 #include <isc/string.h>
00033 #include <isc/socket.h>
00034 #include <isc/task.h>
00035 #include <isc/timer.h>
00036 #include <isc/util.h>
00037 
00038 #include <dns/db.h>
00039 #include <dns/fixedname.h>
00040 #include <dns/log.h>
00041 #include <dns/name.h>
00042 #include <dns/result.h>
00043 #include <dns/view.h>
00044 #include <dns/zone.h>
00045 
00046 #include "dnstest.h"
00047 
00048 isc_mem_t *mctx = NULL;
00049 isc_entropy_t *ectx = NULL;
00050 isc_log_t *lctx = NULL;
00051 isc_taskmgr_t *taskmgr = NULL;
00052 isc_task_t *maintask = NULL;
00053 isc_timermgr_t *timermgr = NULL;
00054 isc_socketmgr_t *socketmgr = NULL;
00055 dns_zonemgr_t *zonemgr = NULL;
00056 isc_boolean_t app_running = ISC_FALSE;
00057 int ncpus;
00058 
00059 static isc_boolean_t hash_active = ISC_FALSE, dst_active = ISC_FALSE;
00060 
00061 /*
00062  * Logging categories: this needs to match the list in bin/named/log.c.
00063  */
00064 static isc_logcategory_t categories[] = {
00065                 { "",                0 },
00066                 { "client",          0 },
00067                 { "network",         0 },
00068                 { "update",          0 },
00069                 { "queries",         0 },
00070                 { "unmatched",       0 },
00071                 { "update-security", 0 },
00072                 { "query-errors",    0 },
00073                 { NULL,              0 }
00074 };
00075 
00076 static void
00077 cleanup_managers(void) {
00078         if (app_running)
00079                 isc_app_finish();
00080         if (socketmgr != NULL)
00081                 isc_socketmgr_destroy(&socketmgr);
00082         if (maintask != NULL)
00083                 isc_task_destroy(&maintask);
00084         if (taskmgr != NULL)
00085                 isc_taskmgr_destroy(&taskmgr);
00086         if (timermgr != NULL)
00087                 isc_timermgr_destroy(&timermgr);
00088 }
00089 
00090 static isc_result_t
00091 create_managers(void) {
00092         isc_result_t result;
00093 #ifdef ISC_PLATFORM_USETHREADS
00094         ncpus = isc_os_ncpus();
00095 #else
00096         ncpus = 1;
00097 #endif
00098 
00099         CHECK(isc_taskmgr_create(mctx, ncpus, 0, &taskmgr));
00100         CHECK(isc_timermgr_create(mctx, &timermgr));
00101         CHECK(isc_socketmgr_create(mctx, &socketmgr));
00102         CHECK(isc_task_create(taskmgr, 0, &maintask));
00103         return (ISC_R_SUCCESS);
00104 
00105   cleanup:
00106         cleanup_managers();
00107         return (result);
00108 }
00109 
00110 isc_result_t
00111 dns_test_begin(FILE *logfile, isc_boolean_t start_managers) {
00112         isc_result_t result;
00113 
00114         if (start_managers)
00115                 CHECK(isc_app_start());
00116         isc_mem_debugging |= ISC_MEM_DEBUGRECORD;
00117         CHECK(isc_mem_create(0, 0, &mctx));
00118         CHECK(isc_entropy_create(mctx, &ectx));
00119 
00120         CHECK(isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE));
00121         hash_active = ISC_TRUE;
00122 
00123         CHECK(dst_lib_init(mctx, ectx, ISC_ENTROPY_BLOCKING));
00124         dst_active = ISC_TRUE;
00125 
00126         if (logfile != NULL) {
00127                 isc_logdestination_t destination;
00128                 isc_logconfig_t *logconfig = NULL;
00129 
00130                 CHECK(isc_log_create(mctx, &lctx, &logconfig));
00131                 isc_log_registercategories(lctx, categories);
00132                 isc_log_setcontext(lctx);
00133                 dns_log_init(lctx);
00134                 dns_log_setcontext(lctx);
00135 
00136                 destination.file.stream = logfile;
00137                 destination.file.name = NULL;
00138                 destination.file.versions = ISC_LOG_ROLLNEVER;
00139                 destination.file.maximum_size = 0;
00140                 CHECK(isc_log_createchannel(logconfig, "stderr",
00141                                             ISC_LOG_TOFILEDESC,
00142                                             ISC_LOG_DYNAMIC,
00143                                             &destination, 0));
00144                 CHECK(isc_log_usechannel(logconfig, "stderr", NULL, NULL));
00145         }
00146 
00147         dns_result_register();
00148 
00149         if (start_managers)
00150                 CHECK(create_managers());
00151 
00152         /*
00153          * atf-run changes us to a /tmp directory, so tests
00154          * that access test data files must first chdir to the proper
00155          * location.
00156          */
00157         if (chdir(TESTS) == -1)
00158                 CHECK(ISC_R_FAILURE);
00159 
00160         return (ISC_R_SUCCESS);
00161 
00162   cleanup:
00163         dns_test_end();
00164         return (result);
00165 }
00166 
00167 void
00168 dns_test_end(void) {
00169         if (lctx != NULL)
00170                 isc_log_destroy(&lctx);
00171         if (dst_active) {
00172                 dst_lib_destroy();
00173                 dst_active = ISC_FALSE;
00174         }
00175         if (hash_active) {
00176                 isc_hash_destroy();
00177                 hash_active = ISC_FALSE;
00178         }
00179         if (ectx != NULL)
00180                 isc_entropy_detach(&ectx);
00181 
00182         cleanup_managers();
00183 
00184         if (mctx != NULL)
00185                 isc_mem_destroy(&mctx);
00186 }
00187 
00188 /*
00189  * Create a view.
00190  */
00191 isc_result_t
00192 dns_test_makeview(const char *name, dns_view_t **viewp) {
00193         isc_result_t result;
00194         dns_view_t *view = NULL;
00195 
00196         CHECK(dns_view_create(mctx, dns_rdataclass_in, name, &view));
00197         *viewp = view;
00198 
00199         return (ISC_R_SUCCESS);
00200 
00201  cleanup:
00202         if (view != NULL)
00203                 dns_view_detach(&view);
00204         return (result);
00205 }
00206 
00207 /*
00208  * Create a zone with origin 'name', return a pointer to the zone object in
00209  * 'zonep'.  If 'view' is set, add the zone to that view; otherwise, create
00210  * a new view for the purpose.
00211  *
00212  * If the created view is going to be needed by the caller subsequently,
00213  * then 'keepview' should be set to true; this will prevent the view
00214  * from being detached.  In this case, the caller is responsible for
00215  * detaching the view.
00216  */
00217 isc_result_t
00218 dns_test_makezone(const char *name, dns_zone_t **zonep, dns_view_t *view,
00219                   isc_boolean_t keepview)
00220 {
00221         isc_result_t result;
00222         dns_zone_t *zone = NULL;
00223         isc_buffer_t buffer;
00224         dns_fixedname_t fixorigin;
00225         dns_name_t *origin;
00226 
00227         if (view == NULL)
00228                 CHECK(dns_view_create(mctx, dns_rdataclass_in, "view", &view));
00229         else if (!keepview)
00230                 keepview = ISC_TRUE;
00231 
00232         zone = *zonep;
00233         if (zone == NULL)
00234                 CHECK(dns_zone_create(&zone, mctx));
00235 
00236         isc_buffer_constinit(&buffer, name, strlen(name));
00237         isc_buffer_add(&buffer, strlen(name));
00238         dns_fixedname_init(&fixorigin);
00239         origin = dns_fixedname_name(&fixorigin);
00240         CHECK(dns_name_fromtext(origin, &buffer, dns_rootname, 0, NULL));
00241         CHECK(dns_zone_setorigin(zone, origin));
00242         dns_zone_setview(zone, view);
00243         dns_zone_settype(zone, dns_zone_master);
00244         dns_zone_setclass(zone, view->rdclass);
00245         dns_view_addzone(view, zone);
00246 
00247         if (!keepview)
00248                 dns_view_detach(&view);
00249 
00250         *zonep = zone;
00251 
00252         return (ISC_R_SUCCESS);
00253 
00254   cleanup:
00255         if (zone != NULL)
00256                 dns_zone_detach(&zone);
00257         if (view != NULL)
00258                 dns_view_detach(&view);
00259         return (result);
00260 }
00261 
00262 isc_result_t
00263 dns_test_setupzonemgr(void) {
00264         isc_result_t result;
00265         REQUIRE(zonemgr == NULL);
00266 
00267         result = dns_zonemgr_create(mctx, taskmgr, timermgr, socketmgr,
00268                                     &zonemgr);
00269         return (result);
00270 }
00271 
00272 isc_result_t
00273 dns_test_managezone(dns_zone_t *zone) {
00274         isc_result_t result;
00275         REQUIRE(zonemgr != NULL);
00276 
00277         result = dns_zonemgr_setsize(zonemgr, 1);
00278         if (result != ISC_R_SUCCESS)
00279                 return (result);
00280 
00281         result = dns_zonemgr_managezone(zonemgr, zone);
00282         return (result);
00283 }
00284 
00285 void
00286 dns_test_releasezone(dns_zone_t *zone) {
00287         REQUIRE(zonemgr != NULL);
00288         dns_zonemgr_releasezone(zonemgr, zone);
00289 }
00290 
00291 void
00292 dns_test_closezonemgr(void) {
00293         REQUIRE(zonemgr != NULL);
00294 
00295         dns_zonemgr_shutdown(zonemgr);
00296         dns_zonemgr_detach(&zonemgr);
00297 }
00298 
00299 /*
00300  * Sleep for 'usec' microseconds.
00301  */
00302 void
00303 dns_test_nap(isc_uint32_t usec) {
00304 #ifdef HAVE_NANOSLEEP
00305         struct timespec ts;
00306 
00307         ts.tv_sec = usec / 1000000;
00308         ts.tv_nsec = (usec % 1000000) * 1000;
00309         nanosleep(&ts, NULL);
00310 #elif HAVE_USLEEP
00311         usleep(usec);
00312 #else
00313         /*
00314          * No fractional-second sleep function is available, so we
00315          * round up to the nearest second and sleep instead
00316          */
00317         sleep((usec / 1000000) + 1);
00318 #endif
00319 }
00320 
00321 isc_result_t
00322 dns_test_loaddb(dns_db_t **db, dns_dbtype_t dbtype, const char *origin,
00323                 const char *testfile)
00324 {
00325         isc_result_t            result;
00326         dns_fixedname_t         fixed;
00327         dns_name_t              *name;
00328 
00329         dns_fixedname_init(&fixed);
00330         name = dns_fixedname_name(&fixed);
00331 
00332         result = dns_name_fromstring(name, origin, 0, NULL);
00333         if (result != ISC_R_SUCCESS)
00334                 return(result);
00335 
00336         result = dns_db_create(mctx, "rbt", name, dbtype, dns_rdataclass_in,
00337                                0, NULL, db);
00338         if (result != ISC_R_SUCCESS)
00339                 return (result);
00340 
00341         result = dns_db_load(*db, testfile);
00342         return (result);
00343 }

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