AtlatestRepositoryfolio

folio / tree / testtest-startup-race.sh

1#!/usr/bin/env bash
2# Concurrent startup on a fresh root.
3#
4# Every session starts its own folio process against the same root, and the
5# root's directories are created check-then-create. Processes starting
6# together on a root without archive/ collided and one exited with
7# "make-directory: File exists" before answering initialize: 20 of 480
8# starts on 0.2.11 native, 9 of 240 on the dev build.
9#
10# The race needs processes that really start at the same moment, which a
11# sigil test's sequential process-spawn cannot produce, so this is a shell
12# test. Trials and width are sized so that the unfixed build fails almost
13# surely: at 4% per start, 20 trials of 8 leave about a 0.2% chance of a
14# false pass.
16# Exit 0 on pass, 1 on any failed start, 2 if the binary could not be found.
17set -u
19FOLIO=${FOLIO:-$(dirname "$0")/../build/release/bin/folio}
20if [ ! -x "$FOLIO" ]; then
21 FOLIO=$(dirname "$0")/../build/dev/bin/folio
22fi
23if [ ! -x "$FOLIO" ]; then
24 echo "ERROR: no folio binary at build/release/bin/folio or build/dev/bin/folio" >&2
25 exit 2
26fi
28TRIALS=${TRIALS:-20}
29WIDTH=${WIDTH:-8}
30WORK=$(mktemp -d -t folio-startup.XXXXXX)
31trap 'rm -rf "$WORK"' EXIT
32INIT='{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{}}}'
34dead=0
35for trial in $(seq 1 "$TRIALS"); do
36 root="$WORK/root-$trial"
37 mkdir -p "$root/notes" "$root/projects"
38 : > "$root/inbox.md"
39 for i in $(seq 1 "$WIDTH"); do
40 (echo "$INIT" | FOLIO_ROOT="$root" "$FOLIO" serve > "$WORK/out-$trial-$i" 2>&1) &
41 done
42 wait
43 for i in $(seq 1 "$WIDTH"); do
44 if ! grep -q protocolVersion "$WORK/out-$trial-$i"; then
45 dead=$((dead + 1))
46 echo " FAIL trial $trial process $i: $(tail -c 200 "$WORK/out-$trial-$i" | tr '\n' ' ')"
47 fi
48 done
49done
51total=$((TRIALS * WIDTH))
52if [ "$dead" -eq 0 ]; then
53 echo " PASS $total concurrent starts on fresh roots, all answered initialize"
54 exit 0
55fi
56echo " FAIL $dead of $total concurrent starts died"
57exit 1