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