From c86f898fcafc31401fe31b4a982f0687640bb5b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicki=20K=C5=99=C3=AD=C5=BEek?= Date: Thu, 2 Oct 2025 18:14:13 +0200 Subject: [PATCH] Use Text with Grep support in isctest.run.cmd() When commands are executed using the isctest.run.cmd() command, allow the output to be Grep-able like logs and text files. (cherry picked from commit 4b6a86b029a34c939b2e265ccab43f4f1b9a5808) --- bin/tests/system/isctest/run.py | 9 ++-- bin/tests/system/isctest/text.py | 9 ++++ .../system/keyfromlabel/tests_keyfromlabel.py | 4 +- bin/tests/system/verify/tests_verify.py | 50 ++++++++----------- 4 files changed, 37 insertions(+), 35 deletions(-) diff --git a/bin/tests/system/isctest/run.py b/bin/tests/system/isctest/run.py index 422877be06..2f421c2808 100644 --- a/bin/tests/system/isctest/run.py +++ b/bin/tests/system/isctest/run.py @@ -15,6 +15,7 @@ import time from typing import Optional import isctest.log +import isctest.text from isctest.compat import dns_rcode import dns.message @@ -24,12 +25,12 @@ class CmdResult: def __init__(self, proc=None): self.proc = proc self.rc = self.proc.returncode - self.out = "" - self.err = "" + self.out = isctest.text.Text("") + self.err = isctest.text.Text("") if self.proc.stdout: - self.out = self.proc.stdout.decode("utf-8") + self.out = isctest.text.Text(self.proc.stdout.decode("utf-8")) if self.proc.stderr: - self.err = self.proc.stderr.decode("utf-8") + self.err = isctest.text.Text(self.proc.stderr.decode("utf-8")) def cmd( diff --git a/bin/tests/system/isctest/text.py b/bin/tests/system/isctest/text.py index 46b710e454..ca3cc835e7 100644 --- a/bin/tests/system/isctest/text.py +++ b/bin/tests/system/isctest/text.py @@ -65,6 +65,15 @@ class Grep(abc.ABC): return True +class Text(Grep, str): # type: ignore + """ + Wrapper around classic string with grep support. + """ + + def readlines(self): + yield from self.splitlines(keepends=True) + + class TextFile(Grep): """ Text file wrapper with grep support. diff --git a/bin/tests/system/keyfromlabel/tests_keyfromlabel.py b/bin/tests/system/keyfromlabel/tests_keyfromlabel.py index 91cc89ca95..f2c1c0bea2 100644 --- a/bin/tests/system/keyfromlabel/tests_keyfromlabel.py +++ b/bin/tests/system/keyfromlabel/tests_keyfromlabel.py @@ -11,7 +11,7 @@ import hashlib import os -import re +from re import compile as Re import shutil import pytest @@ -84,7 +84,7 @@ def token_init_and_cleanup(): env=EMPTY_OPENSSL_CONF_ENV, raise_on_exception=False, ) - assert re.search("Found token (.*) with matching token label", cmd.out) + assert Re("Found token (.*) with matching token label") in cmd.out # pylint: disable-msg=too-many-locals diff --git a/bin/tests/system/verify/tests_verify.py b/bin/tests/system/verify/tests_verify.py index 4b50fe4ee5..6d82bfca89 100644 --- a/bin/tests/system/verify/tests_verify.py +++ b/bin/tests/system/verify/tests_verify.py @@ -11,7 +11,7 @@ import os import re -import subprocess +from re import compile as Re import pytest @@ -62,14 +62,14 @@ def test_verify_good_zone_nsec_next_name_case_mismatch(): ) -def get_bad_zone_output(zone): - only_opt = ["-z"] if re.match(r"[zk]sk-only", zone) else [] +def verify_bad_zone(zone): + only_opt = ["-z"] if re.search(r"^[zk]sk-only", zone) else [] cmd = isctest.run.cmd( [VERIFY, *only_opt, "-o", zone, f"zones/{zone}.bad"], - stderr=subprocess.STDOUT, raise_on_exception=False, ) - return cmd.out + assert cmd.rc != 0 + return cmd @pytest.mark.parametrize( @@ -81,7 +81,8 @@ def get_bad_zone_output(zone): ], ) def test_verify_bad_zone_files_dnskeyonly(zone): - assert re.match(r".*DNSKEY is not signed.*", get_bad_zone_output(zone)) + cmd = verify_bad_zone(zone) + assert "DNSKEY is not signed" in cmd.err @pytest.mark.parametrize( @@ -98,10 +99,8 @@ def test_verify_bad_zone_files_dnskeyonly(zone): ], ) def test_verify_bad_zone_files_expired(zone): - assert re.match( - r".*signature has expired.*|.*No self-signed .*DNSKEY found.*", - get_bad_zone_output(zone), - ) + cmd = verify_bad_zone(zone) + assert Re("signature has expired|No self-signed DNSKEY found") in cmd.err @pytest.mark.parametrize( @@ -113,40 +112,33 @@ def test_verify_bad_zone_files_expired(zone): ], ) def test_verify_bad_zone_files_unexpected_nsec_rrset(zone): - assert re.match(r".*unexpected NSEC RRset at.*", get_bad_zone_output(zone)) + cmd = verify_bad_zone(zone) + assert "unexpected NSEC RRset at" in cmd.err def test_verify_bad_zone_files_bad_nsec_record(): - assert re.match( - r".*Bad NSEC record for.*, next name mismatch.*", - get_bad_zone_output("ksk+zsk.nsec.broken-chain"), - ) + cmd = verify_bad_zone("ksk+zsk.nsec.broken-chain") + assert Re("Bad NSEC record for.*, next name mismatch") in cmd.err def test_verify_bad_zone_files_bad_bitmap(): - assert re.match( - r".*bit map mismatch.*", get_bad_zone_output("ksk+zsk.nsec.bad-bitmap") - ) + cmd = verify_bad_zone("ksk+zsk.nsec.bad-bitmap") + assert "bit map mismatch" in cmd.err def test_verify_bad_zone_files_missing_nsec3_record(): - assert re.match( - r".*Missing NSEC3 record for.*", - get_bad_zone_output("ksk+zsk.nsec3.missing-empty"), - ) + cmd = verify_bad_zone("ksk+zsk.nsec3.missing-empty") + assert "Missing NSEC3 record for" in cmd.err def test_verify_bad_zone_files_no_dnssec_keys(): - assert re.match( - r".*Zone contains no DNSSEC keys.*", get_bad_zone_output("unsigned") - ) + cmd = verify_bad_zone("unsigned") + assert "Zone contains no DNSSEC keys" in cmd.err def test_verify_bad_zone_files_unequal_nsec3_chains(): - assert re.match( - r".*Expected and found NSEC3 chains not equal.*", - get_bad_zone_output("ksk+zsk.nsec3.extra-nsec3"), - ) + cmd = verify_bad_zone("ksk+zsk.nsec3.extra-nsec3") + assert "Expected and found NSEC3 chains not equal" in cmd.err # checking error message when -o is not used