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/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( [