xref: /minix/external/bsd/bind/dist/bin/tests/log_test.c (revision fb9c64b2)
1 /*	$NetBSD: log_test.c,v 1.6 2014/12/10 04:37:53 christos Exp $	*/
2 
3 /*
4  * Copyright (C) 2004, 2007, 2011, 2014  Internet Systems Consortium, Inc. ("ISC")
5  * Copyright (C) 1999-2001  Internet Software Consortium.
6  *
7  * Permission to use, copy, modify, and/or distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 /* Id: log_test.c,v 1.29 2011/08/28 23:46:51 marka Exp  */
21 
22 /* Principal Authors: DCL */
23 
24 #include <config.h>
25 
26 #include <stdlib.h>
27 #include <unistd.h>
28 
29 #include <isc/commandline.h>
30 #include <isc/mem.h>
31 #include <isc/string.h>
32 #include <isc/util.h>
33 
34 #include <dns/log.h>
35 
36 #define TEST_FILE "/tmp/test_log"
37 #define SYSLOG_FILE "/var/log/daemon.log"
38 #define FILE_VERSIONS 10
39 
40 char usage[] = "Usage: %s [-m] [-s syslog_logfile] [-r file_versions]\n";
41 
42 #define CHECK(expr) result = expr; \
43 	if (result != ISC_R_SUCCESS) { \
44 		fprintf(stderr, "%s: " #expr "%s: exiting\n", \
45 			progname, isc_result_totext(result)); \
46 	}
47 
48 int
49 main(int argc, char **argv) {
50 	const char *progname, *syslog_file, *message;
51 	int ch, i, file_versions, stderr_line;
52 	isc_boolean_t show_final_mem = ISC_FALSE;
53 	isc_log_t *lctx;
54 	isc_logconfig_t *lcfg;
55 	isc_mem_t *mctx;
56 	isc_result_t result;
57 	isc_logdestination_t destination;
58 	const isc_logcategory_t *category;
59 	const isc_logmodule_t *module;
60 
61 	progname = strrchr(*argv, '/');
62 	if (progname != NULL)
63 		progname++;
64 	else
65 		progname = *argv;
66 
67 	syslog_file = SYSLOG_FILE;
68 	file_versions = FILE_VERSIONS;
69 
70 	while ((ch = isc_commandline_parse(argc, argv, "ms:r:")) != -1) {
71 		switch (ch) {
72 		case 'm':
73 			show_final_mem = ISC_TRUE;
74 			break;
75 		case 's':
76 			syslog_file = isc_commandline_argument;
77 			break;
78 		case 'r':
79 			file_versions = atoi(isc_commandline_argument);
80 			if (file_versions < 0 &&
81 			    file_versions != ISC_LOG_ROLLNEVER &&
82 			    file_versions != ISC_LOG_ROLLINFINITE) {
83 				fprintf(stderr, "%s: file rotations must be "
84 					"%d (ISC_LOG_ROLLNEVER),\n\t"
85 					"%d (ISC_LOG_ROLLINFINITE) "
86 					"or > 0\n", progname,
87 					ISC_LOG_ROLLNEVER,
88 					ISC_LOG_ROLLINFINITE);
89 				exit(1);
90 			}
91 			break;
92 		case '?':
93 			fprintf(stderr, usage, progname);
94 			exit(1);
95 		}
96 	}
97 
98 	argc -= isc_commandline_index;
99 	argv += isc_commandline_index;
100 	POST(argv);
101 
102 	if (argc > 0) {
103 		fprintf(stderr, usage, progname);
104 		exit(1);
105 	}
106 
107 	fprintf(stderr, "EXPECT:\n%s%d%s%s%s",
108 		"8 lines to stderr (first 4 numbered, #3 repeated)\n",
109 		file_versions == 0 || file_versions == ISC_LOG_ROLLNEVER ? 1 :
110 		file_versions > 0 ? file_versions + 1 : FILE_VERSIONS + 1,
111 		" " TEST_FILE " files, and\n",
112 		"2 lines to syslog\n",
113 		"lines ending with exclamation marks are errors\n\n");
114 
115 	isc_log_opensyslog(progname, LOG_PID, LOG_DAEMON);
116 
117 	mctx = NULL;
118 	lctx = NULL;
119 	lcfg = NULL;
120 
121 	CHECK(isc_mem_create(0, 0, &mctx));
122 	CHECK(isc_log_create(mctx, &lctx, &lcfg));
123 
124 	CHECK(isc_log_settag(lcfg, progname));
125 
126 	isc_log_setcontext(lctx);
127 	dns_log_init(lctx);
128 	dns_log_setcontext(lctx);
129 
130 	/*
131 	 * Test isc_log_categorybyname and isc_log_modulebyname.
132 	 */
133 	category = isc_log_categorybyname(lctx, "notify");
134 	if (category != NULL)
135 		fprintf(stderr, "%s category found. (expected)\n",
136 			category->name);
137 	else
138 		fprintf(stderr, "notify category not found!\n");
139 
140 	module = isc_log_modulebyname(lctx, "xyzzy");
141 	if (module != NULL)
142 		fprintf(stderr, "%s module found!\n", module->name);
143 	else
144 		fprintf(stderr, "xyzzy module not found. (expected)\n");
145 
146 	/*
147 	 * Create a file channel to test file opening, size limiting and
148 	 * version rolling.
149 	 */
150 
151 	destination.file.name = TEST_FILE;
152 	destination.file.maximum_size = 1;
153 	destination.file.versions = file_versions;
154 
155 	CHECK(isc_log_createchannel(lcfg, "file_test", ISC_LOG_TOFILE,
156 				    ISC_LOG_INFO, &destination,
157 				    ISC_LOG_PRINTTIME|
158 				    ISC_LOG_PRINTTAG|
159 				    ISC_LOG_PRINTLEVEL|
160 				    ISC_LOG_PRINTCATEGORY|
161 				    ISC_LOG_PRINTMODULE));
162 
163 	/*
164 	 * Create a dynamic debugging channel to a file descriptor.
165 	 */
166 	destination.file.stream = stderr;
167 
168 	CHECK(isc_log_createchannel(lcfg, "debug_test", ISC_LOG_TOFILEDESC,
169 				    ISC_LOG_DYNAMIC, &destination,
170 				    ISC_LOG_PRINTTIME|
171 				    ISC_LOG_PRINTLEVEL|
172 				    ISC_LOG_DEBUGONLY));
173 
174 	/*
175 	 * Test the usability of the four predefined logging channels.
176 	 */
177 	CHECK(isc_log_usechannel(lcfg, "default_syslog",
178 				 DNS_LOGCATEGORY_DATABASE,
179 				 DNS_LOGMODULE_CACHE));
180 	CHECK(isc_log_usechannel(lcfg, "default_stderr",
181 				 DNS_LOGCATEGORY_DATABASE,
182 				 DNS_LOGMODULE_CACHE));
183 	CHECK(isc_log_usechannel(lcfg, "default_debug",
184 				 DNS_LOGCATEGORY_DATABASE,
185 				 DNS_LOGMODULE_CACHE));
186 	CHECK(isc_log_usechannel(lcfg, "null",
187 				 DNS_LOGCATEGORY_DATABASE,
188 				 NULL));
189 
190 	/*
191 	 * Use the custom channels.
192 	 */
193 	CHECK(isc_log_usechannel(lcfg, "file_test",
194 				 DNS_LOGCATEGORY_GENERAL,
195 				 DNS_LOGMODULE_DB));
196 
197 	CHECK(isc_log_usechannel(lcfg, "debug_test",
198 				 DNS_LOGCATEGORY_GENERAL,
199 				 DNS_LOGMODULE_RBTDB));
200 
201 	fprintf(stderr, "\n==> stderr begin\n");
202 
203 	/*
204 	 * Write to the internal default by testing both a category for which
205 	 * no channel has been specified and a category which was specified
206 	 * but not with the named module.
207 	 */
208 	stderr_line = 1;
209 
210 	isc_log_write(lctx, DNS_LOGCATEGORY_SECURITY, DNS_LOGMODULE_RBT,
211 		      ISC_LOG_CRITICAL, "%s (%d)",
212 		      "Unspecified category and unspecified module to stderr",
213 		      stderr_line++);
214 	isc_log_write(lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_RBT,
215 		      ISC_LOG_CRITICAL, "%s (%d)",
216 		      "Specified category and unspecified module to stderr",
217 		      stderr_line++);
218 
219 	/*
220 	 * Write to default_syslog, default_stderr and default_debug.
221 	 */
222 	isc_log_write(lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_CACHE,
223 		      ISC_LOG_WARNING, "%s (%d twice)",
224 		      "Using the predefined channels to syslog+stderr",
225 		      stderr_line++);
226 
227 	/*
228 	 * Write to predefined null channel.
229 	 */
230 	isc_log_write(lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_RBTDB,
231 		      ISC_LOG_INFO, "This is to null and should not appear!");
232 
233 	/*
234 	 * Reset the internal default to use syslog instead of stderr,
235 	 * and test it.
236 	 */
237 	CHECK(isc_log_usechannel(lcfg, "default_syslog",
238 				 ISC_LOGCATEGORY_DEFAULT, NULL));
239 	isc_log_write(lctx, DNS_LOGCATEGORY_SECURITY, DNS_LOGMODULE_RBT,
240 		      ISC_LOG_ERROR, "%s%s",
241 		      "This message to the redefined default category should ",
242 		      "be second in syslog");
243 	/*
244 	 * Write to the file channel.
245 	 */
246 	if (file_versions >= 0 || file_versions == ISC_LOG_ROLLINFINITE) {
247 
248 		/*
249 		 * If file_versions is 0 or ISC_LOG_ROLLINFINITE, write
250 		 * the "should not appear" and "should be in file" messages
251 		 * to ensure they get rolled.
252 		 */
253 		if (file_versions <= 0)
254 			file_versions = FILE_VERSIONS;
255 
256 		else
257 			isc_log_write(lctx, DNS_LOGCATEGORY_GENERAL,
258 				      DNS_LOGMODULE_DB, ISC_LOG_NOTICE,
259 				      "This should be rolled over "
260 				      "and not appear!");
261 
262 		for (i = file_versions - 1; i >= 0; i--)
263 			isc_log_write(lctx, DNS_LOGCATEGORY_GENERAL,
264 				      DNS_LOGMODULE_DB, ISC_LOG_NOTICE,
265 				      "should be in file %d/%d", i,
266 				      file_versions - 1);
267 
268 		isc_log_write(lctx, DNS_LOGCATEGORY_GENERAL,
269 			      DNS_LOGMODULE_DB, ISC_LOG_NOTICE,
270 			      "should be in base file");
271 	} else {
272 		file_versions = FILE_VERSIONS;
273 		for (i = 1; i <= file_versions; i++)
274 			isc_log_write(lctx, DNS_LOGCATEGORY_GENERAL,
275 				      DNS_LOGMODULE_DB, ISC_LOG_NOTICE,
276 				      "This is message %d in the log file", i);
277 	}
278 
279 
280 	/*
281 	 * Write a debugging message to a category that has no
282 	 * debugging channels for the named module.
283 	 */
284 	isc_log_write(lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_DB,
285 		      ISC_LOG_DEBUG(1),
286 		      "This debug message should not appear!");
287 
288 	/*
289 	 * Write debugging messages to a dynamic debugging channel.
290 	 */
291 	isc_log_write(lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_RBTDB,
292 		      ISC_LOG_CRITICAL, "This critical message should "
293 		      "not appear because the debug level is 0!");
294 
295 	isc_log_setdebuglevel(lctx, 3);
296 
297 	isc_log_write(lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_RBTDB,
298 		      ISC_LOG_DEBUG(1), "%s (%d)",
299 		      "Dynamic debugging to stderr", stderr_line++);
300 	isc_log_write(lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_RBTDB,
301 		      ISC_LOG_DEBUG(5),
302 		      "This debug level is too high and should not appear!");
303 
304 	/*
305 	 * Test out the duplicate filtering using the debug_test channel.
306 	 */
307 	isc_log_setduplicateinterval(lcfg, 10);
308 	message = "This message should appear only once on stderr";
309 
310 	isc_log_write1(lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_RBTDB,
311 		       ISC_LOG_CRITICAL, "%s", message);
312 	isc_log_write1(lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_RBTDB,
313 		       ISC_LOG_CRITICAL, "%s", message);
314 
315 	isc_log_setduplicateinterval(lcfg, 1);
316 	message = "This message should appear twice on stderr";
317 
318 	isc_log_write1(lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_RBTDB,
319 		       ISC_LOG_CRITICAL, "%s", message);
320 	sleep(2);
321 	isc_log_write1(lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_RBTDB,
322 		       ISC_LOG_CRITICAL, "%s", message);
323 
324 	/*
325 	 * Review where everything went.
326 	 * XXXDCL NT
327 	 */
328 	fputc('\n', stderr);
329 	if (system("head " TEST_FILE "*; rm -f " TEST_FILE "*") != 0) {
330 		fprintf(stderr, "system(\"head " TEST_FILE "*; rm -f "
331 			TEST_FILE "*\") failed\n");
332 		goto cleanup;
333 	}
334 
335 	/* This is highly system specific. */
336 	if (freopen(syslog_file, "r", stdin) == NULL) {
337 		fprintf(stderr, "freopen(%s, \"r\", stdin) failed\n",
338 			syslog_file);
339 		goto cleanup;
340 	}
341 	fprintf(stderr, "\n==> %s <==\n", syslog_file);
342 	if (system("tail -2") != 0) {
343 		fprintf(stderr, "system(\"tail -2\") failed\n");
344 		goto cleanup;
345 	}
346 	fputc('\n', stderr);
347 
348  cleanup:
349 	isc_log_destroy(&lctx);
350 
351 	if (show_final_mem)
352 		isc_mem_stats(mctx, stderr);
353 
354 	return (0);
355 }
356