]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Migrate digdelv dig +yaml structure checks to pytest
authorMartin Basti <mbasti@isc.org>
Wed, 22 Jul 2026 21:47:34 +0000 (21:47 +0000)
committerMartin Basti <mbasti@isc.org>
Wed, 29 Jul 2026 11:54:10 +0000 (13:54 +0200)
Move the remaining dig checks from tests.sh into tests_dig.py: the
structure of +yaml output for an ANY query, the printing of an IPv6
address ending in zeroes, the quoting of qnames containing characters
special to YAML, and the quoting of all 256 character values in TXT
rdata, whose expected string is now computed instead of spelled out
over thirty lines.  This completes the dig section of tests.sh, so the
dig_with_opts and set_response_sequence helpers are removed with it.

Assisted-by: Claude:claude-fable-5
bin/tests/system/digdelv/tests.sh
bin/tests/system/digdelv/tests_dig.py

index a00494dcafad93e8062b8b1640baf21e16130c35..6bf4eafdbbdcda98d6539bede0728938bbb155ad 100644 (file)
@@ -19,20 +19,10 @@ set -e
 status=0
 n=0
 
-dig_with_opts() {
-  "$DIG" -p "$PORT" "$@"
-}
-
 mdig_with_opts() {
   "$MDIG" -p "$PORT" "$@"
 }
 
-set_response_sequence() {
-  SEQUENCE="${1}"
-  LOGID="${2}"
-  dig_with_opts @10.53.0.5 "${SEQUENCE}.response-sequence._control" TXT >dig.out.control${LOGID} 2>&1 || ret=1
-}
-
 # Check if response in file $1 has the correct TTL range.
 # The response record must have RRtype $2 and class IN (CLASS1).
 # Maximum TTL is given by $3.  This works in most cases where TTL is
@@ -73,38 +63,6 @@ NOSPLIT="$(sed <ns2/keydata -e 's/+/[+]/g' -e 's/ //g')"
 HAS_PYYAML=0
 $PYTHON -c "import yaml" 2>/dev/null && HAS_PYYAML=1
 
-if [ -x "$DIG" ]; then
-  if [ $HAS_PYYAML -ne 0 ]; then
-    n=$((n + 1))
-    echo_i "check dig +yaml ANY output ($n)"
-    ret=0
-    dig_with_opts +qr +yaml @10.53.0.3 any ns2.example >dig.out.test$n 2>&1 || ret=1
-    $PYTHON yamlget.py dig.out.test$n 0 message query_message_data status >yamlget.out.test$n 2>&1 || ret=1
-    read -r value <yamlget.out.test$n
-    [ "$value" = "NOERROR" ] || ret=1
-    $PYTHON yamlget.py dig.out.test$n 1 message response_message_data status >yamlget.out.test$n 2>&1 || ret=1
-    read -r value <yamlget.out.test$n
-    [ "$value" = "NOERROR" ] || ret=1
-    $PYTHON yamlget.py dig.out.test$n 1 message response_message_data QUESTION_SECTION 0 >yamlget.out.test$n 2>&1 || ret=1
-    read -r value <yamlget.out.test$n
-    [ "$value" = "ns2.example. IN ANY" ] || ret=1
-    if [ $ret -ne 0 ]; then echo_i "failed"; fi
-    status=$((status + ret))
-
-    n=$((n + 1))
-    echo_i "check dig +yaml output of an IPv6 address ending in zeroes ($n)"
-    ret=0
-    dig_with_opts +qr +yaml @10.53.0.3 aaaa d.example >dig.out.test$n 2>&1 || ret=1
-    $PYTHON yamlget.py dig.out.test$n 1 message response_message_data ANSWER_SECTION 0 >yamlget.out.test$n 2>&1 || ret=1
-    read -r value <yamlget.out.test$n
-    [ "$value" = "d.example. 300 IN AAAA fd92:7065:b8e:ffff::0" ] || ret=1
-    if [ $ret -ne 0 ]; then echo_i "failed"; fi
-    status=$((status + ret))
-  fi
-else
-  echo_i "$DIG is needed, so skipping these dig tests"
-fi
-
 if [ -x "$MDIG" ]; then
   n=$((n + 1))
   echo_i "checking mdig +tcp works with a source address and port ($n)"
