Commit 642cdeec60 for bind
commit 642cdeec605f0d2d114fc1d4849486dee1be0a11
Author: Štěpán Balážik <stepan@isc.org>
Date: Tue Sep 8 17:06:00 2026 +0200
Match on the number of QNAME labels with a matcher
LabelCount declares how many labels the QNAME a handler answers has,
which was previously done with a match() method.
Assisted-by: Claude:claude-fable-5
diff --git a/bin/tests/system/cookie/cookie_ans.py b/bin/tests/system/cookie/cookie_ans.py
index 1e186d73b3..108cac2ff3 100644
--- a/bin/tests/system/cookie/cookie_ans.py
+++ b/bin/tests/system/cookie/cookie_ans.py
@@ -25,7 +25,7 @@ from isctest.asyncserver import (
ResponseHandler,
)
from isctest.asyncserver.actions import DnsResponseSend
-from isctest.asyncserver.matchers import LeftmostLabel, Protocol, Qtype
+from isctest.asyncserver.matchers import LabelCount, LeftmostLabel, Protocol, Qtype
from isctest.name import prepend_label
from isctest.vars.algorithms import ALG_VARS
@@ -92,8 +92,7 @@ class _SpoofableHandler(ResponseHandler):
class NsHandler(_SpoofableHandler):
- def match(self, qctx: QueryContext) -> bool:
- return qctx.qtype == dns.rdatatype.NS and qctx.qname == _tld(qctx)
+ matcher = Qtype(dns.rdatatype.NS) & LabelCount(2)
async def get_responses(
self, qctx: QueryContext
@@ -108,8 +107,7 @@ class NsHandler(_SpoofableHandler):
class GlueHandler(_SpoofableHandler):
- def match(self, qctx: QueryContext) -> bool:
- return qctx.qtype == dns.rdatatype.A and qctx.qname == _ns_name(qctx)
+ matcher = Qtype(dns.rdatatype.A) & LabelCount(3) & LeftmostLabel(b"ns")
async def get_responses(
self, qctx: QueryContext
diff --git a/bin/tests/system/isctest/asyncserver/matchers.py b/bin/tests/system/isctest/asyncserver/matchers.py
index 97c630bc64..dcdb37dba3 100644
--- a/bin/tests/system/isctest/asyncserver/matchers.py
+++ b/bin/tests/system/isctest/asyncserver/matchers.py
@@ -293,3 +293,19 @@ class LeftmostLabelPrefix(LabelPredicate):
lambda label: label.startswith(prefix),
f"starting with {prefix.decode()}",
)
+
+
+class LabelCount(Matcher):
+ """
+ Match queries whose QNAME has the given number of labels, the root label
+ included.
+ """
+
+ def __init__(self, count: int) -> None:
+ self._count = count
+
+ def match(self, qctx: QueryContext) -> bool:
+ return len(qctx.qname.labels) == self._count
+
+ def __str__(self) -> str:
+ return f"QNAME of {self._count} labels"