1/* $NetBSD: isctest.c,v 1.1.1.3 2012/12/04 19:26:00 spz 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 <time.h> 26 27#include <isc/app.h> 28#include <isc/buffer.h> 29#include <isc/entropy.h> 30#include <isc/hash.h> 31#include <isc/mem.h> 32#include <isc/os.h> 33#include <isc/socket.h> 34#include <isc/string.h> 35#include <isc/task.h> 36#include <isc/timer.h> 37#include <isc/util.h> 38 39#include "isctest.h" 40 41isc_mem_t *mctx = NULL; 42isc_entropy_t *ectx = NULL; 43isc_log_t *lctx = NULL; 44isc_taskmgr_t *taskmgr = NULL; 45isc_timermgr_t *timermgr = NULL; 46isc_socketmgr_t *socketmgr = NULL; 47isc_task_t *maintask = NULL; 48int ncpus; 49 50static isc_boolean_t hash_active = ISC_FALSE; 51 52/* 53 * Logging categories: this needs to match the list in bin/named/log.c. 54 */ 55static isc_logcategory_t categories[] = { 56 { "", 0 }, 57 { "client", 0 }, 58 { "network", 0 }, 59 { "update", 0 }, 60 { "queries", 0 }, 61 { "unmatched", 0 }, 62 { "update-security", 0 }, 63 { "query-errors", 0 }, 64 { NULL, 0 } 65}; 66 67static void 68cleanup_managers() { 69 if (maintask != NULL) 70 isc_task_destroy(&maintask); 71 if (socketmgr != NULL) 72 isc_socketmgr_destroy(&socketmgr); 73 if (taskmgr != NULL) 74 isc_taskmgr_destroy(&taskmgr); 75 if (timermgr != NULL) 76 isc_timermgr_destroy(&timermgr); 77} 78 79static isc_result_t 80create_managers() { 81 isc_result_t result; 82#ifdef ISC_PLATFORM_USETHREADS 83 ncpus = isc_os_ncpus(); 84#else 85 ncpus = 1; 86#endif 87 88 CHECK(isc_taskmgr_create(mctx, ncpus, 0, &taskmgr)); 89 CHECK(isc_task_create(taskmgr, 0, &maintask)); 90 isc_taskmgr_setexcltask(taskmgr, maintask); 91 92 CHECK(isc_timermgr_create(mctx, &timermgr)); 93 CHECK(isc_socketmgr_create(mctx, &socketmgr)); 94 return (ISC_R_SUCCESS); 95 96 cleanup: 97 cleanup_managers(); 98 return (result); 99} 100 101isc_result_t 102isc_test_begin(FILE *logfile, isc_boolean_t start_managers) { 103 isc_result_t result; 104 105 isc_mem_debugging |= ISC_MEM_DEBUGRECORD; 106 CHECK(isc_mem_create(0, 0, &mctx)); 107 CHECK(isc_entropy_create(mctx, &ectx)); 108 109 CHECK(isc_hash_create(mctx, ectx, 255)); 110 hash_active = ISC_TRUE; 111 112 if (logfile != NULL) { 113 isc_logdestination_t destination; 114 isc_logconfig_t *logconfig = NULL; 115 116 CHECK(isc_log_create(mctx, &lctx, &logconfig)); 117 isc_log_registercategories(lctx, categories); 118 isc_log_setcontext(lctx); 119 120 destination.file.stream = logfile; 121 destination.file.name = NULL; 122 destination.file.versions = ISC_LOG_ROLLNEVER; 123 destination.file.maximum_size = 0; 124 CHECK(isc_log_createchannel(logconfig, "stderr", 125 ISC_LOG_TOFILEDESC, 126 ISC_LOG_DYNAMIC, 127 &destination, 0)); 128 CHECK(isc_log_usechannel(logconfig, "stderr", NULL, NULL)); 129 } 130 131#ifdef ISC_PLATFORM_USETHREADS 132 ncpus = isc_os_ncpus(); 133#else 134 ncpus = 1; 135#endif 136 137 if (start_managers) 138 CHECK(create_managers()); 139 140 return (ISC_R_SUCCESS); 141 142 cleanup: 143 isc_test_end(); 144 return (result); 145} 146 147void 148isc_test_end() { 149 if (maintask != NULL) 150 isc_task_detach(&maintask); 151 if (taskmgr != NULL) 152 isc_taskmgr_destroy(&taskmgr); 153 if (lctx != NULL) 154 isc_log_destroy(&lctx); 155 if (hash_active) { 156 isc_hash_destroy(); 157 hash_active = ISC_FALSE; 158 } 159 if (ectx != NULL) 160 isc_entropy_detach(&ectx); 161 162 cleanup_managers(); 163 164 if (mctx != NULL) 165 isc_mem_destroy(&mctx); 166} 167 168/* 169 * Sleep for 'usec' microseconds. 170 */ 171void 172isc_test_nap(isc_uint32_t usec) { 173#ifdef HAVE_NANOSLEEP 174 struct timespec ts; 175 176 ts.tv_sec = usec / 1000000; 177 ts.tv_nsec = (usec % 1000000) * 1000; 178 nanosleep(&ts, NULL); 179#elif HAVE_USLEEP 180 usleep(usec); 181#else 182 /* 183 * No fractional-second sleep function is available, so we 184 * round up to the nearest second and sleep instead 185 */ 186 sleep((usec / 1000000) + 1); 187#endif 188} 189