xref: /freebsd/contrib/unbound/testdata/stat_values.tdir/stat_values.test (revision b2efd602aea8b3cbc3fb215b9611946d04fceb10)
1# #-- stat_values.test --#
2# source the master var file when it's there
3[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
4# use .tpkg.var.test for in test variable passing
5[ -f .tpkg.var.test ] && source .tpkg.var.test
6. ../common.sh
7
8PRE="../.."
9
10# Individual thread stats.
11STATS_IGNORE_THREAD="\
12^thread"
13
14# Histogram stats.
15STATS_IGNORE_HISTOGRAM="\
16^histogram"
17
18# Time dependent stats.
19STATS_IGNORE_TIME_SPECIFIC="\
20^total.recursion.time.avg=
21^total.recursion.time.median=
22^time.now=
23^time.up=
24^time.elapsed="
25
26# Usage dependent stats.
27STATS_IGNORE_USAGE_SPECIFIC="\
28^total.requestlist.avg=
29^total.requestlist.max=
30^total.requestlist.overwritten=
31^total.requestlist.exceeded=
32^total.requestlist.current.all=
33^total.requestlist.current.user=
34^total.tcpusage=
35^mem\."
36
37# Stats to ignore by default.
38STATS_IGNORE_DEFAULT="\
39$STATS_IGNORE_THREAD
40$STATS_IGNORE_HISTOGRAM
41$STATS_IGNORE_TIME_SPECIFIC
42$STATS_IGNORE_USAGE_SPECIFIC"
43
44# Various files to be used while testing.
45STATS_FILE=stats.$$
46EXPECTED_STATS_FILE=expected_stats.$$
47IGNORE_REGEX_FILE=ignore_regex.$$
48FILTERED_STATS_FILE=filtered_stats.$$
49FOUND_STATS_FILE=found_stats.$$
50REST_STATS_FILE=rest_stats.$$
51
52DEBUG=0
53
54if dig -h 2>&1 | grep "cookie" >/dev/null; then
55	nocookie="+nocookie"
56else
57	nocookie=""
58fi
59
60# Write stats to $STATS_FILE.
61# Call this when you want to get stats from unbound.
62get_stats () {
63	echo "> Getting stats"
64	echo "$PRE/unbound-control -c ub.conf stats"
65	$PRE/unbound-control -c ub.conf stats > $STATS_FILE
66	if test $? -ne 0; then
67		echo "wrong exit value after success"
68		exit 1
69	fi
70}
71
72# Set the expected stat values by writing to $EXPECTED_STATS_FILE.
73# sort is used for proper diff later.
74set_expected_stats () {
75	echo "$1" | sort > $EXPECTED_STATS_FILE
76}
77
78# Set the regex to ignore stats by writing to $IGNORE_REGEX_FILE.
79set_ignore_regex_stats () {
80	echo "$1" > $IGNORE_REGEX_FILE
81}
82
83# Filter the stats by removing any matched regex from $IGNORE_REGEX_FILE,
84# sorts and writes the left over stats to $FILTERED_STATS_FILE.
85filter_stats () {
86	grep -v -f $IGNORE_REGEX_FILE $STATS_FILE | sort > $FILTERED_STATS_FILE
87}
88
89# Check that the stats in $FILTERED_STATS_FILE include the expected stats in
90# $EXPECTED_STATS_FILE.
91check_expected_stats () {
92	echo "> Checking expected stats"
93	grep -F -x -f $EXPECTED_STATS_FILE $FILTERED_STATS_FILE > $FOUND_STATS_FILE
94	if test $DEBUG -ne 0; then
95		echo "Found:"
96		cat $FOUND_STATS_FILE
97	fi
98	if diff $EXPECTED_STATS_FILE $FOUND_STATS_FILE; then
99		echo "OK"
100	else
101		echo "! bad expected stats:"
102        cat $FILTERED_STATS_FILE
103		end 1
104	fi
105}
106
107# Check that the rest (unspecified) stats are all 0 (no surprises).
108check_rest_stats () {
109	echo "> Checking rest stats"
110	grep -F -x -v -f $EXPECTED_STATS_FILE $FILTERED_STATS_FILE > $REST_STATS_FILE
111	if test $DEBUG -ne 0; then
112		echo "Rest:"
113		cat $REST_STATS_FILE
114	fi
115	if grep -v "=0$" $REST_STATS_FILE; then
116		echo "! bad rest stats"
117		end 1
118	else
119		echo "OK"
120	fi
121}
122
123# Main function to check stats by:
124# - Getting stats from unbound
125# - Filtering out the stats we are not interested in
126# - Checking that the expected stats are part of the filtered stats
127# - The rest of the stats have 0 values.
128check_stats () {
129	set_expected_stats "$1"
130	if test $DEBUG -ne 0; then
131		echo "Expected:"
132		cat $EXPECTED_STATS_FILE
133	fi
134	get_stats
135	filter_stats
136	if test $DEBUG -ne 0; then
137		echo "Filtered:"
138		cat $FILTERED_STATS_FILE
139	fi
140	check_expected_stats
141	check_rest_stats
142}
143
144# Convenient function to set an option through unbound-control.
145set_ub_option () {
146	name=$1
147	value=$2
148	echo "$PRE/unbound-control -c ub.conf set_option $name: $value"
149	$PRE/unbound-control -c ub.conf set_option $name: $value
150	if test $? -ne 0; then
151		echo "wrong exit value after success"
152		exit 1
153	fi
154}
155
156# Convenient function to kill current Unbound and bring up one with an alternate configuration.
157bring_up_alternate_configuration () {
158	conf_file=$1
159	kill_pid $UNBOUND_PID  # kill current Unbound
160	echo ""
161	cat unbound.log
162	echo ""
163	$PRE/unbound -d -c $conf_file >unbound.log 2>&1 &
164	UNBOUND_PID=$!
165	echo "UNBOUND_PID=$UNBOUND_PID" >> .tpkg.var.test
166	wait_unbound_up unbound.log
167}
168
169# Convenient function to exit the test.
170end () {
171	echo "> cat logfiles"
172	cat fwd.log
173	cat unbound.log
174	if test $1 -eq 1; then
175		echo "Not OK"
176	else
177		echo "> OK"
178	fi
179	exit $1
180}
181
182# Ignore all run specific stats.
183set_ignore_regex_stats "$STATS_IGNORE_DEFAULT"
184
185# Check if the server is up.
186echo "> dig 1ttl.example.com."
187dig @127.0.0.1 -p $UNBOUND_PORT 1ttl.example.com. | tee outfile
188echo "> check answer"
189if grep "1.1.1.1" outfile; then
190	echo "OK"
191else
192	end 1
193fi
194
195
196teststep "Check initial stats based on first query."
197check_stats "\
198total.num.queries=1
199total.num.cachemiss=1
200total.num.recursivereplies=1
201num.query.type.A=1
202num.query.class.IN=1
203num.query.opcode.QUERY=1
204num.query.flags.RD=1
205num.query.flags.AD=1
206num.query.edns.present=1
207num.query.udpout=1
208msg.cache.count=1
209rrset.cache.count=1
210infra.cache.count=1
211num.answer.rcode.NOERROR=1"
212
213
214teststep "Check stat reset."
215check_stats "\
216msg.cache.count=1
217rrset.cache.count=1
218infra.cache.count=1"
219
220
221teststep "Enable serve-expired and check."
222set_ub_option serve-expired yes
223sleep 2  # make sure the TTL has expired.
224echo "> dig 1ttl.example.com."
225dig @127.0.0.1 -p $UNBOUND_PORT 1ttl.example.com. | tee outfile
226echo "> check answer"
227if grep "1.1.1.1" outfile; then
228	echo "OK"
229else
230	end 1
231fi
232check_stats "\
233total.num.queries=1
234total.num.expired=1
235total.num.cachehits=1
236total.num.prefetch=1
237num.answer.rcode.NOERROR=1
238num.query.class.IN=1
239num.query.edns.present=1
240num.query.flags.AD=1
241num.query.flags.RD=1
242num.query.opcode.QUERY=1
243num.query.type.A=1
244num.query.udpout=1
245msg.cache.count=1
246rrset.cache.count=1
247infra.cache.count=1"
248
249
250teststep "Enable serve-expired-client-timeout and check."
251set_ub_option serve-expired-client-timeout 1
252echo "> dig servfail.expired."
253dig @127.0.0.1 -p $UNBOUND_PORT servfail.expired. | tee outfile
254echo "> check answer"
255if grep "192.0.2.1" outfile; then
256	echo "OK"
257else
258	end 1
259fi
260check_stats "\
261total.num.queries=1
262total.num.cachemiss=1
263total.num.recursivereplies=1
264num.query.type.A=1
265num.query.class.IN=1
266num.query.opcode.QUERY=1
267num.query.flags.RD=1
268num.query.flags.AD=1
269num.query.edns.present=1
270num.query.udpout=1
271msg.cache.count=2
272rrset.cache.count=2
273infra.cache.count=2
274num.answer.rcode.NOERROR=1"
275kill_pid $FWD_EXPIRED_PID  # kill the expired forwarder to force a servfail from upstream.
276sleep 2  # make sure the TTL has expired.
277echo "> dig servfail.expired."
278dig @127.0.0.1 -p $UNBOUND_PORT servfail.expired. | tee outfile
279echo "> check answer"
280if grep "192.0.2.1" outfile; then
281	echo "OK"
282else
283	end 1
284fi
285sleep 1  # make sure the outgoing UDP (and no edns1xx0 retry because not a smaller buffer size) are accounted for.
286check_stats "\
287total.num.queries=1
288total.num.expired=1
289total.num.recursivereplies=1
290num.answer.rcode.NOERROR=1
291num.query.class.IN=1
292num.query.edns.present=1
293num.query.flags.AD=1
294num.query.flags.RD=1
295num.query.opcode.QUERY=1
296num.query.type.A=1
297num.query.udpout=1
298total.num.cachemiss=1
299msg.cache.count=2
300rrset.cache.count=2
301infra.cache.count=2"
302
303
304# Disable serve-expired
305set_ub_option serve-expired no
306
307
308teststep "Check REFUSED; try without RD flag."
309echo "> dig somethingelse.example.com."
310dig @127.0.0.1 -p $UNBOUND_PORT +nordflag somethingelse.example.com. | tee outfile
311echo "> check answer"
312if grep "REFUSED" outfile; then
313	echo "OK"
314else
315	end 1
316fi
317check_stats "\
318num.answer.rcode.REFUSED=1
319total.num.cachehits=1
320num.query.class.IN=1
321num.query.edns.present=1
322num.query.flags.AD=1
323num.query.opcode.QUERY=1
324num.query.type.A=1
325total.num.queries=1
326msg.cache.count=2
327rrset.cache.count=2
328infra.cache.count=2"
329
330
331teststep "Check the AD flag."
332echo "> dig www.example.com."
333dig @127.0.0.1 -p $UNBOUND_PORT +noadflag www.example.com. | tee outfile
334echo "> check answer"
335if grep "10.20.30.40" outfile; then
336	echo "OK"
337else
338	end 1
339fi
340check_stats "\
341num.query.flags.AD=0
342total.num.cachemiss=1
343num.answer.rcode.NOERROR=1
344num.query.class.IN=1
345num.query.edns.present=1
346num.query.flags.RD=1
347num.query.opcode.QUERY=1
348num.query.type.A=1
349num.query.udpout=1
350total.num.queries=1
351total.num.recursivereplies=1
352msg.cache.count=3
353rrset.cache.count=3
354infra.cache.count=2"
355
356
357teststep "Check local zone."
358echo "> dig www.local.zone."
359dig @127.0.0.1 -p $UNBOUND_PORT www.local.zone. | tee outfile
360echo "> check answer"
361if grep "192.0.2.1" outfile; then
362	echo "OK"
363else
364	end 1
365fi
366check_stats "\
367num.answer.rcode.NOERROR=1
368total.num.cachehits=1
369num.query.class.IN=1
370num.query.edns.present=1
371num.query.flags.AD=1
372num.query.flags.RD=1
373num.query.opcode.QUERY=1
374num.query.type.A=1
375total.num.queries=1
376msg.cache.count=3
377rrset.cache.count=3
378infra.cache.count=2"
379
380
381teststep "Check NXDOMAIN (with local data)."
382echo "> dig mail.local.zone."
383dig @127.0.0.1 -p $UNBOUND_PORT mail.local.zone. | tee outfile
384echo "> check answer"
385if grep "NXDOMAIN" outfile; then
386	echo "OK"
387else
388	end 1
389fi
390check_stats "\
391num.answer.rcode.NXDOMAIN=1
392total.num.cachehits=1
393num.query.class.IN=1
394num.query.edns.present=1
395num.query.flags.AD=1
396num.query.flags.RD=1
397num.query.opcode.QUERY=1
398num.query.type.A=1
399total.num.queries=1
400msg.cache.count=3
401rrset.cache.count=3
402infra.cache.count=2"
403
404
405teststep "Check CHAOS."
406echo "> dig id.server. ch txt"
407dig @127.0.0.1 -p $UNBOUND_PORT id.server. ch txt | tee outfile
408echo "> check answer"
409if grep "stat_values" outfile; then
410	echo "OK"
411else
412	end 1
413fi
414check_stats "\
415num.query.class.CH=1
416total.num.cachehits=1
417num.answer.rcode.NOERROR=1
418num.query.edns.present=1
419num.query.flags.AD=1
420num.query.flags.RD=1
421num.query.opcode.QUERY=1
422num.query.type.TXT=1
423total.num.queries=1
424msg.cache.count=3
425rrset.cache.count=3
426infra.cache.count=2"
427
428
429teststep "Check dns-error-reporting."
430echo "> dig www.bogusdnssec."
431dig @127.0.0.1 -p $UNBOUND_PORT www.bogusdnssec. | tee outfile
432echo "> check answer"
433if grep "SERVFAIL" outfile; then
434	echo "OK"
435else
436	end 1
437fi
438check_stats "\
439infra.cache.count=4
440key.cache.count=1
441msg.cache.count=7
442num.answer.bogus=1
443num.answer.rcode.SERVFAIL=1
444num.query.class.IN=1
445num.query.edns.present=1
446num.query.flags.AD=1
447num.query.flags.RD=1
448num.query.opcode.QUERY=1
449num.query.type.A=1
450num.query.udpout=9
451num.valops=6
452rrset.cache.count=5
453total.num.cachemiss=1
454total.num.dns_error_reports=1
455total.num.queries=1
456total.num.recursivereplies=1"
457
458
459###
460#
461# Bring the discard-timeout, wait-limit configured Unbound up
462#
463bring_up_alternate_configuration ub_discard_wait_limit.conf
464#
465###
466
467
468teststep "Check discard-timeout and wait-limit"
469echo "> dig www.unresponsive"
470dig @127.0.0.1 -p $UNBOUND_PORT +retry=2 +timeout=1 www.unresponsive. | tee outfile
471echo "> check answer"
472if grep "no servers could be reached" outfile; then
473	echo "OK"
474else
475	end 1
476fi
477check_stats "\
478infra.cache.count=1
479msg.cache.count=1
480num.query.class.IN=3
481num.query.edns.present=3
482num.query.flags.AD=3
483num.query.flags.RD=3
484num.query.opcode.QUERY=3
485num.query.type.A=3
486num.query.udpout=1
487total.num.cachemiss=3
488total.num.queries=3
489total.num.queries_discard_timeout=2
490total.num.queries_wait_limit=1"
491
492
493###
494#
495# Bring the downstream DNS Cookies configured Unbound up
496#
497bring_up_alternate_configuration ub_downstream_cookies.conf
498#
499###
500
501
502teststep "Get a DNS Cookie."
503echo "> dig www.local.zone +tcp $nocookie +ednsopt=10:0102030405060708"
504dig @127.0.0.1 -p $UNBOUND_PORT +tcp $nocookie +ednsopt=10:0102030405060708 +retry=0 +time=1 www.local.zone. | tee outfile
505echo "> check answer"
506if grep "192.0.2.1" outfile; then
507	echo "OK"
508else
509	end 1
510fi
511# Save valid cookie
512valid_cookie=`grep "COOKIE: " outfile | cut -d ' ' -f 3`
513invalid_cookie=`echo $valid_cookie | tr '0' '4'`
514check_stats "\
515total.num.queries=1
516total.num.queries_cookie_client=1
517total.num.cachehits=1
518num.query.type.A=1
519num.query.class.IN=1
520num.query.opcode.QUERY=1
521num.query.flags.RD=1
522num.query.flags.AD=1
523num.query.edns.present=1
524num.query.tcp=1
525num.answer.rcode.NOERROR=1"
526
527
528teststep "Present the valid DNS Cookie."
529echo "> dig www.local.zone $nocookie +ednsopt=10:valid_cookie"
530dig @127.0.0.1 -p $UNBOUND_PORT $nocookie +ednsopt=10:$valid_cookie +retry=0 +time=1 www.local.zone. | tee outfile
531echo "> check answer"
532if grep "192.0.2.1" outfile; then
533	echo "OK"
534else
535	end 1
536fi
537check_stats "\
538total.num.queries=1
539total.num.queries_cookie_valid=1
540total.num.cachehits=1
541num.query.type.A=1
542num.query.class.IN=1
543num.query.opcode.QUERY=1
544num.query.flags.RD=1
545num.query.flags.AD=1
546num.query.edns.present=1
547num.answer.rcode.NOERROR=1"
548
549
550teststep "Present an invalid DNS Cookie."
551echo "> dig www.local.zone $nocookie +ednsopt=10:invalid_cookie"
552dig @127.0.0.1 -p $UNBOUND_PORT $nocookie +ednsopt=10:$invalid_cookie +retry=0 +time=1 www.local.zone. | tee outfile
553echo "> check answer"
554if grep "192.0.2.1" outfile; then
555	end 1
556else
557	echo "OK"
558fi
559# A lot of stats are missing since BADCOOKIE error response is before
560# those stat calculations.
561# BADCOOKIE is an extended error code; we record YXRRSET below.
562check_stats "\
563total.num.queries=1
564total.num.queries_cookie_invalid=1
565total.num.cachehits=1
566num.answer.rcode.YXRRSET=1"
567
568
569teststep "Present no DNS Cookie."
570echo "> dig www.local.zone +ignore"
571dig @127.0.0.1 -p $UNBOUND_PORT +ignore $nocookie +retry=0 +time=1 www.local.zone. | tee outfile
572echo "> check answer"
573if grep "192.0.2.1" outfile; then
574	end 1
575else
576	echo "OK"
577fi
578# A lot of stats are missing since REFUSED error response because of no DNS
579# Cookie is before those stat calculations.
580check_stats "\
581total.num.queries=1
582total.num.cachehits=1
583num.answer.rcode.REFUSED=1"
584
585if test x$USE_CACHEDB = "x1"; then
586
587
588###
589#
590# Bring the cachedb configured Unbound up
591#
592bring_up_alternate_configuration ub_cachedb.conf
593#
594###
595
596
597teststep "Check cachedb cache miss."
598echo "> dig www.example.com."
599dig @127.0.0.1 +ednsopt=65534 -p $UNBOUND_PORT www.example.com. | tee outfile
600echo "> check answer"
601if grep "10.20.30.40" outfile; then
602	echo "OK"
603else
604	end 1
605fi
606check_stats "\
607total.num.queries=1
608total.num.cachemiss=1
609total.num.cachehits=0
610total.num.recursivereplies=1
611num.query.type.A=1
612num.query.class.IN=1
613num.query.opcode.QUERY=1
614num.query.flags.RD=1
615num.query.flags.AD=1
616num.query.edns.present=1
617num.query.udpout=1
618num.query.cachedb=0
619msg.cache.count=1
620rrset.cache.count=1
621infra.cache.count=1
622num.answer.rcode.NOERROR=1"
623
624
625teststep "Check cachedb cache hit."
626echo "> dig www.example.com."
627dig @127.0.0.1 +ednsopt=65534 -p $UNBOUND_PORT www.example.com. | tee outfile
628echo "> check answer"
629if grep "10.20.30.40" outfile; then
630	echo "OK"
631else
632	end 1
633fi
634check_stats "\
635total.num.queries=1
636total.num.cachemiss=1
637total.num.cachehits=0
638total.num.recursivereplies=1
639num.query.type.A=1
640num.query.class.IN=1
641num.query.opcode.QUERY=1
642num.query.flags.RD=1
643num.query.flags.AD=1
644num.query.edns.present=1
645num.query.udpout=0
646num.query.cachedb=1
647msg.cache.count=1
648rrset.cache.count=1
649infra.cache.count=1
650num.answer.rcode.NOERROR=1"
651
652
653teststep "Check cachedb cache hit with stat reset."
654echo "> dig www.example.com."
655dig @127.0.0.1 +ednsopt=65534 -p $UNBOUND_PORT www.example.com. | tee outfile
656echo "> check answer"
657if grep "10.20.30.40" outfile; then
658	echo "OK"
659else
660	end 1
661fi
662check_stats "\
663total.num.queries=1
664total.num.cachemiss=1
665total.num.cachehits=0
666total.num.recursivereplies=1
667num.query.type.A=1
668num.query.class.IN=1
669num.query.opcode.QUERY=1
670num.query.flags.RD=1
671num.query.flags.AD=1
672num.query.edns.present=1
673num.query.cachedb=1
674msg.cache.count=1
675rrset.cache.count=1
676infra.cache.count=1
677num.answer.rcode.NOERROR=1"
678
679fi  # USE_CACHEDB
680
681end 0
682