#!/usr/bin/env bash # test-link-pi-models.sh — two-sided tests for rootfs/usr/local/lib/pi-devbox/link-pi-models.sh. # # Runs the real script against a throwaway HOME / PI_CODING_AGENT_DIR, so it never # touches a live ~/.pi/agent. Every "must link" case has a "must NOT touch" twin: # the script's whole contract is that it only ever creates a link where nothing # exists, so the negative cases are the important half. # # bash scripts/test-link-pi-models.sh # CI (lint.yml) and locally # LINK_PI_MODELS=/path/to/variant.sh bash scripts/test-link-pi-models.sh set -u here="$(cd "$(dirname "$0")/.." && pwd)" SCRIPT="${LINK_PI_MODELS:-$here/rootfs/usr/local/lib/pi-devbox/link-pi-models.sh}" T="$(mktemp -d)"; trap 'rm -rf "$T"' EXIT PASS=0; FAIL=0 ok() { printf ' ✅ %s\n' "$1"; PASS=$((PASS+1)); } bad() { printf ' ❌ %s — %s\n' "$1" "$2"; FAIL=$((FAIL+1)); } # One fresh world per case: shared dir with models.json, empty HOME, agent dir unset. world() { rm -rf "$T/w"; mkdir -p "$T/w/shared" "$T/w/home" printf '{"providers":{}}\n' > "$T/w/shared/models.json" SRC="$T/w/shared/models.json"; AG="$T/w/home/.pi/agent"; DEST="$AG/models.json" } # run [env assignments...] — run the script with HOME and PI_CODING_AGENT_DIR pointed into the world. # "$@" goes FIRST so an option like `-u PI_MODELS_JSON` is still parsed as one by env. run() { OUT="$(env "$@" HOME="$T/w/home" PI_CODING_AGENT_DIR="$AG" bash "$SCRIPT" 2>&1)"; RC=$?; } echo "── link-pi-models.sh ($SCRIPT)" world; run PI_MODELS_JSON="$SRC" if [ "$RC" = 0 ] && [ -L "$DEST" ] && [ "$(readlink "$DEST")" = "$SRC" ] && [[ "$OUT" == *linked* ]]; then ok "links models.json when the shared file exists and nothing is there (creates the agent dir)" else bad "link when absent" "rc=$RC link=$(readlink "$DEST" 2>&1) out=[$OUT]"; fi run PI_MODELS_JSON="$SRC" if [ "$RC" = 0 ] && [ -z "$OUT" ] && [ "$(readlink "$DEST")" = "$SRC" ]; then ok "second run is a silent no-op (every container start runs it)" else bad "idempotent" "rc=$RC out=[$OUT]"; fi world; mkdir -p "$AG"; printf 'my own\n' > "$DEST"; before="$(sha256sum "$DEST")"; run PI_MODELS_JSON="$SRC" if [ "$RC" = 0 ] && [ ! -L "$DEST" ] && [ "$(sha256sum "$DEST")" = "$before" ] && [[ "$OUT" == NOTE*"real file"* ]]; then ok "never replaces a real models.json (content unchanged, one NOTE line)" else bad "real file kept" "rc=$RC islink=$([ -L "$DEST" ] && echo y) out=[$OUT]"; fi world; mkdir -p "$AG"; ln -s /somewhere/else.json "$DEST"; run PI_MODELS_JSON="$SRC" if [ "$RC" = 0 ] && [ "$(readlink "$DEST")" = /somewhere/else.json ] && [[ "$OUT" == NOTE*"left alone"* ]]; then ok "never re-points a link the user made to another file" else bad "foreign link kept" "rc=$RC link=$(readlink "$DEST") out=[$OUT]"; fi world; rm -f "$SRC"; run PI_MODELS_JSON="$SRC" if [ "$RC" = 0 ] && [ ! -e "$DEST" ] && [ ! -L "$DEST" ] && [ -z "$OUT" ]; then ok "no shared file → creates nothing and says nothing (the default for most users)" else bad "absent source" "rc=$RC out=[$OUT]"; fi world; rm -f "$SRC"; mkdir -p "$SRC"; run PI_MODELS_JSON="$SRC" if [ "$RC" = 0 ] && [ ! -e "$DEST" ] && [ ! -L "$DEST" ]; then ok "a directory at the path is not a models.json → nothing" else bad "directory source" "rc=$RC out=[$OUT]"; fi for v in off OFF ""; do world; run PI_MODELS_JSON="$v" if [ "$RC" = 0 ] && [ ! -e "$DEST" ] && [ ! -L "$DEST" ] && [ -z "$OUT" ]; then ok "PI_MODELS_JSON='$v' disables it" else bad "disable '$v'" "rc=$RC out=[$OUT]"; fi done world; run PI_MODELS_JSON="$SRC"; rm -f "$SRC"; run PI_MODELS_JSON="$SRC" if [ "$RC" = 0 ] && [ -L "$DEST" ] && [ "$(readlink "$DEST")" = "$SRC" ] && [ -z "$OUT" ]; then ok "our link whose target vanished (mount removed) is left as is, silently (pi treats it as no file)" else bad "dangling own link" "rc=$RC out=[$OUT]"; fi # pi honours PI_CODING_AGENT_DIR, so the link must land THERE, not in $HOME/.pi/agent. world; AG="$T/w/elsewhere/agent"; DEST="$AG/models.json"; run PI_MODELS_JSON="$SRC" if [ "$RC" = 0 ] && [ "$(readlink "$DEST" 2>/dev/null)" = "$SRC" ] && [ ! -e "$T/w/home/.pi/agent/models.json" ]; then ok "links into PI_CODING_AGENT_DIR when set (and leaves \$HOME/.pi/agent alone)" else bad "PI_CODING_AGENT_DIR" "rc=$RC link=$(readlink "$DEST" 2>&1) out=[$OUT]"; fi # 'off' must be a switch, not merely a path that happens not to exist: with a file # literally named "off" in the working directory it must still disable. world; printf '{}\n' > "$T/w/off"; OUT="$(cd "$T/w" && env PI_MODELS_JSON=off HOME="$T/w/home" PI_CODING_AGENT_DIR="$AG" bash "$SCRIPT" 2>&1)"; RC=$? if [ "$RC" = 0 ] && [ ! -e "$DEST" ] && [ ! -L "$DEST" ]; then ok "PI_MODELS_JSON=off disables it even when a file named 'off' exists in the cwd" else bad "off is a switch" "rc=$RC link=$(readlink "$DEST" 2>&1) out=[$OUT]"; fi # The default path is /opt/fleet-pi/models.json. Whether it exists depends on where # this runs (a fleet devbox: yes; CI: no), so derive the expectation, don't assume it. world; run -u PI_MODELS_JSON if [ -f /opt/fleet-pi/models.json ]; then if [ "$RC" = 0 ] && [ "$(readlink "$DEST" 2>/dev/null)" = /opt/fleet-pi/models.json ]; then ok "PI_MODELS_JSON unset → default /opt/fleet-pi/models.json (present here) is linked" else bad "default path (present)" "rc=$RC link=$(readlink "$DEST" 2>&1) out=[$OUT]"; fi else if [ "$RC" = 0 ] && [ ! -e "$DEST" ] && [ ! -L "$DEST" ] && [ -z "$OUT" ]; then ok "PI_MODELS_JSON unset → default /opt/fleet-pi/models.json (absent here) → nothing" else bad "default path (absent)" "rc=$RC out=[$OUT]"; fi fi echo "── $PASS passed, $FAIL failed" [ "$FAIL" = 0 ]