PR Pipeline — Authorize → Validate → Review → Merge / auth (pull_request) Successful in 3s
PR Pipeline — Authorize → Validate → Review → Merge / validate (pull_request) Successful in 5s
PR Pipeline — Authorize → Validate → Review → Merge / lint (pull_request) Successful in 4s
PR Pipeline — Authorize → Validate → Review → Merge / ai-review (pull_request) Successful in 3s
PR Pipeline — Authorize → Validate → Review → Merge / gate (pull_request) Successful in 2s
- Implement four-state PBS GC logic in proxmox-monitor.sh: - probe-failed: unparseable JSON, store not found, or empty body → FAIL - running: collection in progress (last-run-endtime absent, upid present) → DO NOT FAIL - stale: no completed run within 48h → FAIL, naming last completed run age - healthy: completed within 48h → PASS, naming endtime and pending bytes - Add tests/test_pbs_gc_states.sh covering all four states - Proves the test bites on the pre-fix version (5/6 tests fail) - All 6 tests pass against the fixed version - Update contract-run.sh to map disk-gc-threat-response -> scripts/disk-gc-scan.py - Update Execution sections of host-scheduled contracts: infrastructure-monitoring, zulip-health, litellm-health, agent-health-check, disk-gc-threat-response, pm2-self-heal Adding note that execution is host-scheduled via cron, not agent session ack.
82 lines
2.5 KiB
Bash
Executable File
82 lines
2.5 KiB
Bash
Executable File
#!/bin/bash
|
|
# test_pbs_gc_states.sh — Tests for PBS GC four-state logic
|
|
|
|
set -uo pipefail
|
|
|
|
TEST_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
SCRIPTS_DIR="$(dirname "$TEST_DIR")/scripts"
|
|
PROXMOX_MONITOR="${1:-${SCRIPTS_DIR}/proxmox-monitor.sh}"
|
|
|
|
PASS=0
|
|
FAIL=0
|
|
|
|
run_test() {
|
|
local name="$1"
|
|
local json="$2"
|
|
local pattern="$3"
|
|
local behavior="$4"
|
|
|
|
local wrapper monitor
|
|
wrapper=$(mktemp /tmp/pbs-test-wrapper.XXXXXX)
|
|
monitor=$(mktemp /tmp/pbs-test-monitor.XXXXXX)
|
|
|
|
printf '%s\n' "$json" > "$wrapper"
|
|
cp "$PROXMOX_MONITOR" "$monitor"
|
|
|
|
# Replace the SSH call with cat "$wrapper"
|
|
python3 /tmp/replace_ssh.py "$wrapper" "$monitor"
|
|
|
|
local output exit_code
|
|
output=$(bash "$monitor" 2>&1)
|
|
exit_code=$?
|
|
|
|
local ok=true
|
|
if [ "$behavior" = "fail" ]; then
|
|
if ! echo "$output" | grep -q "🔴 PBS GC"; then ok=false; fi
|
|
if [ $exit_code -eq 0 ]; then ok=false; fi
|
|
else
|
|
if ! echo "$output" | grep -q "$pattern"; then ok=false; fi
|
|
if echo "$output" | grep -q "🔴 PBS GC"; then ok=false; fi
|
|
fi
|
|
|
|
if $ok; then
|
|
echo " ✅ $name"
|
|
PASS=$((PASS + 1))
|
|
else
|
|
echo " 🔴 $name FAILED (exit=$exit_code)"
|
|
echo "$output" | grep "PBS GC" | sed 's/^/ /'
|
|
FAIL=$((FAIL + 1))
|
|
fi
|
|
|
|
rm -f "$wrapper" "$monitor"
|
|
}
|
|
|
|
echo "=== PBS GC Four-State Tests ==="
|
|
echo "Script: $PROXMOX_MONITOR"
|
|
echo ""
|
|
|
|
echo "1. probe-failed (unparseable JSON)"
|
|
run_test "unparseable-json" "NOT JSON {{{" "probe-failed" "fail"
|
|
|
|
echo "2. probe-failed (store not found)"
|
|
run_test "store-missing" '[{"store": "other", "last-run-endtime": 1000}]' "probe-failed" "fail"
|
|
|
|
echo "3. probe-failed (empty body)"
|
|
run_test "empty-body" "" "probe-failed" "fail"
|
|
|
|
echo "4. running (in progress - upid set, no last-run-endtime)"
|
|
run_test "running" '[{"store": "storepve-datastore", "upid": "UPID:123:1:456:gc:root@pam", "pending-bytes": 100}]' "⏳ PBS GC: running" "pass"
|
|
|
|
echo "5. stale (last run >48h)"
|
|
STALE=$(date -u -d "50 hours ago" +%s)
|
|
run_test "stale" "[{\"store\": \"storepve-datastore\", \"last-run-endtime\": $STALE, \"pending-bytes\": 200}]" "stale" "fail"
|
|
|
|
echo "6. healthy (completed <48h)"
|
|
HEALTHY=$(date -u -d "1 hour ago" +%s)
|
|
run_test "healthy" "[{\"store\": \"storepve-datastore\", \"last-run-endtime\": $HEALTHY, \"pending-bytes\": 0}]" "✅ PBS GC: healthy" "pass"
|
|
|
|
echo ""
|
|
echo "=== Results: $PASS passed, $FAIL failed ==="
|
|
[ $FAIL -eq 0 ] && echo "✅ All passed" || echo "🔴 Some failed"
|
|
[ $FAIL -eq 0 ] && exit 0 || exit 1
|