suites/robustness/repro/switch-kill.sh 29 lines · 2.1 KB · bash
1
#!/bin/bash
2
# P4 finding: `oak switch B` SIGKILLed mid-materialization leaves a half-switched
3
# worktree. The store still says branch A (sqlite3 metadata), status reports the
4
# other branch's files as the user's uncommitted changes, and re-running
5
# `oak switch B` refuses ("Working directory has uncommitted changes", exit 4)
6
# with no recovery guidance. Committing now would record B's partial tree on A.
7
# Usage: switch-kill.sh <oak> <outdir> [kill_after_seconds]
8
set -u
9
OAK=$1; OUT=$2; DELAY=${3:-0.4}
10
rm -rf "$OUT"; mkdir -p "$OUT/home" "$OUT/a"
11
export HOME=$OUT/home OAK_NO_UPDATE_CHECK=1 OAK_API_KEY=p4tok OAK_AUTHOR=p4
12
unset OAK_REMOTE OAK_REPO OAK_TOKEN
13
PORT=$(python3 -c 'import socket;s=socket.socket();s.bind(("127.0.0.1",0));print(s.getsockname()[1])')
14
"$OAK" serve --dir "$OUT/srv" --port $PORT --token p4tok >"$OUT/serve.log" 2>&1 & SP=$!
15
trap 'kill $SP 2>/dev/null' EXIT
16
for i in $(seq 1 100); do curl -s -o /dev/null http://127.0.0.1:$PORT/api/capabilities && break; sleep 0.05; done
17
cd "$OUT/a"; "$OAK" init . >/dev/null 2>&1
18
for i in $(seq 0 199); do mkdir -p d$((i%10)); printf 'base %s\n%.0s' $i $(seq 1 40) > d$((i%10))/f$i.txt; done
19
"$OAK" commit >/dev/null 2>&1; "$OAK" push --repo p4/r -r http://127.0.0.1:$PORT >/dev/null 2>&1 || { echo push failed; exit 2; }
20
A=$(sqlite3 .oak/oak.db "select value from metadata where key='current_branch'")
21
"$OAK" switch -c side >/dev/null 2>&1
22
for i in $(seq 0 199); do printf 'side %s\n%.0s' $i $(seq 1 40) > d$((i%10))/f$i.txt; done
23
"$OAK" commit >/dev/null 2>&1; "$OAK" switch "$A" >/dev/null 2>&1
24
"$OAK" switch side >/dev/null 2>&1 & P=$!
25
python3 -c "import time;time.sleep($DELAY)"; kill -9 $P 2>/dev/null && echo "killed switch after ${DELAY}s"; wait $P 2>/dev/null
26
echo "store current_branch: $(sqlite3 .oak/oak.db "select value from metadata where key='current_branch'")"
27
echo "files with side content: $(grep -l '^side' d*/f*.txt | wc -l | tr -d ' ') / 200"
28
"$OAK" status --json | python3 -c 'import sys,json;d=json.load(sys.stdin);print("status branch:",d["branch"],"changes:",len(d["working_changes"]["changes"]))'
29
"$OAK" switch side; echo "re-run switch exit=$?"