From: Štěpán Balážik Date: Sat, 25 Apr 2026 14:00:38 +0000 (+0200) Subject: Port TCP request statistics checks to Python X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a10e40068cc23b66849b791ca3fa49c04bb825d0;p=thirdparty%2Fbind9.git Port TCP request statistics checks to Python Add a helper that runs `rndc stats` and reads the TCP request counter from named.stats, then use it to port the resolver and forwarder checks from the shell script to tests_tcp.py. Record named.stats as an extra artifact so the generated statistics remain available after test runs. --- diff --git a/bin/tests/system/tcp/tests.sh b/bin/tests/system/tcp/tests.sh index 18276c8441b..3e0f203c5e3 100644 --- a/bin/tests/system/tcp/tests.sh +++ b/bin/tests/system/tcp/tests.sh @@ -27,50 +27,6 @@ rndccmd() { status=0 n=0 -n=$((n + 1)) -echo_i "initializing TCP statistics ($n)" -ret=0 -rndccmd 10.53.0.1 stats || ret=1 -rndccmd 10.53.0.2 stats || ret=1 -mv ns1/named.stats ns1/named.stats.test$n -mv ns2/named.stats ns2/named.stats.test$n -ntcp10="$(grep "TCP requests received" ns1/named.stats.test$n | tail -1 | awk '{print $1}')" -ntcp20="$(grep "TCP requests received" ns2/named.stats.test$n | tail -1 | awk '{print $1}')" -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking TCP request statistics (resolver) ($n)" -ret=0 -dig_with_opts @10.53.0.3 txt.example. >dig.out.test$n -sleep 1 -rndccmd 10.53.0.1 stats || ret=1 -rndccmd 10.53.0.2 stats || ret=1 -mv ns1/named.stats ns1/named.stats.test$n -mv ns2/named.stats ns2/named.stats.test$n -ntcp11="$(grep "TCP requests received" ns1/named.stats.test$n | tail -1 | awk '{print $1}')" -ntcp21="$(grep "TCP requests received" ns2/named.stats.test$n | tail -1 | awk '{print $1}')" -if [ "$ntcp10" -ge "$ntcp11" ]; then ret=1; fi -if [ "$ntcp20" -ne "$ntcp21" ]; then ret=1; fi -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking TCP request statistics (forwarder) ($n)" -ret=0 -dig_with_opts @10.53.0.4 txt.example. >dig.out.test$n -sleep 1 -rndccmd 10.53.0.1 stats || ret=1 -rndccmd 10.53.0.2 stats || ret=1 -mv ns1/named.stats ns1/named.stats.test$n -mv ns2/named.stats ns2/named.stats.test$n -ntcp12="$(grep "TCP requests received" ns1/named.stats.test$n | tail -1 | awk '{print $1}')" -ntcp22="$(grep "TCP requests received" ns2/named.stats.test$n | tail -1 | awk '{print $1}')" -if [ "$ntcp11" -ne "$ntcp12" ]; then ret=1; fi -if [ "$ntcp21" -ge "$ntcp22" ]; then ret=1; fi -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - # -------- TCP high-water tests ---------- refresh_tcp_stats() { rndccmd 10.53.0.5 status >rndc.out.$n || ret=1 diff --git a/bin/tests/system/tcp/tests_sh_tcp.py b/bin/tests/system/tcp/tests_sh_tcp.py index 0e0c9fc0e50..f2430db9eee 100644 --- a/bin/tests/system/tcp/tests_sh_tcp.py +++ b/bin/tests/system/tcp/tests_sh_tcp.py @@ -17,7 +17,6 @@ pytestmark = pytest.mark.extra_artifacts( "rndc.out.*", "ans*/ans.run", "ans*/ans.run.prev", - "ns*/named.stats.*", ] ) diff --git a/bin/tests/system/tcp/tests_tcp.py b/bin/tests/system/tcp/tests_tcp.py index 6a05bc202a9..bcf6a60dc53 100644 --- a/bin/tests/system/tcp/tests_tcp.py +++ b/bin/tests/system/tcp/tests_tcp.py @@ -21,9 +21,11 @@ import dns.query import dns.rrset import pytest +from isctest.instance import NamedInstance + import isctest -pytestmark = pytest.mark.extra_artifacts(["ans*/ans.run"]) +pytestmark = pytest.mark.extra_artifacts(["ans*/ans.run", "ns*/named.stats"]) TIMEOUT: int = 10 @@ -34,6 +36,20 @@ def create_socket(host: str, port: int) -> socket.socket: return sock +def tcp_requests_received(ns: NamedInstance) -> int: + ns.rndc("stats") + stats_file = ns.directory / "named.stats" + last_count: int | None = None + + with open(stats_file, "r", encoding="utf-8") as stats: + for line in stats: + if "TCP requests received" in line: + last_count = int(line.split()[0]) + + assert last_count is not None, f"'TCP requests received' not found in {stats_file}" + return last_count + + def tcp_round_trip( sock: socket.socket, msg: dns.message.Message ) -> dns.message.Message: @@ -131,3 +147,31 @@ def test_tcp_big(named_port: int) -> None: "a.example.", "A", dnssec=False, use_edns=-1, ad=False ) tcp_round_trip(sock, msg) + + +def test_tcp_request_statistics( + ns1: NamedInstance, ns2: NamedInstance, ns3: NamedInstance, ns4: NamedInstance +) -> None: + isctest.log.info("initializing TCP statistics") + ns1_tcp = tcp_requests_received(ns1) + ns2_tcp = tcp_requests_received(ns2) + + isctest.log.info("checking TCP request statistics (resolver)") + msg = isctest.query.create("txt.example.", "A") + isctest.query.udp(msg, ns3.ip) + time.sleep(1) + + ns1_tcp_after_resolver = tcp_requests_received(ns1) + ns2_tcp_after_resolver = tcp_requests_received(ns2) + assert ns1_tcp < ns1_tcp_after_resolver + assert ns2_tcp == ns2_tcp_after_resolver + + isctest.log.info("checking TCP request statistics (forwarder)") + msg = isctest.query.create("txt.example.", "A") + isctest.query.udp(msg, ns4.ip) + time.sleep(1) + + ns1_tcp_after_forwarder = tcp_requests_received(ns1) + ns2_tcp_after_forwarder = tcp_requests_received(ns2) + assert ns1_tcp_after_resolver == ns1_tcp_after_forwarder + assert ns2_tcp_after_resolver < ns2_tcp_after_forwarder