bind9/bin/tests/system/isctest/transfer.py
Michal Nowak 27ee27d4e3
Add isctest.transfer.transfer_message() helper and convert tests
Add a new helper function, isctest.transfer.transfer_message(), to
bin/tests/system/isctest/transfer.py that generates the log message
produced by xfrin_log() in lib/dns/xfrin.c for an incoming zone
transfer:

    transfer of '<zone>/IN' from <source_ns>#<port>: <msg>

The helper always returns a compiled re.Pattern.  source_ns and port
each accept None to match any source address / port.  msg accepts
either a plain str (regex-escaped automatically) or a compiled
re.Pattern (spliced into the regex as-is), so callers that need regex
syntax in the message part can pass Re(r"...") without having to
wrap the whole result.

source_ns is passed through re.escape() when provided, so dots in
IPv4 addresses (e.g. "10.53.0.1") match a literal dot rather than
any character.

Convert the existing call sites across the system tests to use the
new helper.

Co-Authored-By: Nicki Křížek <nicki@isc.org>
Assisted-by: Claude:claude-sonnet-4-6
Assisted-by: Claude:claude-opus-4-7
2026-05-11 15:31:41 +02:00

47 lines
1.8 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.
from re import Pattern
import re
def transfer_message(
zone: str, source_ns: str | None, msg: str | Pattern, port: int | None = None
) -> Pattern:
"""Return the expected log message for an incoming zone transfer.
Mirrors the format produced by xfrin_log() in lib/dns/xfrin.c:
transfer of '<zone>/IN' from <source_ns>#<port>: <msg>
Always returns a compiled Pattern. When source_ns or port is None,
the unknown part is replaced by a wildcard in the regex.
Args:
zone: Zone name (without class, e.g. "example.com").
source_ns: Source nameserver IP address string (e.g. "10.53.0.1"),
or None to match any source address.
msg: Transfer status or other message as a plain string
(e.g. "Transfer status: success"), which is regex-escaped,
or a compiled Pattern whose .pattern is spliced in as-is
for callers that need regex syntax in the message part.
port: Source port number, or None to match any port.
"""
source_str = re.escape(source_ns) if source_ns is not None else ".*"
port_str = str(port) if port is not None else "[0-9]+"
msg_str = msg.pattern if isinstance(msg, Pattern) else re.escape(msg)
return re.compile(
re.escape(f"transfer of '{zone}/IN' from ")
+ f"{source_str}#{port_str}: "
+ msg_str
)