orchestrator-conservation.test.sh
1 #!/bin/sh 2 # Tests for claude-orchestrator.sh should_skip_for_conservation() function 3 # 4 # Extracts the function and tests it in isolation against CONSERVATION_MODE env var. 5 6 PASS=0 7 FAIL=0 8 SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" 9 PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" 10 ORCHESTRATOR="$PROJECT_ROOT/scripts/claude-orchestrator.sh" 11 12 TMPDIR=$(mktemp -d) 13 trap 'rm -rf "$TMPDIR"' EXIT 14 15 # ── Helpers ─────────────────────────────────────────────────────────────────── 16 17 pass() { PASS=$((PASS + 1)); echo " PASS: $1"; } 18 fail() { FAIL=$((FAIL + 1)); echo " FAIL: $1"; } 19 20 assert_returns() { 21 expected="$1"; actual="$2"; msg="$3" 22 if [ "$actual" = "$expected" ]; then pass "$msg"; else fail "$msg (expected $expected, got $actual)"; fi 23 } 24 25 # ── Extract function ────────────────────────────────────────────────────────── 26 27 cat > "$TMPDIR/func.sh" << 'FUNCEOF' 28 #!/bin/sh 29 log() { :; } 30 FUNCEOF 31 32 sed -n '/^should_skip_for_conservation()/,/^}/p' "$ORCHESTRATOR" >> "$TMPDIR/func.sh" 33 . "$TMPDIR/func.sh" 34 35 # ── Test 1: Not in conservation mode → never skips ────────────────────────── 36 37 echo "Test 1: CONSERVATION_MODE=false → returns 1 (don't skip) for all types" 38 CONSERVATION_MODE=false 39 40 for batch_type in proposals_email proposals_sms reword_email reword_sms reword_form \ 41 reword_linkedin reword_x score_semantic score_sites enrich_sites proofread \ 42 reply_responses classify_replies extract_names oversee classify_errors code_review; do 43 should_skip_for_conservation "$batch_type"; rc=$? 44 assert_returns "1" "$rc" "CONSERVATION_MODE=false: $batch_type returns 1" 45 done 46 47 # ── Test 2: Conservation mode → defers Opus-heavy pipeline batches ─────────── 48 49 echo "Test 2: CONSERVATION_MODE=true → defers Opus-heavy batches (returns 0)" 50 CONSERVATION_MODE=true 51 LIMIT_HIT_SINCE="2026-03-17T00:00:00Z" 52 53 for batch_type in proposals_email proposals_sms reword_email reword_sms reword_form \ 54 reword_linkedin reword_x score_semantic score_sites enrich_sites proofread; do 55 should_skip_for_conservation "$batch_type"; rc=$? 56 assert_returns "0" "$rc" "Conservation: $batch_type should be deferred" 57 done 58 59 # ── Test 3: Conservation mode → always runs time-critical/cheap tasks ──────── 60 61 echo "Test 3: CONSERVATION_MODE=true → time-critical tasks always run (returns 1)" 62 CONSERVATION_MODE=true 63 64 for batch_type in reply_responses classify_replies extract_names oversee classify_errors; do 65 should_skip_for_conservation "$batch_type"; rc=$? 66 assert_returns "1" "$rc" "Conservation: $batch_type must not be deferred" 67 done 68 69 # ── Test 4: code_review deferred in conservation mode ──────────────────────── 70 71 echo "Test 4: CONSERVATION_MODE=true → code_review is NOT deferred (unknown types pass through)" 72 CONSERVATION_MODE=true 73 74 # code_review is not in the conservation defer list — unknown types return 1 (don't skip) 75 should_skip_for_conservation "code_review"; rc=$? 76 assert_returns "1" "$rc" "code_review passes through conservation (not deferred)" 77 78 # ── Test 5: Unknown batch type → returns 1 (don't skip) ───────────────────── 79 80 echo "Test 5: Unknown batch type passes through conservation" 81 CONSERVATION_MODE=true 82 83 should_skip_for_conservation "some_unknown_type"; rc=$? 84 assert_returns "1" "$rc" "Unknown type returns 1 in conservation mode" 85 86 # ── Summary ─────────────────────────────────────────────────────────────────── 87 88 echo "" 89 echo "Results: $PASS passed, $FAIL failed" 90 [ "$FAIL" -eq 0 ] || exit 1