isctest.c revision 275970
1259701Sdim/*
2259701Sdim * Copyright (C) 2011, 2012  Internet Systems Consortium, Inc. ("ISC")
3259701Sdim *
4259701Sdim * Permission to use, copy, modify, and/or distribute this software for any
5259701Sdim * purpose with or without fee is hereby granted, provided that the above
6259701Sdim * copyright notice and this permission notice appear in all copies.
7259701Sdim *
8259701Sdim * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
9259701Sdim * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10259701Sdim * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
11259701Sdim * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12259701Sdim * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
13259701Sdim * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14259701Sdim * PERFORMANCE OF THIS SOFTWARE.
15259701Sdim */
16259701Sdim
17259701Sdim/* $Id$ */
18259701Sdim
19259701Sdim/*! \file */
20259701Sdim
21259701Sdim#include <config.h>
22259701Sdim
23259701Sdim#include <time.h>
24259701Sdim
25259701Sdim#include <isc/app.h>
26259701Sdim#include <isc/buffer.h>
27259701Sdim#include <isc/entropy.h>
28259701Sdim#include <isc/hash.h>
29259701Sdim#include <isc/mem.h>
30259701Sdim#include <isc/os.h>
31259701Sdim#include <isc/socket.h>
32259701Sdim#include <isc/string.h>
33259701Sdim#include <isc/task.h>
34259701Sdim#include <isc/timer.h>
35259701Sdim#include <isc/util.h>
36259701Sdim
37259701Sdim#include "isctest.h"
38259701Sdim
39259701Sdimisc_mem_t *mctx = NULL;
40259701Sdimisc_entropy_t *ectx = NULL;
41259701Sdimisc_log_t *lctx = NULL;
42259701Sdimisc_taskmgr_t *taskmgr = NULL;
43259701Sdimisc_timermgr_t *timermgr = NULL;
44259701Sdimisc_socketmgr_t *socketmgr = NULL;
45259701Sdimint ncpus;
46259701Sdim
47259701Sdimstatic isc_boolean_t hash_active = ISC_FALSE;
48259701Sdim
49259701Sdim/*
50259701Sdim * Logging categories: this needs to match the list in bin/named/log.c.
51259701Sdim */
52259701Sdimstatic isc_logcategory_t categories[] = {
53259701Sdim		{ "",                0 },
54259701Sdim		{ "client",          0 },
55259701Sdim		{ "network",         0 },
56259701Sdim		{ "update",          0 },
57259701Sdim		{ "queries",         0 },
58259701Sdim		{ "unmatched",       0 },
59259701Sdim		{ "update-security", 0 },
60259701Sdim		{ "query-errors",    0 },
61259701Sdim		{ NULL,              0 }
62259701Sdim};
63259701Sdim
64259701Sdimstatic void
65259701Sdimcleanup_managers() {
66259701Sdim	if (socketmgr != NULL)
67259701Sdim		isc_socketmgr_destroy(&socketmgr);
68259701Sdim	if (taskmgr != NULL)
69259701Sdim		isc_taskmgr_destroy(&taskmgr);
70259701Sdim	if (timermgr != NULL)
71259701Sdim		isc_timermgr_destroy(&timermgr);
72259701Sdim}
73259701Sdim
74259701Sdimstatic isc_result_t
75259701Sdimcreate_managers() {
76259701Sdim	isc_result_t result;
77259701Sdim#ifdef ISC_PLATFORM_USETHREADS
78259701Sdim	ncpus = isc_os_ncpus();
79259701Sdim#else
80259701Sdim	ncpus = 1;
81259701Sdim#endif
82259701Sdim
83259701Sdim	CHECK(isc_taskmgr_create(mctx, ncpus, 0, &taskmgr));
84259701Sdim	CHECK(isc_timermgr_create(mctx, &timermgr));
85259701Sdim	CHECK(isc_socketmgr_create(mctx, &socketmgr));
86259701Sdim	return (ISC_R_SUCCESS);
87259701Sdim
88259701Sdim  cleanup:
89259701Sdim	cleanup_managers();
90259701Sdim	return (result);
91259701Sdim}
92259701Sdim
93259701Sdimisc_result_t
94259701Sdimisc_test_begin(FILE *logfile, isc_boolean_t start_managers) {
95259701Sdim	isc_result_t result;
96259701Sdim
97259701Sdim	isc_mem_debugging |= ISC_MEM_DEBUGRECORD;
98259701Sdim	CHECK(isc_mem_create(0, 0, &mctx));
99259701Sdim	CHECK(isc_entropy_create(mctx, &ectx));
100259701Sdim
101259701Sdim	CHECK(isc_hash_create(mctx, ectx, 255));
102259701Sdim	hash_active = ISC_TRUE;
103259701Sdim
104259701Sdim	if (logfile != NULL) {
105259701Sdim		isc_logdestination_t destination;
106259701Sdim		isc_logconfig_t *logconfig = NULL;
107259701Sdim
108259701Sdim		CHECK(isc_log_create(mctx, &lctx, &logconfig));
109259701Sdim		isc_log_registercategories(lctx, categories);
110259701Sdim		isc_log_setcontext(lctx);
111259701Sdim
112259701Sdim		destination.file.stream = logfile;
113259701Sdim		destination.file.name = NULL;
114259701Sdim		destination.file.versions = ISC_LOG_ROLLNEVER;
115259701Sdim		destination.file.maximum_size = 0;
116259701Sdim		CHECK(isc_log_createchannel(logconfig, "stderr",
117259701Sdim					    ISC_LOG_TOFILEDESC,
118259701Sdim					    ISC_LOG_DYNAMIC,
119259701Sdim					    &destination, 0));
120259701Sdim		CHECK(isc_log_usechannel(logconfig, "stderr", NULL, NULL));
121259701Sdim	}
122259701Sdim
123259701Sdim#ifdef ISC_PLATFORM_USETHREADS
124259701Sdim	ncpus = isc_os_ncpus();
125259701Sdim#else
126259701Sdim	ncpus = 1;
127259701Sdim#endif
128259701Sdim
129259701Sdim	if (start_managers)
130259701Sdim		CHECK(create_managers());
131259701Sdim
132259701Sdim	return (ISC_R_SUCCESS);
133259701Sdim
134259701Sdim  cleanup:
135259701Sdim	isc_test_end();
136259701Sdim	return (result);
137259701Sdim}
138259701Sdim
139259701Sdimvoid
140259701Sdimisc_test_end() {
141259701Sdim	if (taskmgr != NULL)
142259701Sdim		isc_taskmgr_destroy(&taskmgr);
143259701Sdim	if (lctx != NULL)
144259701Sdim		isc_log_destroy(&lctx);
145259701Sdim	if (hash_active) {
146259701Sdim		isc_hash_destroy();
147259701Sdim		hash_active = ISC_FALSE;
148259701Sdim	}
149259701Sdim	if (ectx != NULL)
150259701Sdim		isc_entropy_detach(&ectx);
151259701Sdim
152259701Sdim	cleanup_managers();
153259701Sdim
154259701Sdim	if (mctx != NULL)
155259701Sdim		isc_mem_destroy(&mctx);
156259701Sdim}
157259701Sdim
158259701Sdim/*
159259701Sdim * Sleep for 'usec' microseconds.
160259701Sdim */
161259701Sdimvoid
162259701Sdimisc_test_nap(isc_uint32_t usec) {
163259701Sdim#ifdef HAVE_NANOSLEEP
164259701Sdim	struct timespec ts;
165259701Sdim
166259701Sdim	ts.tv_sec = usec / 1000000;
167259701Sdim	ts.tv_nsec = (usec % 1000000) * 1000;
168259701Sdim	nanosleep(&ts, NULL);
169259701Sdim#elif HAVE_USLEEP
170259701Sdim	usleep(usec);
171259701Sdim#else
172259701Sdim	/*
173259701Sdim	 * No fractional-second sleep function is available, so we
174259701Sdim	 * round up to the nearest second and sleep instead
175259701Sdim	 */
176259701Sdim	sleep((usec / 1000000) + 1);
177259701Sdim#endif
178259701Sdim}
179259701Sdim