[grade=A urn:ump:seyasvbntxsjibq5jiaqmfowc6xgchwe4jvcc54jd6355ujgm75q] DC-122: self-updater hardening + auto-update on + docker disk discipline (v1.16.0)
- _isNewer: same-version releases are never 'newer' (commit labels are opaque stamps) — kills the same-version auto-apply regression loop - _autoCheckAndApply: identical version@sha256 never re-applied - dashcaddy-update.sh: truthful rollback verdicts (failed rebuild/health = exit 1 + failure result), exact frontend snapshot/restore (incl. update-introduced owned subtrees), contents-copy cp fallbacks with manifest reconciliation, JSON-encoded results/meta/stamp, prune on every exit path - self-updater: frontend-only Linux releases fail loudly (no more silent no-op success stuck in 'applying') - start.sh: DASHCADDY_UPDATE_ENABLED=true (Sami 2026-09-13), json-file log caps 10M x3, source->webroot sync via update-stamp contract - tests: _isNewer regression suite, functional cycle + json/escape suites (scripts/test-frontend-cycle.sh, scripts/test-json-escape.sh) 15 judge rounds: C,C,D,D,C,C,D,C,C,C,D,C,A
This commit is contained in:
Executable
+67
@@ -0,0 +1,67 @@
|
||||
#!/usr/bin/env bash
|
||||
# Functional test of json_escape + restore guard (DC-122 verification)
|
||||
set -euo pipefail
|
||||
# Updater script path: $1 overrides; default = adjacent to this test file
|
||||
# (numbered worktree prefixes included), falling back to installed location.
|
||||
SCRIPT="${1:-}"
|
||||
if [[ -z "$SCRIPT" ]]; then
|
||||
local_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
for cand in "$local_dir/dashcaddy-update.sh" \
|
||||
"$local_dir"/*dashcaddy-update.sh \
|
||||
/opt/dashcaddy/scripts/dashcaddy-update.sh; do
|
||||
[[ -f "$cand" ]] && SCRIPT="$cand" && break
|
||||
done
|
||||
fi
|
||||
[[ -f "$SCRIPT" ]] || { echo "updater script not found"; exit 1; }
|
||||
# Exactly ONE validated, trap-covered workspace for ALL temp artifacts.
|
||||
WORK=$(mktemp -d) || { echo "mktemp failed"; exit 1; }
|
||||
trap 'rm -rf "$WORK"' EXIT
|
||||
source <(sed -n '/^json_escape()/,/^}/p' "$SCRIPT")
|
||||
|
||||
# Test 1: quotes + backslash + newline + tab round-trip through python json
|
||||
r=$(json_escape 'a"b\c
|
||||
d e')
|
||||
python3 - "$r" <<'PY'
|
||||
import json, sys
|
||||
v = json.loads('"' + sys.argv[1] + '"')
|
||||
assert v == 'a"b\\c\nd\te', f"round-trip mismatch: {v!r}"
|
||||
print("TEST1 OK: quotes/backslash/newline/tab round-trip valid JSON")
|
||||
PY
|
||||
|
||||
# Test 2: control chars (backspace, form feed, x01) become \uXXXX short forms
|
||||
r2=$(json_escape "$(printf 'x\by\fz\001w')")
|
||||
python3 - "$r2" <<'PY'
|
||||
import json, sys
|
||||
v = json.loads('"' + sys.argv[1] + '"')
|
||||
assert v == "x\by\fz\x01w", f"control round-trip mismatch: {v!r}"
|
||||
print("TEST2 OK: control bytes escaped and parse back")
|
||||
PY
|
||||
|
||||
# Test 3: restore_frontend_dir must REFUSE an invalid recorded target —
|
||||
# invoke it for real and assert (a) nonzero return, (b) zero mutations.
|
||||
sed -n '/^validate_frontend_target()/,/^}/p' "$SCRIPT" > "$WORK/rfd-parts.sh"
|
||||
sed -n '/^restore_frontend_dir()/,/^}/p' "$SCRIPT" >> "$WORK/rfd-parts.sh"
|
||||
log() { echo "[t] $*"; }
|
||||
source "$WORK/rfd-parts.sh"
|
||||
|
||||
WORK2="$WORK/fixtures"
|
||||
mkdir -p "$WORK2/victim/dist" "$WORK2/backup/frontend"
|
||||
echo keep > "$WORK2/victim/dist/keep.js"
|
||||
cat > "$WORK2/backup/frontend.meta" <<EOF
|
||||
{"target":"relative/not-absolute","indexExisted":true,"swExisted":true}
|
||||
EOF
|
||||
( cd "$WORK2/backup/frontend" && find . -type f -printf '%P\n' | sort ) > "$WORK2/backup/frontend.manifest"
|
||||
|
||||
# Full-tree fingerprint BEFORE any restore attempt: prove ZERO mutations
|
||||
# anywhere in the victim tree across the refused restore.
|
||||
fp_before=$(find "$WORK2/victim" -type f -exec sha256sum {} + | sort)
|
||||
rc=0
|
||||
restore_frontend_dir "$WORK2/backup" 2>/dev/null || rc=$?
|
||||
fp_after=$(find "$WORK2/victim" -type f -exec sha256sum {} + | sort)
|
||||
if [[ $rc -ne 0 ]]; then echo "TEST3a OK: restore returned nonzero ($rc) for invalid target"; else echo "TEST3 FAIL: restore returned 0"; exit 1; fi
|
||||
if [[ "$fp_before" == "$fp_after" ]]; then
|
||||
echo "TEST3b OK: victim untouched (fingerprint identical across refused restore)"
|
||||
else
|
||||
echo "TEST3 FAIL: victim modified"; exit 1
|
||||
fi
|
||||
echo "ALL JSON/GUARD TESTS DONE"
|
||||
Reference in New Issue
Block a user