From 7d97d0d9ad29a22d9196811b37e1789d7e321a78 Mon Sep 17 00:00:00 2001 From: Johnathan Corgan Date: Thu, 1 Oct 2026 03:16:35 +0000 Subject: [PATCH] Fix stale fixtures, pins and comments in the packaging tests The OpenWrt upgrade fixture was the fips.yaml from the commit before the gateway's DNS port moved, not one any release shipped. Replace it with the v0.5.1 bytes and say which releases it stands for, since v0.3.0 to v0.4.2 shipped an older file with the same legacy listen line. busybox:1.37 moves with every 1.37.x rebuild, so the pin did not keep the shell under test fixed as its comment said. Pin the multi-arch index digest instead, as the tree does for its other third-party images. The comment describing run_ci_parity had drifted above run_openwrt_scripts; move it back to its function. The deb-install header named `apt install` where the script runs `apt-get install -y --no-install-recommends`, and its usage line omitted the --deb option the script accepts. Nothing in the tree read the package's Recommends: the Depends check compares Depends only, and the install test installs with --no-install-recommends. check-deb-depends.sh now compares each package's Recommends with the recommends Cargo.toml declares, in any order, and refuses to pass when that declaration cannot be read. --- testing/check-deb-depends.sh | 53 +++++++++++++++++++-- testing/ci-local.sh | 6 +-- testing/deb-install/test.sh | 14 +++--- testing/openwrt/fixtures/released-fips.yaml | 12 +++-- testing/openwrt/maintainer-scripts-test.sh | 9 ++-- testing/openwrt/scenarios.sh | 5 +- 6 files changed, 79 insertions(+), 20 deletions(-) diff --git a/testing/check-deb-depends.sh b/testing/check-deb-depends.sh index 63180d84..dc15fd50 100755 --- a/testing/check-deb-depends.sh +++ b/testing/check-deb-depends.sh @@ -26,11 +26,18 @@ # drops it. The equality rule is what keeps that hand-written floor honest: if # the toolchain stops needing it, or starts needing a newer one, this fails. # +# It also compares the package's Recommends with the recommends Cargo.toml's +# [package.metadata.deb] declares, entry for entry and in any order. Nothing +# else in the tree reads that field (deb-install installs with +# --no-install-recommends), so without this a packaging change that dropped or +# altered it would ship unnoticed. +# # Run it inside the build image (build-deb-container.sh does), so the symbols # files and the C library it reads are the ones cargo-deb read. On a host of a # different distribution a difference could come from the host instead. # # Usage: check-deb-depends.sh ... +# Cargo.toml is read from the checkout this script sits in. # Exit: 0 every package matches, 1 a mismatch, 2 could not establish a result. set -euo pipefail @@ -48,6 +55,32 @@ done exit 2 } +CARGO_TOML="$(cd "$(dirname "$0")/.." && pwd)/Cargo.toml" + +# The recommends value of Cargo.toml's [package.metadata.deb], or empty when +# the section declares none. Fails when the file or the section cannot be read, +# or the key is not a one-line string, so an unreadable declaration is never +# compared as an empty one. +declared_recommends() { + awk ' + /^\[/ { insec = ($0 == "[package.metadata.deb]"); if (insec) found = 1; next } + insec && /^recommends[[:space:]]*=/ { + if (match($0, /^recommends[[:space:]]*=[[:space:]]*"[^"]*"[[:space:]]*$/)) { + sub(/^recommends[[:space:]]*=[[:space:]]*"/, ""); sub(/"[[:space:]]*$/, "") + print; done = 1; exit 0 + } + bad = 1; exit 0 + } + END { if (!found || bad) exit 1 } + ' "$CARGO_TOML" +} + +if ! DECLARED_RECOMMENDS=$(declared_recommends 2>/dev/null); then + echo "check-deb-depends: cannot read a one-line recommends from [package.metadata.deb] in $CARGO_TOML." >&2 + echo " Refusing to report a pass I did not establish." >&2 + exit 2 +fi + FAILED=0 UNKNOWN=0 CHECKED=0 @@ -59,6 +92,7 @@ SIMPLE_RE='^([a-z0-9][a-z0-9+.-]*)( \(>= ([^)]+)\))?$' # Split a Depends value on commas into one trimmed entry per line. split_deps() { printf '%s\n' "$1" | tr ',' '\n' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' | sed '/^$/d' + return 0 } check_deb() { @@ -178,11 +212,22 @@ check_deb() { echo " hand-declared $e" done < <(split_deps "$shipped") + # Recommends: the same entries as Cargo.toml declares, order aside. + local recommends want got + recommends=$(dpkg-deb -f "$deb" Recommends) + echo " recommends shipped: ${recommends:-(none)}; declared: ${DECLARED_RECOMMENDS:-(none)}" + want=$(split_deps "$DECLARED_RECOMMENDS" | sort) + got=$(split_deps "$recommends" | sort) + if [ "$want" != "$got" ]; then + echo " FAIL $label: Recommends '${recommends}' differs from Cargo.toml's recommends '${DECLARED_RECOMMENDS}'" >&2 + bad=1 + fi + CHECKED=$((CHECKED + 1)) [ "$bad" -eq 0 ] || FAILED=$((FAILED + 1)) } -echo "=== Depends check (shipped Depends against dpkg-shlibdeps) ===" +echo "=== Depends check (shipped Depends against dpkg-shlibdeps, Recommends against Cargo.toml) ===" for arg in "$@"; do if [ ! -f "$arg" ]; then echo " ERROR $arg does not exist" >&2 @@ -193,9 +238,11 @@ for arg in "$@"; do done if [ "$FAILED" -ne 0 ]; then - echo "check-deb-depends: $FAILED of $CHECKED package(s) declare Depends that differ from what their binaries need." >&2 - echo " A missing or low entry installs where the binaries cannot run; a high one" >&2 + echo "check-deb-depends: $FAILED of $CHECKED package(s) declare Depends that differ from what their binaries need," >&2 + echo " or Recommends that differ from what Cargo.toml declares." >&2 + echo " A missing or low Depends entry installs where the binaries cannot run; a high one" >&2 echo " is a hand-written floor that no longer tracks them. Fix Cargo.toml's depends." >&2 + echo " A Recommends difference means the packaging did not carry Cargo.toml's recommends." >&2 exit 1 fi diff --git a/testing/ci-local.sh b/testing/ci-local.sh index d48acb9b..96071e87 100755 --- a/testing/ci-local.sh +++ b/testing/ci-local.sh @@ -1465,9 +1465,6 @@ print_summary() { echo "" } -# Verify the local default suite set and the GitHub matrix still cover the -# same work. Runs first: it takes about a second, and a divergence should be -# reported before a half-hour suite rather than after it. # The OpenWrt maintainer scripts and the fips-gateway init script ship to # routers and run there under ash, never under bash. This runs them under ash # in a busybox container against stubbed init scripts, so an install, an @@ -1493,6 +1490,9 @@ run_tarball_install() { return $rc } +# Verify the local default suite set and the GitHub matrix still cover the +# same work. Runs first: it takes about a second, and a divergence should be +# reported before a half-hour suite rather than after it. run_ci_parity() { local rc=0 info "[ci-parity] Comparing the local suite set against the GitHub matrix" diff --git a/testing/deb-install/test.sh b/testing/deb-install/test.sh index a1419491..c43aad94 100755 --- a/testing/deb-install/test.sh +++ b/testing/deb-install/test.sh @@ -4,11 +4,12 @@ # Each scenario takes the .deb from --deb, or builds (or reuses) it # through packaging/debian/build-deb-container.sh, boots a systemd # container with TUN access for the target distro, installs the .deb -# via `apt install ./fips_*.deb`, waits for fips.service + fips-dns.service -# to come up, and verifies that `dig @127.0.0.53 AAAA .fips` -# returns a non-empty AAAA answer through the resolver backend that -# fips-dns-setup configured. Then exercises fips-gateway against the -# same daemon to verify the gateway/daemon default-pairing. Finally it +# via `apt-get install -y --no-install-recommends ./fips_*.deb`, waits +# for fips.service + fips-dns.service to come up, and verifies that +# `dig @127.0.0.53 AAAA .fips` returns a non-empty AAAA answer +# through the resolver backend that fips-dns-setup configured. Then +# exercises fips-gateway against the same daemon to verify the +# gateway/daemon default-pairing. Finally it # purges the package with the DNS routing file planted and fips-dns # stopped, and checks the file is removed and systemd-resolved restarted. # @@ -21,9 +22,10 @@ # - The fips, fips-dns, and (optionally) fips-gateway systemd units # - End-to-end .fips resolution as a real user would experience it # -# Usage: ./test.sh [scenario ...] +# Usage: ./test.sh [--deb PATH] [scenario ...] # No args = run all scenarios. # Named args = run only those (e.g., ./test.sh ubuntu26 debian12) +# --deb PATH = install that package instead of building one. # # Requirements: Docker able to grant SYS_ADMIN and NET_ADMIN and an # unconfined AppArmor profile (the containers are not privileged; see diff --git a/testing/openwrt/fixtures/released-fips.yaml b/testing/openwrt/fixtures/released-fips.yaml index 2f15160d..6bb09aee 100644 --- a/testing/openwrt/fixtures/released-fips.yaml +++ b/testing/openwrt/fixtures/released-fips.yaml @@ -162,11 +162,17 @@ transports: # auto_connect: true # accept_connections: true - # No BLE transport: OpenWrt builds target musl, which has no BlueZ backend. + # Bluetooth Low Energy transport — requires BlueZ and the 'ble' feature. + # ble: + # adapter: "hci0" + # mtu: 2048 + # advertise: true + # scan: true + # auto_connect: true + # accept_connections: true # Outbound LAN gateway. dnsmasq forwards .fips queries to listen=[::1]:5353 -# while it runs (configured by the fips-gateway init script). Requires IPv6 -# forwarding enabled. +# (configured by the fips init script). Requires IPv6 forwarding enabled. gateway: enabled: true pool: "fd01::/112" diff --git a/testing/openwrt/maintainer-scripts-test.sh b/testing/openwrt/maintainer-scripts-test.sh index ad707410..8cf486b8 100755 --- a/testing/openwrt/maintainer-scripts-test.sh +++ b/testing/openwrt/maintainer-scripts-test.sh @@ -17,9 +17,12 @@ set -uo pipefail SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" -# Pinned rather than :latest so the shell under test does not change under a -# run. Overridable for trying another ash build. -IMAGE="${OPENWRT_ASH_IMAGE:-busybox:1.37}" +# Pinned by digest so the shell under test does not change under a run: the +# 1.37 tag moves with every 1.37.x rebuild. This is the multi-arch index digest +# of busybox:1.37.0 as of 2026-10-01. Bump it deliberately, reading the new +# digest with `docker buildx imagetools inspect busybox:`. +# Overridable for trying another ash build. +IMAGE="${OPENWRT_ASH_IMAGE:-busybox:1.37.0@sha256:bdf57e528e45e4433820e045b29b4597825a1c9e38353532d90a01445013f82e}" if ! command -v docker >/dev/null 2>&1; then echo "openwrt-scripts: docker not found; cannot run the ash scenarios" >&2 diff --git a/testing/openwrt/scenarios.sh b/testing/openwrt/scenarios.sh index fe78548f..0eadac3e 100755 --- a/testing/openwrt/scenarios.sh +++ b/testing/openwrt/scenarios.sh @@ -28,8 +28,9 @@ RELEASED_PRERM="$REPO/testing/openwrt/fixtures/released-prerm" INIT_GATEWAY="$REPO/packaging/openwrt-ipk/files/etc/init.d/fips-gateway" APK_SCRIPTS="${APK_SCRIPTS:-}" SHIPPED_YAML="$REPO/packaging/openwrt-ipk/files/etc/fips/fips.yaml" -# The fips.yaml every release up to 0.5.1 shipped, from before the gateway's -# default DNS port moved. +# The fips.yaml v0.5.0 and v0.5.1 shipped, byte for byte (from the v0.5.1 tag), +# from before the gateway's default DNS port moved. v0.3.0 to v0.4.2 shipped an +# older file with the same legacy listen line. RELEASED_YAML="$REPO/testing/openwrt/fixtures/released-fips.yaml" GATEWAY_RS="$REPO/src/config/gateway.rs" SETUP_SCRIPT="$REPO/packaging/openwrt-ipk/files/etc/uci-defaults/90-fips-setup"