Files
computer-playbook/scripts/tests/deploy/ci/dns53-sampler.sh
kevinveenbirkenbachandClaude Opus 5.5 891d46d589 fix(ci): time the DNS53 sampler probes from /proc/uptime
The 🐳 Workspace (ubuntu:latest) job on main (run 38879556215, 1b36ef6120)
failed test-unit-python in the hook's second make test:

    AssertionError: Regex didn't match: '^ localhost=ok/\d+ms$'
    not found in ' localhost=ok/-1612931482679767779ms'

ubuntu:latest is Ubuntu 26.04, whose date is uutils coreutils. uutils
0.7.0 ignores the field width in %3N and prints all nine nanosecond
digits, so `date +%s%3N` yields a 19-digit value instead of epoch
milliseconds. Against main's sampler, uutils 0.7.0 date reports
localhost=ok/7081859ms, and an unpadded nanosecond value turns the
difference negative.

answer_once now takes both timestamps from /proc/uptime, which the
kernel prints with two decimals whatever date the image ships. The
sampler already reads /proc/net/udp, so it was Linux-only before. The
resolution is 10 ms; the same probe reports 10 to 20 ms with uutils
date on PATH.

The new test puts a date on PATH that does not understand %3N; main's
sampler dies on it, the fixed one does not call date for the latency.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-16 14:15:25 +02:00

57 lines
1.6 KiB
Bash
Executable File

#!/bin/sh
# Run 32118850138 could bound the dnsmasq listener loss only to a 6m39s
# window between two host DNS consumers; one line per 10s pins it to one
# sample bucket and names which :53 listener (hex local_address) was left.
set -u
EXTERNAL_PROBE_NAME=deb.debian.org
sample_once() {
socks="$(awk '$2 ~ /:0035$/ && $3 == "00000000:0000" {printf " %s", $2}' "${1}")"
printf '%s%s\n' "$(date -u '+%Y-%m-%dT%H:%M:%SZ')" "${socks:- none}"
}
zone_probe_name() {
dirs="$(sed -n 's|^[[:space:]]*conf-dir=\([^,[:space:]]*\).*|\1|p' "${1}" 2>/dev/null)"
# shellcheck disable=SC2086 # a dnsmasq conf-dir path carries no whitespace
zone="$(grep -rhs '^[[:space:]]*address=/' "${1}" ${dirs} |
sed -n 's|^[[:space:]]*address=/\([^/]*\)/.*|\1|p' | head -n1)"
[ -n "${zone}" ] || return 0
printf 'rescue-probe.%s' "${zone}"
}
uptime_ms() {
read -r up _ </proc/uptime
printf '%s' "$((${up%.*}${up#*.} * 10))"
}
answer_once() {
name="${1}"
start="$(uptime_ms)"
if timeout 3 getent ahosts "${name}" >/dev/null 2>&1; then
verdict=ok
else
verdict=fail
fi
printf ' %s=%s/%sms' "${name}" "${verdict}" "$(($(uptime_ms) - start))"
}
[ "${DNS53_SAMPLER_LIB:-}" = "1" ] && return 0
: "${INFINITO_DNS53_SAMPLER_LOG:?INFINITO_DNS53_SAMPLER_LOG must be set}"
mkdir -p "$(dirname "${INFINITO_DNS53_SAMPLER_LOG}")"
while :; do
{
printf '%s' "$(sample_once /proc/net/udp)"
inzone="$(zone_probe_name /etc/dnsmasq.conf)"
if [ -n "${inzone}" ]; then
answer_once "${inzone}"
else
printf ' inzone=unconfigured'
fi
answer_once "${EXTERNAL_PROBE_NAME}"
printf '\n'
} >>"${INFINITO_DNS53_SAMPLER_LOG}"
sleep 10
done