mirror of
https://github.com/forcedotcom/afv-library.git
synced 2026-08-07 08:04:28 +08:00
102 lines
4.5 KiB
Bash
Executable File
102 lines
4.5 KiB
Bash
Executable File
#!/bin/bash
|
|
# Regression test for the python3 preflight guards added to scripts/sf-context,
|
|
# scripts/sf-deploy-gate, and bin/lsp-precheck. All three shell out to python3
|
|
# for their real logic (org detection/classification, JSON parsing); without a
|
|
# guard, a missing python3 surfaces as a raw "command not found" instead of a
|
|
# diagnosable message, and (for sf-deploy-gate/lsp-precheck, which back
|
|
# PreToolUse/PostToolUse hooks) can break the hook's expected JSON-on-stdout
|
|
# contract entirely.
|
|
#
|
|
# Simulates "python3 missing" by running each script with PATH restricted to a
|
|
# stub directory containing only the couple of external commands each script
|
|
# needs BEFORE it reaches the python3 check (dirname, cat) — deliberately
|
|
# omitting python3 so `command -v python3` fails for real, not just at runtime.
|
|
#
|
|
# Run: bash plugins/builder/salesforce-development/scripts/test/python3-guard.test.sh
|
|
set -uo pipefail
|
|
|
|
PLUGIN_ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
|
|
SF_CONTEXT="$PLUGIN_ROOT/scripts/sf-context"
|
|
SF_DEPLOY_GATE="$PLUGIN_ROOT/scripts/sf-deploy-gate"
|
|
LSP_PRECHECK="$PLUGIN_ROOT/bin/lsp-precheck"
|
|
PASS=0
|
|
FAIL=0
|
|
|
|
ok() { PASS=$((PASS + 1)); printf ' ok %s\n' "$1"; }
|
|
bad() { FAIL=$((FAIL + 1)); printf ' FAIL %s\n' "$1"; }
|
|
|
|
# PATH with no python3 on it at all — only the bare commands each wrapper
|
|
# needs before its guard runs (dirname, cat). Real symlinks, not stubs, so the
|
|
# scripts behave exactly as they normally would up to the python3 check.
|
|
STUB_DIR=$(mktemp -d)
|
|
trap 'rm -rf "$STUB_DIR"' EXIT
|
|
ln -s "$(command -v dirname)" "$STUB_DIR/dirname"
|
|
ln -s "$(command -v cat)" "$STUB_DIR/cat"
|
|
|
|
echo "python3 preflight guards — sf-context, sf-deploy-gate, lsp-precheck"
|
|
|
|
# --- 1. sf-context: fails closed with a clear message ------------------------
|
|
OUT=$(PATH="$STUB_DIR" "$SF_CONTEXT" detect 2>&1)
|
|
RC=$?
|
|
if [ "$RC" -ne 0 ] && printf '%s' "$OUT" | grep -qi "python3 not found"; then
|
|
ok "sf-context: missing python3 -> non-zero exit with clear stderr message"
|
|
else
|
|
bad "sf-context: missing python3 -> expected non-zero exit + message (rc=$RC out=$OUT)"
|
|
fi
|
|
|
|
# --- 2. sf-deploy-gate classify: fails OPEN as 'unknown' ----------------------
|
|
OUT=$(printf '' | PATH="$STUB_DIR" "$SF_DEPLOY_GATE" classify 2>&1)
|
|
RC=$?
|
|
if [ "$RC" -eq 0 ] && printf '%s' "$OUT" | grep -q "unknown" && printf '%s' "$OUT" | grep -qi "python3 not found"; then
|
|
ok "sf-deploy-gate classify: missing python3 -> 'unknown', exit 0, stderr note"
|
|
else
|
|
bad "sf-deploy-gate classify: missing python3 -> expected 'unknown'/exit 0/stderr note (rc=$RC out=$OUT)"
|
|
fi
|
|
|
|
# --- 3. sf-deploy-gate prod-check: fails OPEN with a valid allow decision -----
|
|
OUT=$(PATH="$STUB_DIR" "$SF_DEPLOY_GATE" prod-check < /dev/null 2>&1)
|
|
RC=$?
|
|
if [ "$RC" -eq 0 ] && printf '%s' "$OUT" | grep -q '"continue": true'; then
|
|
ok "sf-deploy-gate prod-check: missing python3 -> allows (continue:true)"
|
|
else
|
|
bad "sf-deploy-gate prod-check: missing python3 -> expected continue:true (rc=$RC out=$OUT)"
|
|
fi
|
|
|
|
# --- 4. lsp-precheck: fails OPEN, never attempts the node cold-start ---------
|
|
OUT=$(printf '%s' '{"tool_input":{"command":"sf project deploy start"}}' | PATH="$STUB_DIR" "$LSP_PRECHECK" 2>&1)
|
|
RC=$?
|
|
if [ "$RC" -eq 0 ] && printf '%s' "$OUT" | grep -q '"continue": true'; then
|
|
ok "lsp-precheck: missing python3 -> allows (continue:true), no node cold-start"
|
|
else
|
|
bad "lsp-precheck: missing python3 -> expected continue:true (rc=$RC out=$OUT)"
|
|
fi
|
|
|
|
# --- 5. Normal behavior is unaffected when python3 IS present ----------------
|
|
OUT=$("$SF_CONTEXT" __python3_guard_test_unknown_cmd__ 2>&1)
|
|
RC=$?
|
|
if [ "$RC" -ne 0 ] && printf '%s' "$OUT" | grep -qi "Unknown command" && ! printf '%s' "$OUT" | grep -qi "python3 not found"; then
|
|
ok "sf-context: python3 present -> guard does not fire, real dispatch runs"
|
|
else
|
|
bad "sf-context: python3 present -> guard should not fire (rc=$RC out=$OUT)"
|
|
fi
|
|
|
|
OUT=$(printf '{}' | "$SF_DEPLOY_GATE" classify 2>&1)
|
|
RC=$?
|
|
if [ "$RC" -eq 0 ] && printf '%s' "$OUT" | grep -q "unknown" && ! printf '%s' "$OUT" | grep -qi "python3 not found"; then
|
|
ok "sf-deploy-gate classify: python3 present -> guard does not fire"
|
|
else
|
|
bad "sf-deploy-gate classify: python3 present -> guard should not fire (rc=$RC out=$OUT)"
|
|
fi
|
|
|
|
OUT=$(printf '%s' '{"tool_input":{"command":"ls"}}' | "$LSP_PRECHECK" 2>&1)
|
|
RC=$?
|
|
if [ "$RC" -eq 0 ] && printf '%s' "$OUT" | grep -q '"continue": true' && ! printf '%s' "$OUT" | grep -qi "python3 not found"; then
|
|
ok "lsp-precheck: python3 present -> guard does not fire"
|
|
else
|
|
bad "lsp-precheck: python3 present -> guard should not fire (rc=$RC out=$OUT)"
|
|
fi
|
|
|
|
echo ""
|
|
echo " $PASS passed, $FAIL failed"
|
|
[ "$FAIL" -eq 0 ]
|