2024-02-19 18:06:53 +01:00
|
|
|
# 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.
|
|
|
|
|
2024-07-22 16:20:02 +02:00
|
|
|
import os
|
2024-03-20 12:49:08 +01:00
|
|
|
import subprocess
|
2024-02-19 18:06:53 +01:00
|
|
|
import time
|
2024-08-27 20:14:00 +02:00
|
|
|
from typing import Optional
|
2024-03-20 12:49:08 +01:00
|
|
|
|
|
|
|
import isctest.log
|
2024-08-27 20:14:00 +02:00
|
|
|
from isctest.compat import dns_rcode
|
2024-03-20 12:49:08 +01:00
|
|
|
|
2024-07-22 16:20:02 +02:00
|
|
|
import dns.message
|
|
|
|
|
|
|
|
|
2024-10-14 14:44:06 +02:00
|
|
|
def cmd(
|
2024-03-20 12:49:08 +01:00
|
|
|
args,
|
|
|
|
cwd=None,
|
|
|
|
timeout=60,
|
|
|
|
stdout=subprocess.PIPE,
|
|
|
|
stderr=subprocess.PIPE,
|
|
|
|
log_stdout=False,
|
|
|
|
log_stderr=True,
|
|
|
|
input_text: Optional[bytes] = None,
|
|
|
|
raise_on_exception=True,
|
|
|
|
):
|
|
|
|
"""Execute a command with given args as subprocess."""
|
|
|
|
isctest.log.debug(f"command: {' '.join(args)}")
|
|
|
|
|
|
|
|
def print_debug_logs(procdata):
|
|
|
|
if procdata:
|
|
|
|
if log_stdout and procdata.stdout:
|
|
|
|
isctest.log.debug(
|
|
|
|
f"~~~ cmd stdout ~~~\n{procdata.stdout.decode('utf-8')}\n~~~~~~~~~~~~~~~~~~"
|
|
|
|
)
|
|
|
|
if log_stderr and procdata.stderr:
|
|
|
|
isctest.log.debug(
|
|
|
|
f"~~~ cmd stderr ~~~\n{procdata.stderr.decode('utf-8')}\n~~~~~~~~~~~~~~~~~~"
|
|
|
|
)
|
|
|
|
|
|
|
|
try:
|
|
|
|
proc = subprocess.run(
|
|
|
|
args,
|
|
|
|
stdout=stdout,
|
|
|
|
stderr=stderr,
|
|
|
|
input=input_text,
|
|
|
|
check=True,
|
|
|
|
cwd=cwd,
|
|
|
|
timeout=timeout,
|
|
|
|
)
|
|
|
|
print_debug_logs(proc)
|
|
|
|
return proc
|
|
|
|
except subprocess.CalledProcessError as exc:
|
|
|
|
print_debug_logs(exc)
|
|
|
|
isctest.log.debug(f" return code: {exc.returncode}")
|
|
|
|
if raise_on_exception:
|
|
|
|
raise exc
|
|
|
|
return exc
|
2024-02-19 18:06:53 +01:00
|
|
|
|
|
|
|
|
|
|
|
def retry_with_timeout(func, timeout, delay=1, msg=None):
|
|
|
|
start_time = time.time()
|
|
|
|
while time.time() < start_time + timeout:
|
|
|
|
if func():
|
|
|
|
return
|
|
|
|
time.sleep(delay)
|
|
|
|
if msg is None:
|
|
|
|
msg = f"{func.__module__}.{func.__qualname__} timed out after {timeout} s"
|
|
|
|
assert False, msg
|
2024-07-22 16:20:02 +02:00
|
|
|
|
|
|
|
|
|
|
|
def get_named_cmdline(cfg_dir, cfg_file="named.conf"):
|
|
|
|
cfg_dir = os.path.join(os.getcwd(), cfg_dir)
|
|
|
|
assert os.path.isdir(cfg_dir)
|
|
|
|
|
|
|
|
cfg_file = os.path.join(cfg_dir, cfg_file)
|
|
|
|
assert os.path.isfile(cfg_file)
|
|
|
|
|
|
|
|
named = os.getenv("NAMED")
|
|
|
|
assert named is not None
|
|
|
|
|
|
|
|
named_cmdline = [named, "-c", cfg_file, "-d", "99", "-g"]
|
|
|
|
|
|
|
|
return named_cmdline
|
|
|
|
|
|
|
|
|
|
|
|
def get_custom_named_instance(assumed_ns):
|
|
|
|
# This test launches and monitors a named instance itself rather than using
|
|
|
|
# bin/tests/system/start.pl, so manually defining a NamedInstance here is
|
|
|
|
# necessary for sending RNDC commands to that instance. If this "custom"
|
|
|
|
# instance listens on 10.53.0.3, use "ns3" as the identifier passed to
|
|
|
|
# the NamedInstance constructor.
|
|
|
|
named_ports = isctest.instance.NamedPorts.from_env()
|
|
|
|
instance = isctest.instance.NamedInstance(assumed_ns, named_ports)
|
|
|
|
|
|
|
|
return instance
|
|
|
|
|
|
|
|
|
|
|
|
def assert_custom_named_is_alive(named_proc, resolver_ip):
|
|
|
|
assert named_proc.poll() is None, "named isn't running"
|
|
|
|
msg = dns.message.make_query("version.bind", "TXT", "CH")
|
|
|
|
isctest.query.tcp(msg, resolver_ip, expected_rcode=dns_rcode.NOERROR)
|