]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
test: make the resolved notifications check a bit more robust 24637/head
authorFrantisek Sumsal <frantisek@sumsal.cz>
Sun, 11 Sep 2022 12:17:56 +0000 (14:17 +0200)
committerFrantisek Sumsal <frantisek@sumsal.cz>
Sun, 11 Sep 2022 12:29:34 +0000 (14:29 +0200)
Let's parse the resolved JSON notifications via `jq` and check them in a
bit more "controlled" manner - e.g. until now the `grep` was checking just
a one gigantic JSON string, as all received notifications via the
varlink socket are terminated by a NUL character, not a newline.

Also, as the notification delivery is asynchronous, retry the check
a couple of times if it fails (spotted in C8S jobs):

```
[ 2891.935879] testsuite-75.sh[36]: + : '--- nss-resolve/nss-myhostname tests'
[ 2891.935988] testsuite-75.sh[36]: + run getent -s resolve hosts ns1.unsigned.test
[ 2891.936542] testsuite-75.sh[177]: + getent -s resolve hosts ns1.unsigned.test
[ 2891.937499] testsuite-75.sh[178]: + tee /tmp/tmp.pqjNvbQ2eS
[ 2891.939977] testsuite-75.sh[178]: 10.0.0.1        ns1.unsigned.test
[ 2891.940258] testsuite-75.sh[36]: + grep -qE '^10\.0\.0\.1\s+ns1\.unsigned\.test' /tmp/tmp.pqjNvbQ2eS
[ 2891.942235] testsuite-75.sh[189]: + grep -qF '[10,0,0,1]'
[ 2891.942577] testsuite-75.sh[188]: + grep -aF ns1.unsigned.test /tmp/notifications.txt
[ 2891.943978] systemd[1]: testsuite-75.service: Child 36 belongs to testsuite-75.service.
[ 2891.944112] systemd[1]: testsuite-75.service: Main process exited, code=exited, status=1/FAILURE
[ 2891.944215] systemd[1]: testsuite-75.service: Failed with result 'exit-code'.
```

test/units/testsuite-75.sh

index 26ad109538585eb99ff2f9fa53f5f836fd6347be..ba91284a73efabc6e5181f262a4f72ae66b98a97 100755 (executable)
@@ -11,10 +11,71 @@ RUN_OUT="$(mktemp)"
 NOTIFICATION_SUBSCRIPTION_SCRIPT="/tmp/subscribe.sh"
 NOTIFICATION_LOGS="/tmp/notifications.txt"
 
+at_exit() {
+    set +e
+    cat "$NOTIFICATION_LOGS"
+}
+
+trap at_exit EXIT
+
 run() {
     "$@" |& tee "$RUN_OUT"
 }
 
+run_retry() {
+    local ntries="${1:?}"
+    local i
+
+    shift
+
+    for ((i = 0; i < ntries; i++)); do
+        "$@" && return 0
+        sleep .5
+    done
+
+    return 1
+}
+
+notification_check_host() {
+    local host="${1:?}"
+    local address="${2:?}"
+
+    # Attempt to parse the notification JSON returned over varlink and check
+    # if it contains the requested record. As this is an async operation, let's
+    # retry it a couple of times in case it fails.
+    #
+    # Example JSON:
+    # {
+    #   "parameters": {
+    #     "addresses": [
+    #       {
+    #         "ifindex": 2,
+    #         "family": 2,
+    #         "address": [
+    #           10,
+    #           0,
+    #           0,
+    #           121
+    #         ],
+    #         "type": "A"
+    #       }
+    #     ],
+    #     "name": "untrusted.test"
+    #   },
+    #   "continues": true
+    # }
+    #
+    # Note: we need to do some post-processing of the $NOTIFICATION_LOGS file,
+    #       since the JSON objects are concatenated with \0 instead of a newline
+    # shellcheck disable=SC2016
+    run_retry 10 jq --slurp \
+                    --exit-status \
+                    --arg host "$host" \
+                    --arg address "$address" \
+                    '.[] | select(.parameters.name == $host) | .parameters.addresses[] | select(.address | join(".") == $address) | true' \
+                    <(tr '\0' '\n' <"$NOTIFICATION_LOGS")
+}
+
 ### SETUP ###
 # Configure network
 hostnamectl hostname ns1.unsigned.test
@@ -120,7 +181,7 @@ knotc reload
 # Sanity check
 run getent -s resolve hosts ns1.unsigned.test
 grep -qE "^10\.0\.0\.1\s+ns1\.unsigned\.test" "$RUN_OUT"
-grep -aF "ns1.unsigned.test" $NOTIFICATION_LOGS | grep -qF "[10,0,0,1]"
+notification_check_host "ns1.unsigned.test" "10.0.0.1"
 
 # Issue: https://github.com/systemd/systemd/issues/18812
 # PR: https://github.com/systemd/systemd/pull/18896
@@ -213,7 +274,7 @@ grep -qF "; fully validated" "$RUN_OUT"
 run resolvectl query -t A cname-chain.signed.test
 grep -qF "follow14.final.signed.test IN A 10.0.0.14" "$RUN_OUT"
 grep -qF "authenticated: yes" "$RUN_OUT"
-grep -aF "cname-chain.signed.test" $NOTIFICATION_LOGS | grep -qF "[10,0,0,14]"
+notification_check_host "cname-chain.signed.test" "10.0.0.14"
 # Non-existing RR + CNAME chain
 run dig +dnssec AAAA cname-chain.signed.test
 grep -qF "status: NOERROR" "$RUN_OUT"
@@ -252,7 +313,7 @@ grep -qF "authenticated: yes" "$RUN_OUT"
 # Resolve via dbus method
 run busctl call org.freedesktop.resolve1 /org/freedesktop/resolve1 org.freedesktop.resolve1.Manager ResolveHostname 'isit' 0 secondsub.onlinesign.test 0 0
 grep -qF '10 0 0 134 "secondsub.onlinesign.test"' "$RUN_OUT"
-grep -aF "secondsub.onlinesign.test" $NOTIFICATION_LOGS | grep -qF "[10,0,0,134]"
+notification_check_host "secondsub.onlinesign.test" "10.0.0.134"
 
 : "--- ZONE: untrusted.test (DNSSEC without propagated DS records) ---"
 run dig +short untrusted.test
@@ -271,7 +332,5 @@ grep -qF "authenticated: no" "$RUN_OUT"
 #run dig +dnssec this.does.not.exist.untrusted.test
 #grep -qF "status: NXDOMAIN" "$RUN_OUT"
 
-cat $NOTIFICATION_LOGS
-
 touch /testok
 rm /failed