#!/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"