blob: d85f65474ac79188e93090ce89996cf2ac76cb42 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
#!/bin/bash
# A daemon killed mid-write must never leave @agent_state=done next to a
# stale @dingger_hook (a restart would trust the hook). Kills the daemon the
# instant "done" appears, N times; prints how many left them inconsistent.
# usage: kill-race.sh <dingger binary> <rounds>; counts inconsistent (@agent_state done, @dingger_hook not idle) after kill -9
BIN=$1; N=$2; D=$(mktemp -d /tmp/dingger-race.XXXXXX); R=dingger-race-$$
r() { tmux -u -L $R "$@"; }
mkdir -p $D/bin; printf '#!/bin/sh\nexec sleep 100000\n' > $D/bin/pi; chmod +x $D/bin/pi
r -f /dev/null new-session -d -s a -n w1 $D/bin/pi; r new-session -d -s b -n w2 $D/bin/pi
P=$(r display -p -t a:w1 '#{pane_id}')
start() { PI_CODING_AGENT_DIR=$D/pi-agent DINGGER_TMUX_SOCKET=$R DINGGER_AGENT_SOCKET=$D/hook.sock DINGGER_STATE_DIR=$D/state $BIN watch --interval-secs 30 --no-sounds --no-notifications >/dev/null 2>&1 & DP=$!; for _ in $(seq 50); do [ -S $D/hook.sock ] && break; sleep 0.05; done; }
hook() { python3 -c "
import json,socket; s=socket.socket(socket.AF_UNIX); s.connect('$D/hook.sock')
s.sendall((json.dumps({'method':'pane.report_agent','params':{'pane_id':'$P','agent':'pi','state':'$1'}})+'\n').encode())"; }
bad=0
for i in $(seq $N); do
start; hook working; hook idle
for _ in $(seq 400); do [ "$(r show -pv -t $P @agent_state 2>/dev/null)" = done ] && break; done
kill -9 $DP; wait $DP 2>/dev/null; rm -f $D/hook.sock
h=$(r show -pv -t $P @dingger_hook 2>/dev/null); [ "$h" != idle ] && bad=$((bad+1))
r set -p -t $P -u @dingger_hook; r set -p -t $P @agent_state idle
done
echo "$(basename $(dirname $BIN))/$(basename $BIN): $bad of $N kills left @agent_state=done with @dingger_hook not idle"
r kill-server; rm -rf $D
|