xref: /netbsd-src/external/mpl/bind/dist/bin/tests/system/tcp/tests.sh (revision cef8759bd76c1b621f8eab8faa6f208faabc2e15)
1#!/bin/sh
2#
3# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
4#
5# This Source Code Form is subject to the terms of the Mozilla Public
6# License, v. 2.0. If a copy of the MPL was not distributed with this
7# file, You can obtain one at http://mozilla.org/MPL/2.0/.
8#
9# See the COPYRIGHT file distributed with this work for additional
10# information regarding copyright ownership.
11
12set -e
13
14SYSTEMTESTTOP=..
15# shellcheck source=../conf.sh
16. "$SYSTEMTESTTOP/conf.sh"
17
18dig_with_opts() {
19	"${DIG}" -p "${PORT}" "$@"
20}
21
22rndccmd() {
23	"${RNDC}" -p "${CONTROLPORT}" -c ../common/rndc.conf -s "$@"
24}
25
26status=0
27n=0
28
29n=$((n + 1))
30echo_i "initializing TCP statistics ($n)"
31ret=0
32rndccmd 10.53.0.1 stats || ret=1
33rndccmd 10.53.0.2 stats || ret=1
34mv ns1/named.stats ns1/named.stats.test$n
35mv ns2/named.stats ns2/named.stats.test$n
36ntcp10="$(grep "TCP requests received" ns1/named.stats.test$n | tail -1 | awk '{print $1}')"
37ntcp20="$(grep "TCP requests received" ns2/named.stats.test$n | tail -1 | awk '{print $1}')"
38if [ $ret != 0 ]; then echo_i "failed"; fi
39status=$((status + ret))
40
41n=$((n + 1))
42echo_i "checking TCP request statistics (resolver) ($n)"
43ret=0
44dig_with_opts @10.53.0.3 txt.example. > dig.out.test$n
45sleep 1
46rndccmd 10.53.0.1 stats || ret=1
47rndccmd 10.53.0.2 stats || ret=1
48mv ns1/named.stats ns1/named.stats.test$n
49mv ns2/named.stats ns2/named.stats.test$n
50ntcp11="$(grep "TCP requests received" ns1/named.stats.test$n | tail -1 | awk '{print $1}')"
51ntcp21="$(grep "TCP requests received" ns2/named.stats.test$n | tail -1 | awk '{print $1}')"
52if [ "$ntcp10" -ge "$ntcp11" ]; then ret=1; fi
53if [ "$ntcp20" -ne "$ntcp21" ]; then ret=1; fi
54if [ $ret != 0 ]; then echo_i "failed"; fi
55status=$((status + ret))
56
57n=$((n + 1))
58echo_i "checking TCP request statistics (forwarder) ($n)"
59ret=0
60dig_with_opts @10.53.0.4 txt.example. > dig.out.test$n
61sleep 1
62rndccmd 10.53.0.1 stats || ret=1
63rndccmd 10.53.0.2 stats || ret=1
64mv ns1/named.stats ns1/named.stats.test$n
65mv ns2/named.stats ns2/named.stats.test$n
66ntcp12="$(grep "TCP requests received" ns1/named.stats.test$n | tail -1 | awk '{print $1}')"
67ntcp22="$(grep "TCP requests received" ns2/named.stats.test$n | tail -1 | awk '{print $1}')"
68if [ "$ntcp11" -ne "$ntcp12" ]; then ret=1; fi
69if [ "$ntcp21" -ge "$ntcp22" ];then ret=1; fi
70if [ $ret != 0 ]; then echo_i "failed"; fi
71status=$((status + ret))
72
73# -------- TCP high-water tests ----------
74refresh_tcp_stats() {
75	rndccmd 10.53.0.5 status > rndc.out.$n || ret=1
76	TCP_CUR="$(sed -n "s/^tcp clients: \([0-9][0-9]*\).*/\1/p" rndc.out.$n)"
77	TCP_LIMIT="$(sed -n "s/^tcp clients: .*\/\([0-9][0-9]*\)/\1/p" rndc.out.$n)"
78	TCP_HIGH="$(sed -n "s/^TCP high-water: \([0-9][0-9]*\)/\1/p" rndc.out.$n)"
79}
80
81# Send a command to the tool script listening on 10.53.0.6.
82send_command() {
83	nextpart ans6/ans.run > /dev/null
84	echo "$*" | "${PERL}" "${SYSTEMTESTTOP}/send.pl" 10.53.0.6 "${CONTROLPORT}"
85	wait_for_log_peek 10 "result=" ans6/ans.run || ret=1
86	if ! nextpartpeek ans6/ans.run | grep -qF "result=OK"; then
87		return 1
88	fi
89}
90
91# Instructs ans6 to open $1 TCP connections to 10.53.0.5.
92open_connections() {
93	send_command "open" "${1}" 10.53.0.5 "${PORT}" || return 1
94}
95
96# Instructs ans6 to close $1 TCP connections to 10.53.0.5.
97close_connections() {
98	send_command "close" "${1}" || return 1
99}
100
101# Check TCP connections are working normally before opening
102# multiple connections
103n=$((n + 1))
104echo_i "checking TCP query repsonse ($n)"
105ret=0
106dig_with_opts +tcp @10.53.0.5 txt.example > dig.out.test$n
107grep "status: NXDOMAIN" dig.out.test$n > /dev/null || ret=1
108if [ $ret != 0 ]; then echo_i "failed"; fi
109status=$((status + ret))
110
111# Check TCP statistics after server startup before using them as a baseline for
112# subsequent checks.
113n=$((n + 1))
114echo_i "TCP high-water: check initial statistics ($n)"
115ret=0
116refresh_tcp_stats
117assert_int_equal "${TCP_CUR}" 0 "current TCP clients count" || ret=1
118# We compare initial tcp-highwater value with 1 because as part of the
119# system test startup, the script start.pl executes dig to check if target
120# named is running, and that increments tcp-quota by one.
121assert_int_equal "${TCP_HIGH}" 1 "tcp-highwater count" || ret=1
122if [ $ret != 0 ]; then echo_i "failed"; fi
123status=$((status + ret))
124
125# Ensure the TCP high-water statistic gets updated after some TCP connections
126# are established.
127n=$((n + 1))
128echo_i "TCP high-water: check value after some TCP connections are established ($n)"
129ret=0
130OLD_TCP_CUR="${TCP_CUR}"
131TCP_ADDED=9
132open_connections "${TCP_ADDED}" || ret=1
133check_stats_added() {
134	refresh_tcp_stats
135	assert_int_equal "${TCP_CUR}" $((OLD_TCP_CUR + TCP_ADDED)) "current TCP clients count" || return 1
136	assert_int_equal "${TCP_HIGH}" $((OLD_TCP_CUR + TCP_ADDED)) "TCP high-water value" || return 1
137}
138retry 2 check_stats_added || ret=1
139if [ $ret != 0 ]; then echo_i "failed"; fi
140status=$((status + ret))
141
142# Ensure the TCP high-water statistic remains unchanged after some TCP
143# connections are closed.
144n=$((n + 1))
145echo_i "TCP high-water: check value after some TCP connections are closed ($n)"
146ret=0
147OLD_TCP_CUR="${TCP_CUR}"
148OLD_TCP_HIGH="${TCP_HIGH}"
149TCP_REMOVED=5
150close_connections "${TCP_REMOVED}" || ret=1
151check_stats_removed() {
152	refresh_tcp_stats
153	assert_int_equal "${TCP_CUR}" $((OLD_TCP_CUR - TCP_REMOVED)) "current TCP clients count" || return 1
154	assert_int_equal "${TCP_HIGH}" "${OLD_TCP_HIGH}" "TCP high-water value" || return 1
155}
156retry 2 check_stats_removed || ret=1
157if [ $ret != 0 ]; then echo_i "failed"; fi
158status=$((status + ret))
159
160# Ensure the TCP high-water statistic never exceeds the configured TCP clients
161# limit.
162n=$((n + 1))
163echo_i "TCP high-water: ensure tcp-clients is an upper bound ($n)"
164ret=0
165open_connections $((TCP_LIMIT + 1)) || ret=1
166check_stats_limit() {
167	refresh_tcp_stats
168	assert_int_equal "${TCP_CUR}" "${TCP_LIMIT}" "current TCP clients count" || return 1
169	assert_int_equal "${TCP_HIGH}" "${TCP_LIMIT}" "TCP high-water value" || return 1
170}
171retry 2 check_stats_limit || ret=1
172if [ $ret != 0 ]; then echo_i "failed"; fi
173status=$((status + ret))
174
175# Check TCP connections are working normally before opening
176# multiple connections
177n=$((n + 1))
178echo_i "checking TCP response recovery ($n)"
179ret=0
180# "0" closes all connections
181close_connections 0 || ret=1
182dig_with_opts +tcp @10.53.0.5 txt.example > dig.out.test$n || ret=1
183grep "status: NXDOMAIN" dig.out.test$n > /dev/null || ret=1
184if [ $ret != 0 ]; then echo_i "failed"; fi
185status=$((status + ret))
186
187echo_i "exit status: $status"
188[ $status -eq 0 ] || exit 1
189