bind9/bin/tests/system/masterfile/tests_masterfile.py
Nicki Křížek 64143ea077 Use isctest.query.create across system tests
Rather than using the dnspython's facilities and defaults to create the
queries, use the isctest.query.create function in all the cases that
don't require special handling to have consistent defaults.
2025-07-29 12:13:11 -07:00

168 lines
6.2 KiB
Python

# 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 dns.message
import dns.zone
import isctest
import pytest
pytestmark = pytest.mark.extra_artifacts(
["ns2/copied.db", "ns2/present.db", "ns2/alternate.db"]
)
def test_masterfile_include_semantics():
"""Test master file $INCLUDE semantics"""
msg_axfr = isctest.query.create("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 = isctest.query.create("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 = isctest.query.create("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 = isctest.query.create("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_initial_file():
"""Test zone configurations with initial template files"""
# example inherited its configuration from the template,
# make sure it works
msg_soa = isctest.query.create("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)
# initial uses an initial-file option with the "file"
# option set to "copied.db". make sure it works and that
# copied.db has been populated.
msg_soa = isctest.query.create("initial.", "SOA")
res_soa = isctest.query.tcp(msg_soa, "10.53.0.2")
expected_soa_rr = """;ANSWER
initial. 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)
isctest.check.file_contents_equal("ns2/example.db", "ns2/copied.db")
# present uses an initial-file option, but the file 'present.db'
# already exists and is empty, so the initial-file should not be
# copied into place and the zone should not load.
msg_soa = isctest.query.create("present.", "SOA")
res_soa = isctest.query.tcp(msg_soa, "10.53.0.2")
isctest.check.servfail(res_soa)
isctest.check.file_empty("ns2/present.db")
def test_masterfile_template_override():
"""Test zone configurations with overridden template options"""
# different inherited configuration from the template, but
# overrides the "file" option to 'alternate.db'.
msg_soa = isctest.query.create("different.", "SOA")
res_soa = isctest.query.tcp(msg_soa, "10.53.0.2")
expected_soa_rr = """;ANSWER
different. 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)
isctest.check.file_contents_equal("ns2/example.db", "ns2/alternate.db")
assert not os.path.exists("ns2/different.db")
def test_masterfile_missing_master_file_servfail():
"""Test nameserver returning SERVFAIL for a missing master file"""
msg_soa = isctest.query.create("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 = isctest.run.cmd(
[
os.environ["CHECKZONE"],
"-D",
"-q",
"example",
"zone/inheritownerafterinclude.db",
]
).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)