@@ -570,60 +528,5 @@ else
   echo_i "$DELV is needed, so skipping these delv tests"
 fi
 
-if [ $HAS_PYYAML -ne 0 ]; then
-  for qname in "yaml" "'.yaml" "[.yaml" "{.yaml" "&.yaml" "#.yaml"; do
-    n=$((n + 1))
-    echo_i "check yaml special '${yaml}.example' ($n)"
-    ret=0
-    dig_with_opts @10.53.0.3 +yaml "${qname}.example" TXT +qr >dig.out.test$n 2>&1 || ret=1
-    $PYTHON yamlget.py dig.out.test$n 0 message query_message_data QUESTION_SECTION 0 >yamlget.out.test$n 2>&1 || ret=1
-    read -r value <yamlget.out.test$n
-    [ "$value" = "${qname}.example. IN TXT" ] || ret=1
-    $PYTHON yamlget.py dig.out.test$n 1 message response_message_data ANSWER_SECTION 0 >yamlget.out.test$n 2>&1 || ret=1
-    read -r value <yamlget.out.test$n
-    [ "$value" = "${qname}"'.example. 300 IN TXT "a: b"' ] || ret=1
-    if [ $ret -ne 0 ]; then echo_i "failed"; fi
-    status=$((status + ret))
-  done
-
-  n=$((n + 1))
-  echo_i "check yaml character values ($n)"
-  ret=0
-  dig_with_opts @10.53.0.3 +yaml "all.yaml.example" TXT +qr >dig.out.test$n 2>&1 || ret=1
-  $PYTHON yamlget.py dig.out.test$n 1 message response_message_data ANSWER_SECTION 0 >yamlget.out.test$n 2>&1 || ret=1
-  read -r value <yamlget.out.test$n
-  expected='all.yaml.example. 300 IN TXT'
-  expected="$expected "'"\000" "\001" "\002" "\003" "\004" "\005" "\006" "\007"'
-  expected="$expected "'"\008" "\009" "\010" "\011" "\012" "\013" "\014" "\015"'
-  expected="$expected "'"\016" "\017" "\018" "\019" "\020" "\021" "\022" "\023"'
-  expected="$expected "'"\024" "\025" "\026" "\027" "\028" "\029" "\030" "\031"'
-  expected="$expected "'" " "!" "\"" "#" "$" "%" "&" "'"'"'" "(" ")" "*" "+" ","'
-  expected="$expected "'"-" "." "/" "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" ":"'
-  expected="$expected "'";" "<" "=" ">" "?" "@" "A" "B" "C" "D" "E" "F" "G" "H"'
-  expected="$expected "'"I" "J" "K" "L" "M" "N" "O" "P" "Q" "R" "S" "T" "U" "V"'
-  expected="$expected "'"W" "X" "Y" "Z" "[" "\\" "]" "^" "_" "`" "a" "b" "c" "d"'
-  expected="$expected "'"e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r"'
-  expected="$expected "'"s" "t" "u" "v" "w" "x" "y" "z" "{" "|" "}" "~" "\127"'
-  expected="$expected "'"\128" "\129" "\130" "\131" "\132" "\133" "\134" "\135"'
-  expected="$expected "'"\136" "\137" "\138" "\139" "\140" "\141" "\142" "\143"'
-  expected="$expected "'"\144" "\145" "\146" "\147" "\148" "\149" "\150" "\151"'
-  expected="$expected "'"\152" "\153" "\154" "\155" "\156" "\157" "\158" "\159"'
-  expected="$expected "'"\160" "\161" "\162" "\163" "\164" "\165" "\166" "\167"'
-  expected="$expected "'"\168" "\169" "\170" "\171" "\172" "\173" "\174" "\175"'
-  expected="$expected "'"\176" "\177" "\178" "\179" "\180" "\181" "\182" "\183"'
-  expected="$expected "'"\184" "\185" "\186" "\187" "\188" "\189" "\190" "\191"'
-  expected="$expected "'"\192" "\193" "\194" "\195" "\196" "\197" "\198" "\199"'
-  expected="$expected "'"\200" "\201" "\202" "\203" "\204" "\205" "\206" "\207"'
-  expected="$expected "'"\208" "\209" "\210" "\211" "\212" "\213" "\214" "\215"'
-  expected="$expected "'"\216" "\217" "\218" "\219" "\220" "\221" "\222" "\223"'
-  expected="$expected "'"\224" "\225" "\226" "\227" "\228" "\229" "\230" "\231"'
-  expected="$expected "'"\232" "\233" "\234" "\235" "\236" "\237" "\238" "\239"'
-  expected="$expected "'"\240" "\241" "\242" "\243" "\244" "\245" "\246" "\247"'
-  expected="$expected "'"\248" "\249" "\250" "\251" "\252" "\253" "\254" "\255"'
-  [ "$value" = "$expected" ] || ret=1
-  if [ $ret -ne 0 ]; then echo_i "failed"; fi
-  status=$((status + ret))
-fi
-
 echo_i "exit status: $status"
 [ $status -eq 0 ] || exit 1
