From af5566c514f519ddc723ccd0bf6a1b83e904dfd5 Mon Sep 17 00:00:00 2001 From: Daniel Rapp Date: Thu, 23 Jul 2026 12:30:56 +0000 Subject: [PATCH] =?UTF-8?q?fix(test):=20=C2=A779=20macOS/BSD=20portability?= =?UTF-8?q?=20=E2=80=94=20awk=20\$-anchor=20+=20wc=20leading=20whitespace?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three §79 (`sandy --gc`) checks passed in CI (Ubuntu/GNU) but failed on a macOS host. Both root causes are BSD-userland vs GNU differences in the TEST harness only — the sandy --gc product code is unaffected (every per-container identity assertion passed on macOS; only these three broke): 1/2. The two structural checks extracting the --gc dispatcher block used `awk "/^if \[\[ \"\${1:-}\" == \"--gc\" \]\]; then/,/^fi$/"`. macOS's BWK awk ("the one true awk") treats `\$` as the `$` end-of-line ANCHOR (dropping the backslash) rather than a literal `$`, putting an anchor mid-pattern so the range start never matches → empty region → the greps for `_sandy_gc_dry_run` / `_sandy_dead_owner_containers_list reap` fail. GNU awk and mawk treat `\$` as a literal `$`, so CI passed. Rewrote the start pattern to `/^if .*--gc/` (no literal `$`), which matches exactly the one dispatcher line and extracts the identical 143-line region on gawk/mawk/BWK awk. 3. `sort -u "$1" | wc -l | grep -qx 5` — BSD `wc -l` emits leading whitespace (` 5`) even when piped, so the whole-line match `grep -qx 5` fails on macOS. Replaced with `[ "$(... | wc -l | tr -d ' ')" = 5 ]`. Verified: both structural checks pass under mawk (BSD regex proxy); the count fix handles leading-whitespace wc. No other `\${1:-}`-in-awk or `wc -l | grep -qx` traps remain in the suite. Co-Authored-By: Claude Opus 4.8 --- test/run-tests.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/run-tests.sh b/test/run-tests.sh index b80a030..8f09b7a 100755 --- a/test/run-tests.sh +++ b/test/run-tests.sh @@ -5672,7 +5672,7 @@ check "the container-liveness gate never reads/queries the sandy.daemon_pid labe ! printf "%s" "$_f" | grep -q "sandy\.daemon_pid"' -- "$_S79" check "--gc parses its OWN --dry-run/--yes into distinct locals, not SANDY_UPDATE_*" \ - bash -c '_f="$(awk "/^if \[\[ \"\\\${1:-}\" == \"--gc\" \]\]; then/,/^fi\$/" "$1")" + bash -c '_f="$(awk "/^if .*--gc/,/^fi\$/" "$1")" printf "%s" "$_f" | grep -qF "_sandy_gc_dry_run" \ && printf "%s" "$_f" | grep -qF "_sandy_gc_yes" \ && ! printf "%s" "$_f" | grep -qE "SANDY_UPDATE_(DRY_RUN|YES)="' -- "$_S79" @@ -5698,7 +5698,7 @@ check "the container reaper invokes the lister with the retrying 'reap' mode" \ printf "%s" "$_f" | grep -qF "_sandy_dead_owner_containers_list reap"' -- "$_S79" check "the --gc dispatcher's plan step also uses 'reap' mode (plan matches what actually happens)" \ - bash -c '_f="$(awk "/^if \[\[ \"\\\${1:-}\" == \"--gc\" \]\]; then/,/^fi\$/" "$1")" + bash -c '_f="$(awk "/^if .*--gc/,/^fi\$/" "$1")" printf "%s" "$_f" | grep -qF "_sandy_dead_owner_containers_list reap"' -- "$_S79" check "the container-liveness gate discriminates agent-vs-proxy by IMAGE, not name prefix (B1/B2 fix)" \ @@ -5906,7 +5906,7 @@ _S79_YES_RC=0 PATH="$_S79_BIN:$PATH" SANDY_HOME="$_S79_HOME" bash "$_S79" --gc --yes /dev/null 2>&1 || _S79_YES_RC=$? check "--gc --yes (non-TTY) exits 0" test "$_S79_YES_RC" -eq 0 check "--gc --yes reaped exactly the 5 expected dead-owner containers (4 base + 1 orphaned proxy)" \ - bash -c 'sort -u "$1" | wc -l | grep -qx 5' -- "$_S79_RM_CONTAINERS" + bash -c '[ "$(sort -u "$1" | wc -l | tr -d " ")" = 5 ]' -- "$_S79_RM_CONTAINERS" check "--gc --yes never touched the D9-alive daemon container" \ bash -c '! grep -qx "sandy-daemon-alive" "$1"' -- "$_S79_RM_CONTAINERS" check "--gc --yes never touched the live-lock foreground container" \