From 624c20b191dc518d7ef65982fcc9fbdd8db07876 Mon Sep 17 00:00:00 2001 From: Michal Nowak Date: Tue, 9 May 2023 19:11:00 +0200 Subject: [PATCH 1/2] Rewrite stress test to pytest The shell version of the test was completed only after all DNS zone updates were sent, even if the BIND server crashed while processing them, leading to prolonged execution and potential hang in the CI environment. The Python rewrite of the test ensures that DNS update tasks finish within five minutes of starting, irrespective of a BIND crash possibility or DNS zone updates not finishing in time. (cherry picked from commit ecd7b30d0ac9f2ada45448f9adf7c9a22f33b122) --- bin/tests/system/stress/clean.sh | 2 - bin/tests/system/stress/tests.sh | 44 -------- bin/tests/system/stress/tests_sh_stress.py | 14 --- .../system/stress/tests_stress_update.py | 79 ++++++++++++++ bin/tests/system/stress/update.pl | 101 ------------------ 5 files changed, 79 insertions(+), 161 deletions(-) delete mode 100644 bin/tests/system/stress/tests.sh delete mode 100644 bin/tests/system/stress/tests_sh_stress.py create mode 100644 bin/tests/system/stress/tests_stress_update.py delete mode 100644 bin/tests/system/stress/update.pl diff --git a/bin/tests/system/stress/clean.sh b/bin/tests/system/stress/clean.sh index b365d7cc77..0396845cbd 100644 --- a/bin/tests/system/stress/clean.sh +++ b/bin/tests/system/stress/clean.sh @@ -11,8 +11,6 @@ # See the COPYRIGHT file distributed with this work for additional # information regarding copyright ownership. -rm -f reload.pid - rm -f ns?/zones.conf rm -f ns?/zone*.bk diff --git a/bin/tests/system/stress/tests.sh b/bin/tests/system/stress/tests.sh deleted file mode 100644 index 5466ecbbf8..0000000000 --- a/bin/tests/system/stress/tests.sh +++ /dev/null @@ -1,44 +0,0 @@ -#!/bin/sh - -# Copyright (C) Internet Systems Consortium, Inc. ("ISC") -# -# SPDX-License-Identifier: MPL-2.0 -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, you can obtain one at https://mozilla.org/MPL/2.0/. -# -# See the COPYRIGHT file distributed with this work for additional -# information regarding copyright ownership. - -set -e - -. ../conf.sh - -status=0 - -( -$SHELL -c "while true - do $RNDC -c ../common/rndc.conf -s 10.53.0.3 -p $CONTROLPORT reload 2>&1 | - sed 's/^/I:ns3 /'; - sleep 1 - done" & echo $! >reload.pid -) & - -for i in 0 1 2 3 4 -do - $PERL update.pl -s 10.53.0.2 -p $PORT zone00000$i.example. & -done - -echo_i "waiting for background processes to finish" -wait - -echo_i "killing reload loop" -kill $(cat reload.pid) - -# If the test has run to completion without named crashing, it has succeeded. -# Otherwise, the crash will be detected by the test framework and the test will -# fail. - -echo_i "exit status: $status" -[ $status -eq 0 ] || exit 1 diff --git a/bin/tests/system/stress/tests_sh_stress.py b/bin/tests/system/stress/tests_sh_stress.py deleted file mode 100644 index 283e2617b6..0000000000 --- a/bin/tests/system/stress/tests_sh_stress.py +++ /dev/null @@ -1,14 +0,0 @@ -# Copyright (C) Internet Systems Consortium, Inc. ("ISC") -# -# SPDX-License-Identifier: MPL-2.0 -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, you can obtain one at https://mozilla.org/MPL/2.0/. -# -# See the COPYRIGHT file distributed with this work for additional -# information regarding copyright ownership. - - -def test_stress(run_tests_sh): - run_tests_sh() diff --git a/bin/tests/system/stress/tests_stress_update.py b/bin/tests/system/stress/tests_stress_update.py new file mode 100644 index 0000000000..d326f14b7f --- /dev/null +++ b/bin/tests/system/stress/tests_stress_update.py @@ -0,0 +1,79 @@ +# Copyright (C) Internet Systems Consortium, Inc. ("ISC") +# +# SPDX-License-Identifier: MPL-2.0 +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, you can obtain one at https://mozilla.org/MPL/2.0/. +# +# See the COPYRIGHT file distributed with this work for additional +# information regarding copyright ownership. + +import concurrent.futures +import os +import subprocess +import time +import dns.query +import dns.update + + +def rndc_loop(test_state, server): + rndc = os.getenv("RNDC") + port = os.getenv("CONTROLPORT") + + cmdline = [ + rndc, + "-c", + "../common/rndc.conf", + "-p", + port, + "-s", + server, + "reload", + ] + + while not test_state["finished"]: + subprocess.run(cmdline, check=False) + time.sleep(1) + + +def update_zone(test_state, zone, named_port, logger): + server = "10.53.0.2" + for i in range(1000): + if test_state["finished"]: + return + update = dns.update.UpdateMessage(zone) + update.add(f"dynamic-{i}.{zone}", 300, "TXT", f"txt-{i}") + try: + response = dns.query.udp(update, server, 10, named_port) + assert response.rcode() == dns.rcode.NOERROR + except dns.exception.Timeout: + logger.info(f"error: query timeout for {zone}") + + logger.info(f"Update of {server} zone {zone} successful") + + +# If the test has run to completion without named crashing, it has succeeded. +def test_update_stress(named_port, logger): + test_state = {"finished": False} + + with concurrent.futures.ThreadPoolExecutor() as executor: + executor.submit(rndc_loop, test_state, "10.53.0.3") + + updaters = [] + for i in range(5): + zone = f"zone00000{i}.example." + updaters.append( + executor.submit(update_zone, test_state, zone, named_port, logger) + ) + + # All the update_zone() tasks are expected to complete within 5 + # minutes. If they do not, we cannot assert immediately as that will + # cause the ThreadPoolExecutor context manager to wait indefinitely; + # instead, we first signal all tasks that it is time to exit and only + # check whether any task failed to finish within 5 minutes outside of + # the ThreadPoolExecutor context manager. + unfinished_tasks = concurrent.futures.wait(updaters, timeout=300).not_done + test_state["finished"] = True + + assert not unfinished_tasks diff --git a/bin/tests/system/stress/update.pl b/bin/tests/system/stress/update.pl deleted file mode 100644 index 1276b21728..0000000000 --- a/bin/tests/system/stress/update.pl +++ /dev/null @@ -1,101 +0,0 @@ -#!/usr/bin/perl - -# Copyright (C) Internet Systems Consortium, Inc. ("ISC") -# -# SPDX-License-Identifier: MPL-2.0 -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, you can obtain one at https://mozilla.org/MPL/2.0/. -# -# See the COPYRIGHT file distributed with this work for additional -# information regarding copyright ownership. - -# -# Dynamic update test suite. -# -# Usage: -# -# perl update_test.pl [-s server] [-p port] zone -# -# The server defaults to 127.0.0.1. -# The port defaults to 53. -# -# The "Special NS rules" tests will only work correctly if the -# has no NS records to begin with, or alternatively has a -# single NS record pointing at the name "ns1" (relative to -# the zone name). -# -# Installation notes: -# -# This program uses the Net::DNS::Resolver module. -# You can install it by saying -# -# perl -MCPAN -e "install Net::DNS" -# - -use Getopt::Std; -use Net::DNS; -use Net::DNS::Update; -use Net::DNS::Resolver; - -$opt_s = "127.0.0.1"; -$opt_p = 53; - -getopt('s:p:'); - -$res = new Net::DNS::Resolver; -$res->nameservers($opt_s); -$res->port($opt_p); -$res->defnames(0); # Do not append default domain. - -@ARGV == 1 or die - "usage: perl update_test.pl [-s server] [-p port] zone\n"; - -$zone = shift @ARGV; - -my $failures = 0; - -sub assert { - my ($cond, $explanation) = @_; - if (!$cond) { - print "I:Test Failed: $explanation ***\n"; - $failures++ - } -} - -sub test { - my ($expected, @records) = @_; - - my $update = new Net::DNS::Update("$zone"); - - foreach $rec (@records) { - $update->push(@$rec); - } - - $reply = $res->send($update); - - # Did it work? - if (defined $reply) { - my $rcode = $reply->header->rcode; - assert($rcode eq $expected, "expected $expected, got $rcode"); - } else { - print "I:Update failed: ", $res->errorstring, "\n"; - } -} - -sub section { - my ($msg) = @_; - print "I:$msg\n"; -} - -for ($i = 0; $i < 1000; $i++) { - test("NOERROR", ["update", rr_add("dynamic-$i.$zone 300 TXT txt-$i" )]); -} - -if ($failures) { - print "I:$failures tests failed.\n"; -} else { - print "I:Update of $opt_s zone $zone successful.\n"; -} -exit $failures; From dbdc70cbe088b2296aa25dff28c5d4f6fe0667aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20K=C4=99pie=C5=84?= Date: Tue, 11 Jul 2023 15:56:31 +0200 Subject: [PATCH 2/2] Convert setup.pl into static configurations The setup.pl script has been replaced with static BIND configurations, and in the course of this change, the unused ns1 server was removed. This enhancement has greatly improved the overall test's readability. (cherry picked from commit 08a8906cfcf2ba4c1b305a14411b24b18f32e0ae) --- bin/tests/system/stress/clean.sh | 4 - bin/tests/system/stress/ns1/named.conf.in | 32 -------- bin/tests/system/stress/ns2/named.conf.in | 31 ++++++- bin/tests/system/stress/ns2/zone.template.db | 21 +++++ bin/tests/system/stress/ns3/named.conf.in | 36 ++++++-- bin/tests/system/stress/ns4/named.conf.in | 30 ++++++- bin/tests/system/stress/setup.pl | 86 -------------------- bin/tests/system/stress/setup.sh | 11 ++- 8 files changed, 109 insertions(+), 142 deletions(-) delete mode 100644 bin/tests/system/stress/ns1/named.conf.in create mode 100644 bin/tests/system/stress/ns2/zone.template.db delete mode 100644 bin/tests/system/stress/setup.pl diff --git a/bin/tests/system/stress/clean.sh b/bin/tests/system/stress/clean.sh index 0396845cbd..4833fa7df8 100644 --- a/bin/tests/system/stress/clean.sh +++ b/bin/tests/system/stress/clean.sh @@ -11,12 +11,8 @@ # See the COPYRIGHT file distributed with this work for additional # information regarding copyright ownership. -rm -f ns?/zones.conf rm -f ns?/zone*.bk -rm -f ns1/delegations.db -rm -f ns1/root.db - rm -f ns2/zone0*.db rm -f ns2/zone0*.jnl rm -f */named.memstats diff --git a/bin/tests/system/stress/ns1/named.conf.in b/bin/tests/system/stress/ns1/named.conf.in deleted file mode 100644 index 74ad00787b..0000000000 --- a/bin/tests/system/stress/ns1/named.conf.in +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * SPDX-License-Identifier: MPL-2.0 - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * See the COPYRIGHT file distributed with this work for additional - * information regarding copyright ownership. - */ - -controls { /* empty */ }; - -options { - query-source address 10.53.0.1; - notify-source 10.53.0.1; - transfer-source 10.53.0.1; - port @PORT@; - pid-file "named.pid"; - listen-on { 10.53.0.1; }; - listen-on-v6 { none; }; - recursion no; - dnssec-validation no; - notify yes; -}; - -zone "." { - type primary; - file "root.db"; -}; diff --git a/bin/tests/system/stress/ns2/named.conf.in b/bin/tests/system/stress/ns2/named.conf.in index 5bbea78aca..607e0b5341 100644 --- a/bin/tests/system/stress/ns2/named.conf.in +++ b/bin/tests/system/stress/ns2/named.conf.in @@ -26,9 +26,32 @@ options { notify yes; }; -zone "." { - type hint; - file "../../common/root.hint"; +zone "zone000000.example" { + type primary; + allow-update { any; }; + file "zone000000.example.db"; }; -include "zones.conf"; +zone "zone000001.example" { + type primary; + allow-update { any; }; + file "zone000001.example.db"; +}; + +zone "zone000002.example" { + type primary; + allow-update { any; }; + file "zone000002.example.db"; +}; + +zone "zone000003.example" { + type primary; + allow-update { any; }; + file "zone000003.example.db"; +}; + +zone "zone000004.example" { + type primary; + allow-update { any; }; + file "zone000004.example.db"; +}; diff --git a/bin/tests/system/stress/ns2/zone.template.db b/bin/tests/system/stress/ns2/zone.template.db new file mode 100644 index 0000000000..7ca1cc3de7 --- /dev/null +++ b/bin/tests/system/stress/ns2/zone.template.db @@ -0,0 +1,21 @@ +; Copyright (C) Internet Systems Consortium, Inc. ("ISC") +; +; SPDX-License-Identifier: MPL-2.0 +; +; This Source Code Form is subject to the terms of the Mozilla Public +; License, v. 2.0. If a copy of the MPL was not distributed with this +; file, you can obtain one at https://mozilla.org/MPL/2.0/. +; +; See the COPYRIGHT file distributed with this work for additional +; information regarding copyright ownership. + +$TTL 300 +@ IN SOA ns2 hostmaster 1 300 120 3600 86400 +@ NS ns2 + NS ns3 + NS ns4 +ns2 A 10.53.0.2 +ns3 A 10.53.0.3 +ns4 A 10.53.0.4 + +$GENERATE 0-999 name${0,6} A 10.0.0.1 diff --git a/bin/tests/system/stress/ns3/named.conf.in b/bin/tests/system/stress/ns3/named.conf.in index 036ffdbac2..13e54a54e4 100644 --- a/bin/tests/system/stress/ns3/named.conf.in +++ b/bin/tests/system/stress/ns3/named.conf.in @@ -35,16 +35,40 @@ controls { inet 10.53.0.3 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; }; -zone "." { - type hint; - file "../../common/root.hint"; -}; - server 10.53.0.4 { provide-ixfr no; }; + server 10.53.0.2 { request-ixfr no; }; -include "zones.conf"; +zone "zone000000.example" { + type secondary; + file "zone000000.example.bk"; + primaries { 10.53.0.2; }; +}; + +zone "zone000001.example" { + type secondary; + file "zone000001.example.bk"; + primaries { 10.53.0.2; }; +}; + +zone "zone000002.example" { + type secondary; + file "zone000002.example.bk"; + primaries { 10.53.0.2; }; +}; + +zone "zone000003.example" { + type secondary; + file "zone000003.example.bk"; + primaries { 10.53.0.2; }; +}; + +zone "zone000004.example" { + type secondary; + file "zone000004.example.bk"; + primaries { 10.53.0.2; }; +}; diff --git a/bin/tests/system/stress/ns4/named.conf.in b/bin/tests/system/stress/ns4/named.conf.in index 57f7e40fdd..26296f52bf 100644 --- a/bin/tests/system/stress/ns4/named.conf.in +++ b/bin/tests/system/stress/ns4/named.conf.in @@ -26,10 +26,32 @@ options { notify yes; }; -zone "." { - type hint; - file "../../common/root.hint"; +zone "zone000000.example" { + type secondary; + file "zone000000.example.bk"; + primaries { 10.53.0.3; }; }; -include "zones.conf"; +zone "zone000001.example" { + type secondary; + file "zone000001.example.bk"; + primaries { 10.53.0.3; }; +}; +zone "zone000002.example" { + type secondary; + file "zone000002.example.bk"; + primaries { 10.53.0.3; }; +}; + +zone "zone000003.example" { + type secondary; + file "zone000003.example.bk"; + primaries { 10.53.0.3; }; +}; + +zone "zone000004.example" { + type secondary; + file "zone000004.example.bk"; + primaries { 10.53.0.3; }; +}; diff --git a/bin/tests/system/stress/setup.pl b/bin/tests/system/stress/setup.pl deleted file mode 100644 index 18a4246b29..0000000000 --- a/bin/tests/system/stress/setup.pl +++ /dev/null @@ -1,86 +0,0 @@ -#!/usr/bin/perl - -# Copyright (C) Internet Systems Consortium, Inc. ("ISC") -# -# SPDX-License-Identifier: MPL-2.0 -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, you can obtain one at https://mozilla.org/MPL/2.0/. -# -# See the COPYRIGHT file distributed with this work for additional -# information regarding copyright ownership. - -# -# Set up test data for zone transfer quota tests. -# -use FileHandle; - -my $n_zones = 5; -my $n_names = 1000; - -make_zones(2, undef); -make_zones(3, "10.53.0.2"); -make_zones(4, "10.53.0.3"); - -my $rootdelegations = - new FileHandle("ns1/root.db", "w") or die; - -print $rootdelegations <close; - } - } -} diff --git a/bin/tests/system/stress/setup.sh b/bin/tests/system/stress/setup.sh index cc751d3b7a..aab7002904 100644 --- a/bin/tests/system/stress/setup.sh +++ b/bin/tests/system/stress/setup.sh @@ -14,13 +14,12 @@ # shellcheck source=conf.sh . ../conf.sh -# -# Set up test data for zone transfer quota tests. -# +cp ns2/zone.template.db ns2/zone000000.example.db +cp ns2/zone.template.db ns2/zone000001.example.db +cp ns2/zone.template.db ns2/zone000002.example.db +cp ns2/zone.template.db ns2/zone000003.example.db +cp ns2/zone.template.db ns2/zone000004.example.db -$PERL setup.pl - -copy_setports ns1/named.conf.in ns1/named.conf copy_setports ns2/named.conf.in ns2/named.conf copy_setports ns3/named.conf.in ns3/named.conf copy_setports ns4/named.conf.in ns4/named.conf