index 6c1ec1b6798c93dee53bc0012fb1c501b896984c..e1ee7859533dc8eb92752508fbe75eafed3373b4 100644 (file)
@@ -1014,3 +1014,60 @@ def test_source_address_both_families_no_crash(dig, ns1):
     by a signal) is an error.  See GL #5609 for more information."""
     result = dig(f"@localhost example -b {ns1.ip}", raise_on_exception=False)
     assert result.rc >= 0
+
+
+@needs_pyyaml
+def test_yaml_any_output(dig, ns3):
+    """Check the structure of dig +yaml output for an ANY query."""
+    result = dig(f"+qr +yaml @{ns3.ip} any ns2.example")
+    messages = parse_yaml(result.out)
+    query = messages[0]["message"]["query_message_data"]
+    assert query["status"] == "NOERROR"
+    response = messages[1]["message"]["response_message_data"]
+    assert response["status"] == "NOERROR"
+    assert response["QUESTION_SECTION"][0] == "ns2.example. IN ANY"
+
+
+@needs_pyyaml
+def test_yaml_ipv6_trailing_zeroes(dig, ns3):
+    """Check dig +yaml output of an IPv6 address ending in zeroes."""
+    result = dig(f"+qr +yaml @{ns3.ip} aaaa d.example")
+    response = parse_yaml(result.out)[1]["message"]["response_message_data"]
+    answer = response["ANSWER_SECTION"][0]
+    assert answer == "d.example. 300 IN AAAA fd92:7065:b8e:ffff::0"
+
+
+@needs_pyyaml
+@pytest.mark.parametrize(
+    "qname", ["yaml", "'.yaml", "[.yaml", "{.yaml", "&.yaml", "#.yaml"]
+)
+def test_yaml_special_characters_in_qname(dig, ns3, qname):
+    """Check that qnames containing characters special to YAML are quoted
+    correctly in dig +yaml output."""
+    result = dig(f"@{ns3.ip} +yaml {qname}.example TXT +qr")
+    query = parse_yaml(result.out)[0]["message"]["query_message_data"]
+    question = query["QUESTION_SECTION"][0]
+    assert question == f"{qname}.example. IN TXT"
+    response = parse_yaml(result.out)[1]["message"]["response_message_data"]
+    answer = response["ANSWER_SECTION"][0]
+    assert answer == f'{qname}.example. 300 IN TXT "a: b"'
+
+
+@needs_pyyaml
+def test_yaml_character_values(dig, ns3):
+    """Check the quoting of all 256 character values in dig +yaml TXT
+    output."""
+
+    def quoted(i):
+        char = chr(i)
+        if char in ('"', "\\"):
+            return f'"\\{char}"'
+        if 32 <= i <= 126:
+            return f'"{char}"'
+        return f'"\\{i:03d}"'
+
+    result = dig(f"@{ns3.ip} +yaml all.yaml.example TXT +qr")
+    response = parse_yaml(result.out)[1]["message"]["response_message_data"]
+    answer = response["ANSWER_SECTION"][0]
+    strings = " ".join(quoted(i) for i in range(256))
+    assert answer == f"all.yaml.example. 300 IN TXT {strings}"