Files

108 lines
5.7 KiB
Bash
Executable File

#!/usr/bin/env bash
set -eu
HERE=$(cd "$(dirname "$0")" && pwd)
RUN=$HERE/../scripts/codex-run.sh
TMP=$(mktemp -d)
trap 'rm -rf "$TMP"' EXIT
# 1. happy path -> status ok, thread_id captured, exit 0
mkdir -p "$TMP/ok"; echo "hello" > "$TMP/ok/prompt.md"
CODEX_BIN=$HERE/stub-ok/codex "$RUN" "$TMP/ok" exec
[[ $(cat "$TMP/ok/status") == ok ]]
[[ $(cat "$TMP/ok/thread_id") == test-thread-123 ]]
[[ $(cat "$TMP/ok/last.md") == "stub answer|args="*" -|hello" ]]
# 2. stall -> watchdog kills, status stalled, exit nonzero
mkdir -p "$TMP/hang"; echo "hello" > "$TMP/hang/prompt.md"
if CODEX_BIN=$HERE/stub-hang/codex CODEX_STALL_TIMEOUT=4 CODEX_WATCH_INTERVAL=2 \
"$RUN" "$TMP/hang" exec; then
echo "FAIL: stall run must exit nonzero"; exit 1
fi
[[ $(cat "$TMP/hang/status") == stalled ]]
[[ $(cat "$TMP/hang/thread_id") == hang-thread-456 ]]
# 3. prompt.md via stdin path
mkdir -p "$TMP/stdin"; echo "prompt from file" > "$TMP/stdin/prompt.md"
CODEX_BIN=$HERE/stub-ok/codex "$RUN" "$TMP/stdin" exec
[[ $(cat "$TMP/stdin/status") == ok ]]
[[ $(cat "$TMP/stdin/last.md") == "stub answer|args="*" -|prompt from file" ]]
# 4. prompt.md + codex flags -> stdin still delivered (regression: options ate the prompt)
mkdir -p "$TMP/flags"; echo "prompt with flags" > "$TMP/flags/prompt.md"
CODEX_BIN=$HERE/stub-ok/codex "$RUN" "$TMP/flags" exec -s read-only
[[ $(cat "$TMP/flags/status") == ok ]]
[[ $(cat "$TMP/flags/last.md") == *"-s read-only exec"* ]]
[[ $(cat "$TMP/flags/last.md") == *" -|prompt with flags" ]]
# 5. review + scope + prompt.md -> scope translated into prompt text, no scope flag in args
mkdir -p "$TMP/rev"; echo "focus: correctness" > "$TMP/rev/prompt.md"
CODEX_BIN=$HERE/stub-ok/codex "$RUN" "$TMP/rev" review --base main
[[ $(cat "$TMP/rev/status") == ok ]]
LAST5=$(cat "$TMP/rev/last.md")
[[ $LAST5 == "stub answer|args=exec review"* ]]
[[ $LAST5 != *"--base"* ]]
[[ $LAST5 == *"against base ref 'main'"* ]]
[[ $LAST5 == *"git diff main...HEAD"* ]]
[[ $LAST5 == *"focus: correctness" ]]
# 6. review + scope, no prompt.md -> native path keeps the scope flag
mkdir -p "$TMP/rev-native"
CODEX_BIN=$HERE/stub-ok/codex "$RUN" "$TMP/rev-native" review --uncommitted
[[ $(cat "$TMP/rev-native/status") == ok ]]
[[ $(cat "$TMP/rev-native/last.md") == "stub answer|args=exec review"* ]]
[[ $(cat "$TMP/rev-native/last.md") == *"--uncommitted"* ]]
# 7. review + prompt.md, no scope -> custom instructions pass through untouched
mkdir -p "$TMP/rev-custom"; echo "review whatever you find" > "$TMP/rev-custom/prompt.md"
CODEX_BIN=$HERE/stub-ok/codex "$RUN" "$TMP/rev-custom" review
[[ $(cat "$TMP/rev-custom/status") == ok ]]
[[ $(cat "$TMP/rev-custom/last.md") == "stub answer|args=exec review"*"-|review whatever you find" ]]
# 8. exec -s read-only then resume reuses -s read-only before exec (hoisted)
mkdir -p "$TMP/persist"; echo "task persist" > "$TMP/persist/prompt.md"
CODEX_BIN=$HERE/stub-ok/codex "$RUN" "$TMP/persist" exec -s read-only
[[ $(cat "$TMP/persist/status") == ok ]]
[[ $(cat "$TMP/persist/last.md") == *"-s read-only exec"* ]]
# resume should hoist saved flags before exec
CODEX_BIN=$HERE/stub-ok/codex "$RUN" "$TMP/persist" resume "$(cat "$TMP/persist/thread_id")"
[[ $(cat "$TMP/persist/status") == ok ]]
RESUME8=$(cat "$TMP/persist/last.md")
[[ $RESUME8 == *"-s read-only exec resume"* ]] || { echo "FAIL case 8 hoist: $RESUME8"; exit 1; }
[[ $RESUME8 == *" -|task persist"* ]] || { echo "FAIL case 8 prompt: $RESUME8"; exit 1; }
# 9. exec -m gpt-5.5 --add-dir "/tmp/with spaces" NUL preserves space; resume proves persistence
mkdir -p "$TMP/spaces"; echo "task spaces" > "$TMP/spaces/prompt.md"
CODEX_BIN=$HERE/stub-ok/codex "$RUN" "$TMP/spaces" exec -m gpt-5.5 --add-dir "/tmp/with spaces"
[[ $(cat "$TMP/spaces/status") == ok ]]
[[ $(cat "$TMP/spaces/last.md") == *"-m gpt-5.5 --add-dir /tmp/with spaces"* ]]
# verify NUL storage preserves space as single entry
mapfile -d '' -t CHK < "$TMP/spaces/codex-flags"
[[ ${#CHK[@]} -eq 4 ]] || { echo "FAIL case 9 NUL count ${#CHK[@]}: ${CHK[*]}"; exit 1; }
[[ ${CHK[0]} == "-m" ]] || { echo "FAIL case 9 flag0 ${CHK[0]}"; exit 1; }
[[ ${CHK[2]} == "--add-dir" ]] || { echo "FAIL case 9 flag2 ${CHK[2]}"; exit 1; }
[[ ${CHK[3]} == "/tmp/with spaces" ]] || { echo "FAIL case 9 space preserved got '${CHK[3]}'"; exit 1; }
# resume should contain same spaced arg as single entry
CODEX_BIN=$HERE/stub-ok/codex "$RUN" "$TMP/spaces" resume "$(cat "$TMP/spaces/thread_id")"
[[ $(cat "$TMP/spaces/status") == ok ]]
RESUME9=$(cat "$TMP/spaces/last.md")
[[ $RESUME9 == *"-m gpt-5.5 --add-dir /tmp/with spaces exec resume"* ]] || { echo "FAIL case 9 resume hoist: $RESUME9"; exit 1; }
# 10. review --base main -s read-only then resume keeps -s read-only before exec
mkdir -p "$TMP/rev-persist"; echo "review persist" > "$TMP/rev-persist/prompt.md"
CODEX_BIN=$HERE/stub-ok/codex "$RUN" "$TMP/rev-persist" review --base main -s read-only
[[ $(cat "$TMP/rev-persist/status") == ok ]]
LAST10=$(cat "$TMP/rev-persist/last.md")
[[ $LAST10 == *"-s read-only exec review"* ]] || { echo "FAIL case 10 exec hoist: $LAST10"; exit 1; }
[[ $LAST10 == *"against base ref 'main'"* ]] || { echo "FAIL case 10 scope text: $LAST10"; exit 1; }
# flags file should contain only -s read-only, scope translated to prompt
mapfile -d '' -t CHK10 < "$TMP/rev-persist/codex-flags"
[[ ${#CHK10[@]} -eq 2 ]] || { echo "FAIL case 10 flags count ${#CHK10[@]}: ${CHK10[*]}"; exit 1; }
[[ ${CHK10[0]} == "-s" && ${CHK10[1]} == "read-only" ]] || { echo "FAIL case 10 flags ${CHK10[*]}"; exit 1; }
# resume keeps flag
CODEX_BIN=$HERE/stub-ok/codex "$RUN" "$TMP/rev-persist" resume "$(cat "$TMP/rev-persist/thread_id")"
[[ $(cat "$TMP/rev-persist/status") == ok ]]
RESUME10=$(cat "$TMP/rev-persist/last.md")
[[ $RESUME10 == *"-s read-only exec resume"* ]] || { echo "FAIL case 10 resume: $RESUME10"; exit 1; }
echo "ALL PASS"