Files
agent-orchestrator/tests/run.sh
autonomic-bot cdcece9a9a test: add tests/ — unit suite + isolated live claude/opencode smokes + runner
Unit tests (no agents/tmux): config load + defaults merge, kickoff-template
assembly, phase machine (advance/idempotent-complete/append-resumes), limit
reset-banner parsing, WAITING-UNTIL/stall parsing, claude+opencode activity
detectors. Live smokes bring a throwaway project up THROUGH agents.py on each
real backend in an isolated sandbox (unique prefix, opencode on a non-4096
port), verify attach + status + down, and clean up. tests/run.sh runs unit
always + smokes when backends present; README documents it.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 18:55:34 +00:00

76 lines
4.1 KiB
Bash
Executable File

#!/usr/bin/env bash
# ─────────────────────────────────────────────────────────────────────────────
# agent-orchestrator test runner.
#
# • UNIT tests — always run (pure logic, no agents spawned). A failure fails the suite.
# • CLAUDE smoke — live, run when the `claude` CLI is available; SKIPs otherwise.
# • OPENCODE smoke — live, run when `opencode` + creds are available; SKIPs otherwise.
# • ISOLATION sanity — after the live runs: assert no leftover aotest-* tmux sessions, and that
# the live cc-ci-* sessions are untouched.
#
# Run inside the devShell: nix develop -c ./tests/run.sh
# or simply: ./tests/run.sh (python3 + tmux must be on PATH)
#
# Exit: 0 = all run tests passed (skips are OK); 1 = a unit test or a live smoke FAILED, or a
# leftover aotest-* session was found.
# ─────────────────────────────────────────────────────────────────────────────
set -uo pipefail
HERE="$(cd "$(dirname "$0")" && pwd)"
REPO="$(cd "$HERE/.." && pwd)"
RC=0
UNIT=FAIL CLAUDE=SKIP OPENCODE=SKIP ISO=PASS
echo "######################################################################"
echo "# agent-orchestrator test suite"
echo "######################################################################"
# ── unit tests (always) ───────────────────────────────────────────────────────────
echo; echo ">>> UNIT TESTS"
if python3 -m unittest discover -s "$HERE" -p 'test_*.py' -v; then
UNIT=PASS
else
UNIT=FAIL; RC=1
fi
# helper: run a smoke script, classify its result from its output
run_smoke() {
local label="$1" script="$2"; shift 2
echo; echo ">>> ${label} SMOKE"
local out
out="$(bash "$script" 2>&1)"; local rc=$?
echo "$out"
if echo "$out" | grep -q "BACKEND SMOKE: PASS"; then echo "PASS"; return 0; fi
if [ "$rc" -eq 0 ] && echo "$out" | grep -qE "^SKIP:"; then echo "SKIP"; return 2; fi
echo "FAIL"; return 1
}
# ── live smoke tests (when backends available) ──────────────────────────────────────
run_smoke "CLAUDE" "$HERE/smoke_claude.sh"; case $? in 0) CLAUDE=PASS;; 2) CLAUDE=SKIP;; *) CLAUDE=FAIL; RC=1;; esac
run_smoke "OPENCODE" "$HERE/smoke_opencode.sh"; case $? in 0) OPENCODE=PASS;; 2) OPENCODE=SKIP;; *) OPENCODE=FAIL; RC=1;; esac
# ── isolation sanity ────────────────────────────────────────────────────────────────
echo; echo ">>> ISOLATION SANITY"
if command -v tmux >/dev/null 2>&1; then
leftover="$(tmux ls 2>/dev/null | sed 's/:.*//' | grep '^aotest-' || true)"
if [ -n "$leftover" ]; then
echo " FAIL: leftover aotest-* sessions: $leftover"; ISO=FAIL; RC=1
else
echo " PASS: no leftover aotest-* tmux sessions"
fi
intact=""
for s in cc-ci-orchestrator cc-ci-watchdog cc-ci-assistant3; do
tmux has-session -t "=$s" 2>/dev/null && intact="$intact $s"
done
echo " info: live cc-ci sessions present:${intact:- (none — not a cc-ci host)}"
else
echo " (tmux not on PATH — isolation sanity skipped)"
fi
# ── summary ─────────────────────────────────────────────────────────────────────────
echo; echo "######################################################################"
echo "# SUMMARY: unit=$UNIT claude=$CLAUDE opencode=$OPENCODE isolation=$ISO"
echo "######################################################################"
[ "$RC" -eq 0 ] && echo "ALL RUN TESTS PASSED (skips are OK)" || echo "SUITE FAILED"
exit "$RC"