mirror of
https://github.com/isc-projects/bind9.git
synced 2026-03-31 06:45:56 -04:00
Merge branch 'mnowak/pytest_rewrite_masterfile' into 'main'
Rewrite masterfile system test to pytest See merge request isc-projects/bind9!8791
This commit is contained in:
commit
c252ca2ce5
9 changed files with 175 additions and 130 deletions
|
|
@ -9,11 +9,13 @@
|
|||
# See the COPYRIGHT file distributed with this work for additional
|
||||
# information regarding copyright ownership.
|
||||
|
||||
from typing import Any
|
||||
from typing import Any, Optional
|
||||
|
||||
import dns.rcode
|
||||
import dns.message
|
||||
import dns.zone
|
||||
|
||||
import isctest.log
|
||||
|
||||
# compatiblity with dnspython<2.0.0
|
||||
try:
|
||||
|
|
@ -38,8 +40,58 @@ def servfail(message: dns.message.Message) -> None:
|
|||
rcode(message, dns_rcode.SERVFAIL)
|
||||
|
||||
|
||||
def rrsets_equal(first_rrset: dns.rrset.RRset, second_rrset: dns.rrset.RRset) -> None:
|
||||
def rrsets_equal(
|
||||
first_rrset: dns.rrset.RRset,
|
||||
second_rrset: dns.rrset.RRset,
|
||||
compare_ttl: Optional[bool] = False,
|
||||
) -> None:
|
||||
"""Compare two RRset (optionally including TTL)"""
|
||||
|
||||
def compare_rrs(rr1, rrset):
|
||||
rr2 = next((other_rr for other_rr in rrset if rr1 == other_rr), None)
|
||||
assert rr2 is not None, f"No corresponding RR found for: {rr1}"
|
||||
if compare_ttl:
|
||||
assert rr1.ttl == rr2.ttl
|
||||
|
||||
isctest.log.debug(
|
||||
"%s() first RRset:\n%s",
|
||||
rrsets_equal.__name__,
|
||||
"\n".join([str(rr) for rr in first_rrset]),
|
||||
)
|
||||
isctest.log.debug(
|
||||
"%s() second RRset:\n%s",
|
||||
rrsets_equal.__name__,
|
||||
"\n".join([str(rr) for rr in second_rrset]),
|
||||
)
|
||||
for rr in first_rrset:
|
||||
assert rr in second_rrset
|
||||
compare_rrs(rr, second_rrset)
|
||||
for rr in second_rrset:
|
||||
assert rr in first_rrset
|
||||
compare_rrs(rr, first_rrset)
|
||||
|
||||
|
||||
def zones_equal(
|
||||
first_zone: dns.zone.Zone,
|
||||
second_zone: dns.zone.Zone,
|
||||
compare_ttl: Optional[bool] = False,
|
||||
) -> None:
|
||||
"""Compare two zones (optionally including TTL)"""
|
||||
|
||||
isctest.log.debug(
|
||||
"%s() first zone:\n%s",
|
||||
zones_equal.__name__,
|
||||
first_zone.to_text(relativize=False),
|
||||
)
|
||||
isctest.log.debug(
|
||||
"%s() second zone:\n%s",
|
||||
zones_equal.__name__,
|
||||
second_zone.to_text(relativize=False),
|
||||
)
|
||||
assert first_zone == second_zone
|
||||
if compare_ttl:
|
||||
for name, node in first_zone.nodes.items():
|
||||
for rdataset in node:
|
||||
found_rdataset = second_zone.find_rdataset(
|
||||
name=name, rdtype=rdataset.rdtype
|
||||
)
|
||||
assert found_rdataset
|
||||
assert found_rdataset.ttl == rdataset.ttl
|
||||
|
|
|
|||
|
|
@ -11,9 +11,7 @@
|
|||
# See the COPYRIGHT file distributed with this work for additional
|
||||
# information regarding copyright ownership.
|
||||
|
||||
rm -f dig.out.*
|
||||
rm -f */named.memstats
|
||||
rm -f */named.conf
|
||||
rm -f */named.run
|
||||
rm -f checkzone.out*
|
||||
rm -f ns*/managed-keys.bind*
|
||||
|
|
|
|||
|
|
@ -1,12 +0,0 @@
|
|||
include. 300 IN SOA ns.include. hostmaster.include. 1 3600 1800 1814400 3600
|
||||
include. 300 IN NS ns.include.
|
||||
a.include. 300 IN A 10.0.0.1
|
||||
a.include. 300 IN A 10.0.0.99
|
||||
a.a.include. 300 IN A 10.0.1.1
|
||||
b.foo.a.include. 300 IN A 10.0.2.2
|
||||
b.include. 300 IN A 10.0.0.2
|
||||
a.b.include. 300 IN A 10.0.1.1
|
||||
c.b.include. 300 IN A 10.0.0.3
|
||||
b.foo.b.include. 300 IN A 10.0.2.2
|
||||
ns.include. 300 IN A 127.0.0.1
|
||||
include. 300 IN SOA ns.include. hostmaster.include. 1 3600 1800 1814400 3600
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
ttl1. 3 IN SOA ns.ttl1. hostmaster.ttl1. 1 3600 1800 1814400 3
|
||||
ttl1. 3 IN NS ns.ttl1.
|
||||
a.ttl1. 3 IN TXT "soa minttl 3"
|
||||
b.ttl1. 2 IN TXT "explicit ttl 2"
|
||||
c.ttl1. 3 IN TXT "soa minttl 3"
|
||||
d.ttl1. 1 IN TXT "default ttl 1"
|
||||
e.ttl1. 4 IN TXT "explicit ttl 4"
|
||||
f.ttl1. 1 IN TXT "default ttl 1"
|
||||
ns.ttl1. 3 IN A 10.53.0.1
|
||||
ttl1. 3 IN SOA ns.ttl1. hostmaster.ttl1. 1 3600 1800 1814400 3
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
ttl2. 1 IN SOA ns.ttl2. hostmaster.ttl2. 1 3600 1800 1814400 3
|
||||
ttl2. 1 IN NS ns.ttl2.
|
||||
a.ttl2. 1 IN TXT "inherited ttl 1"
|
||||
b.ttl2. 2 IN TXT "explicit ttl 2"
|
||||
c.ttl2. 2 IN TXT "inherited ttl 2"
|
||||
d.ttl2. 3 IN TXT "default ttl 3"
|
||||
e.ttl2. 2 IN TXT "explicit ttl 2"
|
||||
f.ttl2. 3 IN TXT "default ttl 3"
|
||||
ns.ttl2. 1 IN A 10.53.0.1
|
||||
ttl2. 1 IN SOA ns.ttl2. hostmaster.ttl2. 1 3600 1800 1814400 3
|
||||
|
|
@ -1,75 +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
|
||||
|
||||
DIGOPTS="-p ${PORT}"
|
||||
|
||||
status=0
|
||||
n=0
|
||||
|
||||
ret=0
|
||||
n=$((n + 1))
|
||||
echo_i "test master file \$INCLUDE semantics ($n)"
|
||||
$DIG $DIGOPTS +nostats +nocmd include. axfr @10.53.0.1 >dig.out.$n || ret=1
|
||||
|
||||
diff dig.out.$n knowngood.include || ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=$((status + ret))
|
||||
|
||||
ret=0
|
||||
n=$((n + 1))
|
||||
echo_i "test master file BIND 8 compatibility TTL and \$TTL semantics ($n)"
|
||||
$DIG $DIGOPTS +nostats +nocmd ttl1. axfr @10.53.0.1 >dig.out.$n || ret=1
|
||||
|
||||
diff dig.out.$n knowngood.ttl1 || ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=$((status + ret))
|
||||
|
||||
ret=0
|
||||
n=$((n + 1))
|
||||
echo_i "test of master file RFC1035 TTL and \$TTL semantics ($n)"
|
||||
$DIG $DIGOPTS +nostats +nocmd ttl2. axfr @10.53.0.1 >dig.out.$n || ret=1
|
||||
|
||||
diff dig.out.$n knowngood.ttl2 || ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=$((status + ret))
|
||||
|
||||
ret=0
|
||||
n=$((n + 1))
|
||||
echo_i "test that the nameserver is running with a missing master file ($n)"
|
||||
$DIG $DIGOPTS +tcp +noall +answer example soa @10.53.0.2 >dig.out.$n || ret=1
|
||||
grep SOA dig.out.$n >/dev/null || ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=$((status + ret))
|
||||
|
||||
ret=0
|
||||
n=$((n + 1))
|
||||
echo_i "test that the nameserver returns SERVFAIL for a missing master file ($n)"
|
||||
$DIG $DIGOPTS +tcp +all missing soa @10.53.0.2 >dig.out.$n || ret=1
|
||||
grep "status: SERVFAIL" dig.out.$n >/dev/null || ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=$((status + ret))
|
||||
|
||||
ret=0
|
||||
n=$((n + 1))
|
||||
echo_i "test owner inheritance after "'$INCLUDE'" ($n)"
|
||||
$CHECKZONE -Dq example zone/inheritownerafterinclude.db >checkzone.out$n
|
||||
diff checkzone.out$n zone/inheritownerafterinclude.good || ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=$((status + ret))
|
||||
|
||||
echo_i "exit status: $status"
|
||||
[ $status -eq 0 ] || exit 1
|
||||
119
bin/tests/system/masterfile/tests_masterfile.py
Normal file
119
bin/tests/system/masterfile/tests_masterfile.py
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
# 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 os
|
||||
import subprocess
|
||||
|
||||
import dns.message
|
||||
import dns.zone
|
||||
|
||||
import isctest
|
||||
|
||||
|
||||
def test_masterfile_include_semantics():
|
||||
"""Test master file $INCLUDE semantics"""
|
||||
msg_axfr = dns.message.make_query("include.", "AXFR")
|
||||
res_axfr = isctest.query.tcp(msg_axfr, "10.53.0.1")
|
||||
axfr_include_semantics = """;ANSWER
|
||||
include. 300 IN SOA ns.include. hostmaster.include. 1 3600 1800 1814400 3600
|
||||
include. 300 IN NS ns.include.
|
||||
a.include. 300 IN A 10.0.0.1
|
||||
a.include. 300 IN A 10.0.0.99
|
||||
a.a.include. 300 IN A 10.0.1.1
|
||||
b.foo.a.include. 300 IN A 10.0.2.2
|
||||
b.include. 300 IN A 10.0.0.2
|
||||
a.b.include. 300 IN A 10.0.1.1
|
||||
c.b.include. 300 IN A 10.0.0.3
|
||||
b.foo.b.include. 300 IN A 10.0.2.2
|
||||
ns.include. 300 IN A 127.0.0.1
|
||||
"""
|
||||
expected = dns.message.from_text(axfr_include_semantics)
|
||||
isctest.check.rrsets_equal(res_axfr.answer, expected.answer, compare_ttl=True)
|
||||
|
||||
|
||||
def test_masterfile_bind_8_compat_semantics():
|
||||
"""Test master file BIND 8 TTL and $TTL semantics compatibility"""
|
||||
msg_axfr = dns.message.make_query("ttl1.", "AXFR")
|
||||
res_axfr = isctest.query.tcp(msg_axfr, "10.53.0.1")
|
||||
axfr_ttl_semantics = """;ANSWER
|
||||
ttl1. 3 IN SOA ns.ttl1. hostmaster.ttl1. 1 3600 1800 1814400 3
|
||||
ttl1. 3 IN NS ns.ttl1.
|
||||
a.ttl1. 3 IN TXT "soa minttl 3"
|
||||
b.ttl1. 2 IN TXT "explicit ttl 2"
|
||||
c.ttl1. 3 IN TXT "soa minttl 3"
|
||||
d.ttl1. 1 IN TXT "default ttl 1"
|
||||
e.ttl1. 4 IN TXT "explicit ttl 4"
|
||||
f.ttl1. 1 IN TXT "default ttl 1"
|
||||
ns.ttl1. 3 IN A 10.53.0.1
|
||||
"""
|
||||
expected = dns.message.from_text(axfr_ttl_semantics)
|
||||
isctest.check.rrsets_equal(res_axfr.answer, expected.answer, compare_ttl=True)
|
||||
|
||||
|
||||
def test_masterfile_rfc_1035_semantics():
|
||||
"""Test master file RFC1035 TTL and $TTL semantics"""
|
||||
msg_axfr = dns.message.make_query("ttl2.", "AXFR")
|
||||
res_axfr = isctest.query.tcp(msg_axfr, "10.53.0.1")
|
||||
axfr_ttl_semantics = """;ANSWER
|
||||
ttl2. 1 IN SOA ns.ttl2. hostmaster.ttl2. 1 3600 1800 1814400 3
|
||||
ttl2. 1 IN NS ns.ttl2.
|
||||
a.ttl2. 1 IN TXT "inherited ttl 1"
|
||||
b.ttl2. 2 IN TXT "explicit ttl 2"
|
||||
c.ttl2. 2 IN TXT "inherited ttl 2"
|
||||
d.ttl2. 3 IN TXT "default ttl 3"
|
||||
e.ttl2. 2 IN TXT "explicit ttl 2"
|
||||
f.ttl2. 3 IN TXT "default ttl 3"
|
||||
ns.ttl2. 1 IN A 10.53.0.1
|
||||
"""
|
||||
expected = dns.message.from_text(axfr_ttl_semantics)
|
||||
isctest.check.rrsets_equal(res_axfr.answer, expected.answer, compare_ttl=True)
|
||||
|
||||
|
||||
def test_masterfile_missing_master_file():
|
||||
"""Test nameserver running with a missing master file"""
|
||||
msg_soa = dns.message.make_query("example.", "SOA")
|
||||
res_soa = isctest.query.tcp(msg_soa, "10.53.0.2")
|
||||
expected_soa_rr = """;ANSWER
|
||||
example. 300 IN SOA mname1. . 2010042407 20 20 1814400 3600
|
||||
"""
|
||||
expected = dns.message.from_text(expected_soa_rr)
|
||||
isctest.check.rrsets_equal(res_soa.answer, expected.answer, compare_ttl=True)
|
||||
|
||||
|
||||
def test_masterfile_missing_master_file_servfail():
|
||||
"""Test nameserver returning SERVFAIL for a missing master file"""
|
||||
msg_soa = dns.message.make_query("missing.", "SOA")
|
||||
res_soa = isctest.query.tcp(msg_soa, "10.53.0.2")
|
||||
isctest.check.servfail(res_soa)
|
||||
|
||||
|
||||
def test_masterfile_owner_inheritance():
|
||||
"""Test owner inheritance after $INCLUDE"""
|
||||
checker_output = subprocess.run(
|
||||
[
|
||||
os.environ["CHECKZONE"],
|
||||
"-D",
|
||||
"-q",
|
||||
"example",
|
||||
"zone/inheritownerafterinclude.db",
|
||||
],
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
check=True,
|
||||
).stdout.decode("utf-8")
|
||||
owner_inheritance_zone = """
|
||||
example. 0 IN SOA . . 0 0 0 0 0
|
||||
example. 0 IN TXT "this should be at the zone apex"
|
||||
example. 0 IN NS .
|
||||
"""
|
||||
checker_zone = dns.zone.from_text(checker_output, origin="example.")
|
||||
expected = dns.zone.from_text(owner_inheritance_zone, origin="example.")
|
||||
isctest.check.zones_equal(checker_zone, expected, compare_ttl=True)
|
||||
|
|
@ -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_masterfile(run_tests_sh):
|
||||
run_tests_sh()
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
example. 0 IN SOA . . 0 0 0 0 0
|
||||
example. 0 IN NS .
|
||||
example. 0 IN TXT "this should be at the zone apex"
|
||||
Loading…
Reference in a new issue