diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 5c1222277c..6fdae5f5c0 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1020,7 +1020,6 @@ gcc:almalinux8:amd64: system:gcc:almalinux8:amd64: <<: *almalinux_8_amd64_image <<: *system_test_job - <<: *api_pipelines_schedules_tags_triggers_web_triggering_rules needs: - job: gcc:almalinux8:amd64 artifacts: true diff --git a/bin/tests/system/chain/tests_sh_chain.py b/bin/tests/system/chain/tests_sh_chain.py index f7d7ac3b01..5aa86d9082 100644 --- a/bin/tests/system/chain/tests_sh_chain.py +++ b/bin/tests/system/chain/tests_sh_chain.py @@ -11,6 +11,9 @@ import pytest +# isctest.asyncserver requires dnspython >= 2.0.0 +pytest.importorskip("dns", minversion="2.0.0") + pytestmark = pytest.mark.extra_artifacts( [ "dig.out.*", diff --git a/bin/tests/system/cookie/tests_sh_cookie.py b/bin/tests/system/cookie/tests_sh_cookie.py index 1c9e8280f5..d5f88dedeb 100644 --- a/bin/tests/system/cookie/tests_sh_cookie.py +++ b/bin/tests/system/cookie/tests_sh_cookie.py @@ -11,6 +11,9 @@ import pytest +# isctest.asyncserver requires dnspython >= 2.0.0 +pytest.importorskip("dns", minversion="2.0.0") + pytestmark = pytest.mark.extra_artifacts( [ "dig.out.*", diff --git a/bin/tests/system/dispatch/tests_connreset.py b/bin/tests/system/dispatch/tests_connreset.py index 0b78fb8e0a..6c7f7140a6 100644 --- a/bin/tests/system/dispatch/tests_connreset.py +++ b/bin/tests/system/dispatch/tests_connreset.py @@ -14,7 +14,9 @@ import pytest import isctest -pytest.importorskip("dns") +# isctest.asyncserver requires dnspython >= 2.0.0 +pytest.importorskip("dns", minversion="2.0.0") + import dns.message pytestmark = pytest.mark.extra_artifacts( diff --git a/bin/tests/system/dnssec/tests_sh_dnssec.py b/bin/tests/system/dnssec/tests_sh_dnssec.py index a824ee7ef9..7ccf744420 100644 --- a/bin/tests/system/dnssec/tests_sh_dnssec.py +++ b/bin/tests/system/dnssec/tests_sh_dnssec.py @@ -11,6 +11,9 @@ import pytest +# isctest.asyncserver requires dnspython >= 2.0.0 +pytest.importorskip("dns", minversion="2.0.0") + pytestmark = pytest.mark.extra_artifacts( [ ".hypothesis/examples/*", diff --git a/bin/tests/system/fetchlimit/tests_sh_fetchlimit.py b/bin/tests/system/fetchlimit/tests_sh_fetchlimit.py index 23076980b5..26bdff7fc2 100644 --- a/bin/tests/system/fetchlimit/tests_sh_fetchlimit.py +++ b/bin/tests/system/fetchlimit/tests_sh_fetchlimit.py @@ -11,6 +11,9 @@ import pytest +# isctest.asyncserver requires dnspython >= 2.0.0 +pytest.importorskip("dns", minversion="2.0.0") + pytestmark = pytest.mark.extra_artifacts( [ "dig.out.*", diff --git a/bin/tests/system/forward/tests_sh_forward.py b/bin/tests/system/forward/tests_sh_forward.py index 0decea61e5..4ffec3fbd7 100644 --- a/bin/tests/system/forward/tests_sh_forward.py +++ b/bin/tests/system/forward/tests_sh_forward.py @@ -11,6 +11,9 @@ import pytest +# isctest.asyncserver requires dnspython >= 2.0.0 +pytest.importorskip("dns", minversion="2.0.0") + pytestmark = pytest.mark.extra_artifacts( [ "dig.out.*", diff --git a/bin/tests/system/hooks/tests_async_plugin.py b/bin/tests/system/hooks/tests_async_plugin.py index cb70c5c78c..4c3b1f714f 100644 --- a/bin/tests/system/hooks/tests_async_plugin.py +++ b/bin/tests/system/hooks/tests_async_plugin.py @@ -10,6 +10,10 @@ # information regarding copyright ownership. import isctest +import pytest + +# isctest.asyncserver requires dnspython >= 2.0.0 +pytest.importorskip("dns", minversion="2.0.0") def test_async_hook(): diff --git a/bin/tests/system/isctest/asyncserver.py b/bin/tests/system/isctest/asyncserver.py index e5277696cc..c91f63a123 100644 --- a/bin/tests/system/isctest/asyncserver.py +++ b/bin/tests/system/isctest/asyncserver.py @@ -116,6 +116,7 @@ class AsyncServer: tcp_handler: Optional[_TcpHandler], pidfile: Optional[str] = None, ) -> None: + self._abort_if_on_dnspython_version_less_than_2_0_0() logging.basicConfig( format="%(asctime)s %(levelname)8s %(message)s", level=os.environ.get("ANS_LOG_LEVEL", "INFO").upper(), @@ -143,6 +144,14 @@ class AsyncServer: self._pidfile: Optional[str] = pidfile self._work_done: Optional[asyncio.Future] = None + @classmethod + def _abort_if_on_dnspython_version_less_than_2_0_0(cls) -> None: + if dns.version.MAJOR < 2: + error = f"Using {cls.__name__} requires dnspython >= 2.0.0; " + error += 'add `pytest.importorskip("dns", minversion="2.0.0")` ' + error += "to the test module to skip this test." + raise RuntimeError(error) + def _get_ipv4_address_from_directory_name(self) -> str: containing_directory = pathlib.Path().absolute().stem match_result = re.match(r"ans(?P\d+)", containing_directory) @@ -1053,7 +1062,6 @@ class AsyncDnsServer(AsyncServer): try: query = dns.message.from_wire(wire) except dns.message.UnknownTSIGKey: - self._abort_if_on_dnspython_version_less_than_2_0_0() self._abort_if_tsig_signed_query_received_unless_acknowledged() query = _DnsMessageWithTsigDisabled.from_wire(wire) except dns.exception.DNSException as exc: @@ -1074,13 +1082,6 @@ class AsyncDnsServer(AsyncServer): response_length = struct.pack("!H", len(response)) yield response_length + response - def _abort_if_on_dnspython_version_less_than_2_0_0(self) -> None: - if dns.version.MAJOR < 2: - error = "Receiving TSIG signed queries requires dnspython >= 2.0.0; " - error += 'add `pytest.importorskip("dns", minversion="2.0.0")` ' - error += "to the test module to skip this test." - raise RuntimeError(error) - def _abort_if_tsig_signed_query_received_unless_acknowledged(self) -> None: if self._acknowledge_tsig_dnspython_hacks: return diff --git a/bin/tests/system/isctest/name.py b/bin/tests/system/isctest/name.py index 7cf3e8d696..a2fe3ac424 100644 --- a/bin/tests/system/isctest/name.py +++ b/bin/tests/system/isctest/name.py @@ -9,15 +9,14 @@ # See the COPYRIGHT file distributed with this work for additional # information regarding copyright ownership. -from typing import Container, Iterable, FrozenSet +from typing import Iterable, FrozenSet -import pytest - -pytest.importorskip("dns", minversion="2.3.0") # NameRelation -from dns.name import Name, NameRelation +import dns.name import dns.zone import dns.rdatatype +from dns.name import Name + def prepend_label(label: str, name: Name) -> Name: return Name((label,) + name.labels) @@ -60,6 +59,7 @@ class ZoneAnalyzer: return cls(zonedb) def __init__(self, zone: dns.zone.Zone): + self._abort_on_old_dnspython() self.zone = zone assert self.zone.origin # mypy hack # based on individual nodes but not relationship between nodes @@ -85,6 +85,14 @@ class ZoneAnalyzer: .union(self.reachable_dnames) ) + def _abort_on_old_dnspython(self): + if not hasattr(dns.name, "NameRelation"): + raise RuntimeError( + "ZoneAnalyzer requires dnspython>=2.3.0 for dns.name.NameRelation support. " + "Use pytest.importorskip('dns', minversion='2.3.0') to the test module to " + "skip this test." + ) + def get_names_with_type(self, rdtype) -> FrozenSet[Name]: return frozenset( name for name in self.zone if self.zone.get_rdataset(name, rdtype) @@ -117,15 +125,15 @@ class ZoneAnalyzer: for name in reachable: relation, _, _ = name.fullcompare(self.zone.origin) if relation in ( - NameRelation.NONE, # out of zone? - NameRelation.SUPERDOMAIN, # parent of apex?! + dns.name.NameRelation.NONE, # out of zone? + dns.name.NameRelation.SUPERDOMAIN, # parent of apex?! ): raise NotImplementedError for maybe_occluded in reachable.copy(): for cut in self.delegations: rel, _, _ = maybe_occluded.fullcompare(cut) - if rel == NameRelation.EQUAL: + if rel == dns.name.NameRelation.EQUAL: # data _on_ a parent-side of a zone cut are in limbo: # - are not really authoritative (except for DS) # - but NS is not really 'occluded' @@ -134,14 +142,14 @@ class ZoneAnalyzer: if maybe_occluded in reachable: reachable.remove(maybe_occluded) - if rel == NameRelation.SUBDOMAIN: + if rel == dns.name.NameRelation.SUBDOMAIN: _mark_occluded(maybe_occluded) # do not break cycle - handle also nested NS and DNAME # DNAME itself is authoritative but nothing under it is reachable for dname in self.dnames: rel, _, _ = maybe_occluded.fullcompare(dname) - if rel == NameRelation.SUBDOMAIN: + if rel == dns.name.NameRelation.SUBDOMAIN: _mark_occluded(maybe_occluded) # do not break cycle - handle also nested NS and DNAME @@ -174,7 +182,7 @@ class ZoneAnalyzer: nce = None # Next closer name, RFC 5155 for zname in self.all_existing_names: relation, _, common_labels = qname.fullcompare(zname) - if relation == NameRelation.SUBDOMAIN: + if relation == dns.name.NameRelation.SUBDOMAIN: if not ce or common_labels > len(ce): # longest match so far ce = zname @@ -190,15 +198,3 @@ class ZoneAnalyzer: """ ce, _ = self.closest_encloser(qname) return Name("*") + ce - - -def is_related_to_any( - test_name: Name, - acceptable_relations: Container[NameRelation], - candidates: Iterable[Name], -) -> bool: - for maybe_parent in candidates: - relation, _, _ = test_name.fullcompare(maybe_parent) - if relation in acceptable_relations: - return True - return False diff --git a/bin/tests/system/nsec3-answer/tests_nsec3.py b/bin/tests/system/nsec3-answer/tests_nsec3.py index 33d16aca7f..785f574f42 100755 --- a/bin/tests/system/nsec3-answer/tests_nsec3.py +++ b/bin/tests/system/nsec3-answer/tests_nsec3.py @@ -14,7 +14,7 @@ from dataclasses import dataclass import os from pathlib import Path -from typing import Optional, Set, Tuple +from typing import Container, Iterable, Optional, Set, Tuple import pytest @@ -45,6 +45,18 @@ ZONE = isctest.name.ZoneAnalyzer.read_path( ) +def is_related_to_any( + test_name: dns.name.Name, + acceptable_relations: Container[dns.name.NameRelation], + candidates: Iterable[dns.name.Name], +) -> bool: + for maybe_parent in candidates: + relation, _, _ = test_name.fullcompare(maybe_parent) + if relation in acceptable_relations: + return True + return False + + def do_test_query( qname: dns.name.Name, qtype: dns.rdatatype.RdataType, server: str, named_port: int ) -> Tuple[dns.message.QueryMessage, "NSEC3Checker"]: @@ -103,7 +115,7 @@ def assume_nx_and_no_delegation(qname: dns.name.Name) -> None: # name must not be under a delegation or DNAME: # it would not work with resolver ns2 assume( - not isctest.name.is_related_to_any( + not is_related_to_any( qname, (dns.name.NameRelation.EQUAL, dns.name.NameRelation.SUBDOMAIN), ZONE.reachable_delegations.union(ZONE.reachable_dnames), diff --git a/bin/tests/system/nsupdate/tests_sh_nsupdate.py b/bin/tests/system/nsupdate/tests_sh_nsupdate.py index bd41ac64c5..c4ce9ab6f0 100644 --- a/bin/tests/system/nsupdate/tests_sh_nsupdate.py +++ b/bin/tests/system/nsupdate/tests_sh_nsupdate.py @@ -13,6 +13,9 @@ import platform import pytest +# isctest.asyncserver requires dnspython >= 2.0.0 +pytest.importorskip("dns", minversion="2.0.0") + pytestmark = pytest.mark.extra_artifacts( [ "Kxxx*", diff --git a/bin/tests/system/qmin/tests_sh_qmin.py b/bin/tests/system/qmin/tests_sh_qmin.py index 1116f7ec6c..4f5af7f56c 100644 --- a/bin/tests/system/qmin/tests_sh_qmin.py +++ b/bin/tests/system/qmin/tests_sh_qmin.py @@ -11,6 +11,9 @@ import pytest +# isctest.asyncserver requires dnspython >= 2.0.0 +pytest.importorskip("dns", minversion="2.0.0") + pytestmark = pytest.mark.extra_artifacts( [ "dig.out.*", diff --git a/bin/tests/system/rpzrecurse/tests_sh_rpzrecurse.py b/bin/tests/system/rpzrecurse/tests_sh_rpzrecurse.py index 983c6c3c33..3798ed6ee6 100644 --- a/bin/tests/system/rpzrecurse/tests_sh_rpzrecurse.py +++ b/bin/tests/system/rpzrecurse/tests_sh_rpzrecurse.py @@ -11,6 +11,9 @@ import pytest +# isctest.asyncserver requires dnspython >= 2.0.0 +pytest.importorskip("dns", minversion="2.0.0") + pytestmark = pytest.mark.extra_artifacts( [ "dig.out.*", diff --git a/bin/tests/system/rpzrecurse/tests_sh_rpzrecurse_dnsrps.py b/bin/tests/system/rpzrecurse/tests_sh_rpzrecurse_dnsrps.py index a32d70cd7a..427af96a79 100644 --- a/bin/tests/system/rpzrecurse/tests_sh_rpzrecurse_dnsrps.py +++ b/bin/tests/system/rpzrecurse/tests_sh_rpzrecurse_dnsrps.py @@ -11,6 +11,9 @@ import pytest +# isctest.asyncserver requires dnspython >= 2.0.0 +pytest.importorskip("dns", minversion="2.0.0") + import isctest.mark pytestmark = [ diff --git a/bin/tests/system/selftest/tests_zone_analyzer.py b/bin/tests/system/selftest/tests_zone_analyzer.py index 9cea8c7986..3c7a2fc609 100755 --- a/bin/tests/system/selftest/tests_zone_analyzer.py +++ b/bin/tests/system/selftest/tests_zone_analyzer.py @@ -26,6 +26,8 @@ import pytest import isctest import isctest.name +pytest.importorskip("dns.name", minversion="2.3.0") + # set of properies present in the tested zone - read by tests_zone_analyzer.py CATEGORIES = frozenset( [ diff --git a/bin/tests/system/statistics/tests_sh_statistics.py b/bin/tests/system/statistics/tests_sh_statistics.py index c96bb28808..7f3035b0fa 100644 --- a/bin/tests/system/statistics/tests_sh_statistics.py +++ b/bin/tests/system/statistics/tests_sh_statistics.py @@ -11,6 +11,9 @@ import pytest +# isctest.asyncserver requires dnspython >= 2.0.0 +pytest.importorskip("dns", minversion="2.0.0") + pytestmark = pytest.mark.extra_artifacts( [ "curl.out.*", diff --git a/bin/tests/system/tsig/tests_badtime.py b/bin/tests/system/tsig/tests_badtime.py index 1a45e51ec0..4f5a1b9f97 100644 --- a/bin/tests/system/tsig/tests_badtime.py +++ b/bin/tests/system/tsig/tests_badtime.py @@ -18,7 +18,9 @@ import time import pytest +# isctest.asyncserver requires dnspython >= 2.0.0 pytest.importorskip("dns", minversion="2.0.0") + import dns.message import dns.query import dns.tsigkeyring diff --git a/bin/tests/system/upforwd/tests_sh_upforwd.py b/bin/tests/system/upforwd/tests_sh_upforwd.py index 3dfa290a31..28be6c4c2d 100644 --- a/bin/tests/system/upforwd/tests_sh_upforwd.py +++ b/bin/tests/system/upforwd/tests_sh_upforwd.py @@ -11,6 +11,8 @@ import pytest +# isctest.asyncserver requires dnspython >= 2.0.0 +pytest.importorskip("dns", minversion="2.0.0") pytestmark = pytest.mark.extra_artifacts( [ diff --git a/bin/tests/system/xfer/tests_sh_xfer.py b/bin/tests/system/xfer/tests_sh_xfer.py index d94f90b981..5226cfc50b 100644 --- a/bin/tests/system/xfer/tests_sh_xfer.py +++ b/bin/tests/system/xfer/tests_sh_xfer.py @@ -11,6 +11,9 @@ import pytest +# isctest.asyncserver requires dnspython >= 2.0.0 +pytest.importorskip("dns", minversion="2.0.0") + pytestmark = pytest.mark.extra_artifacts( [ "axfr.out", diff --git a/bin/tests/system/zero/tests_sh_zero.py b/bin/tests/system/zero/tests_sh_zero.py index 3191f1c62a..50abfe0f2d 100644 --- a/bin/tests/system/zero/tests_sh_zero.py +++ b/bin/tests/system/zero/tests_sh_zero.py @@ -11,6 +11,9 @@ import pytest +# isctest.asyncserver requires dnspython >= 2.0.0 +pytest.importorskip("dns", minversion="2.0.0") + pytestmark = pytest.mark.extra_artifacts( [ "dig.out*",