gem/tests/long_context_server_gate_resume.sh
2026-08-30 18:24:55 -06:00

169 lines
5.7 KiB
Bash
Executable file

#!/bin/sh
set -eu
if [ "$#" -ne 1 ]; then
echo "usage: $0 LONG_CONTEXT_SERVER_GATE" >&2
exit 2
fi
runner=$1
fixture=$(mktemp -d /private/tmp/gem-server-gate-resume.XXXXXX)
listener_pid=
cleanup()
{
if [ -n "$listener_pid" ] && kill -0 "$listener_pid" 2>/dev/null; then
kill "$listener_pid"
wait "$listener_pid" 2>/dev/null || true
fi
rm -rf "$fixture"
}
trap cleanup EXIT INT TERM HUP
mkdir -p "$fixture/build" "$fixture/scripts"
printf 'fixture model\n' > "$fixture/model.gguf"
printf 'fixture prompt\n' > "$fixture/prompt.txt"
# The single-quoted fragments below are the literal body of a generated fixture.
# shellcheck disable=SC2016
printf '%s\n' '#!/bin/sh' \
'set -eu' \
'if [ "$1" = print-config ]; then' \
' if [ -e .changed-config ]; then' \
' printf '\''{"engine":"gem-native-c-metal","context":4098,"kv_type":"f32","route":"changed"}\n'\''' \
' else' \
' printf '\''{"engine":"gem-native-c-metal","context":4098,"kv_type":"f32","route":"fixture"}\n'\''' \
' fi' \
' exit 0' \
'fi' \
': > .serve-attempted' \
'printf '\''serve must not run during a completed-sample resume\n'\'' >&2' \
'exit 99' > "$fixture/build/gem"
printf '%s\n' '#!/bin/sh' 'printf '\''{"token_count":4096}\n'\''' \
> "$fixture/build/gem-tokenize"
printf '%s\n' '#!/bin/sh' 'exit 99' > "$fixture/scripts/server-stream-probe.sh"
chmod +x "$fixture/build/gem" "$fixture/build/gem-tokenize" \
"$fixture/scripts/server-stream-probe.sh"
port=$((20000 + ($$ % 20000)))
nc -l 127.0.0.1 "$port" >/dev/null 2>&1 &
listener_pid=$!
attempt=0
while ! lsof -nP -iTCP:"$port" -sTCP:LISTEN >/dev/null 2>&1; do
attempt=$((attempt + 1))
if [ "$attempt" -ge 50 ]; then
echo "fixture listener did not become ready" >&2
exit 1
fi
sleep 0.02
done
set +e
(
cd "$fixture"
GEM_MODEL_SHA256=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef \
GEM_STREAM_MAX_TOKENS=2 \
"$runner" model.gguf 4098 prompt.txt results "$port"
)
initial_status=$?
set -e
if [ "$initial_status" -ne 1 ]; then
echo "initial occupied-port run returned $initial_status, expected 1" >&2
exit 1
fi
kill "$listener_pid"
wait "$listener_pid" 2>/dev/null || true
listener_pid=
set +e
(
cd "$fixture"
GEM_MODEL_SHA256=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef \
GEM_STREAM_MAX_TOKENS=2 GEM_GATE_PREFLIGHT_MIN_TOKENS=0 \
GEM_GATE_MAX_LOAD_PER_CPU=0.000001 \
"$runner" model.gguf 4098 prompt.txt results-busy "$port" >/dev/null 2>&1
)
preflight_status=$?
set -e
if [ "$preflight_status" -ne 1 ] ||
! jq -e '.status == "fail"' "$fixture/results-busy/host-preflight-1.json" >/dev/null ||
[ -e "$fixture/.serve-attempted" ]; then
echo "busy-host preflight did not fail before server launch" >&2
exit 1
fi
sample=1
while [ "$sample" -le 3 ]; do
printf 'gem: prompt prefill 4096/4096 tokens (100.00%%), fixture sample %s\n' \
"$sample" > "$fixture/results/server-$sample.log"
printf 'data: {"choices":[{"delta":{"content":"x"}}]}\n\ndata: [DONE]\n\n' \
> "$fixture/results/stream-$sample.sse"
jq -n --argjson sample "$sample" \
'{schema_version: 1, engine: "gem-native-c-metal", model: "gemma4",
requested_max_tokens: 2, http_code: 200,
header_ttfb_seconds: 0.01,
first_visible_event_seconds: (0.02 + ($sample / 1000)),
completion_seconds: 0.04, visible_event_count: 1,
finish_reason: "stop",
usage: {prompt_tokens: 4096, completion_tokens: 2, total_tokens: 4098}}' \
> "$fixture/results/measurement-$sample.json"
sample=$((sample + 1))
done
(
cd "$fixture"
GEM_MODEL_SHA256=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef \
GEM_STREAM_MAX_TOKENS=2 GEM_GATE_RESUME=1 \
"$runner" model.gguf 4098 prompt.txt results "$port" >/dev/null
)
jq -e '.repetitions == 3 and .resumed_samples == 3 and (.samples | length) == 3' \
"$fixture/results/summary.json" >/dev/null
printf 'nonempty but missing final prefill record\n' > "$fixture/results/server-2.log"
set +e
(
cd "$fixture"
GEM_MODEL_SHA256=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef \
GEM_STREAM_MAX_TOKENS=2 GEM_GATE_RESUME=1 \
"$runner" model.gguf 4098 prompt.txt results "$port" >/dev/null 2>&1
)
log_status=$?
set -e
if [ "$log_status" -ne 1 ] || [ ! -e "$fixture/.serve-attempted" ]; then
echo "missing final prefill record was silently resumed" >&2
exit 1
fi
rm "$fixture/.serve-attempted"
printf 'gem: prompt prefill 4096/4096 tokens (100.00%%), fixture sample 2\n' \
> "$fixture/results/server-2.log"
touch "$fixture/.changed-config"
set +e
(
cd "$fixture"
GEM_MODEL_SHA256=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef \
GEM_STREAM_MAX_TOKENS=2 GEM_GATE_RESUME=1 \
"$runner" model.gguf 4098 prompt.txt results "$port" >/dev/null 2>&1
)
config_status=$?
set -e
if [ "$config_status" -ne 2 ]; then
echo "changed native configuration returned $config_status, expected 2" >&2
exit 1
fi
rm "$fixture/.changed-config"
jq '.prompt_sha256 = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"' \
"$fixture/results/gate-config.json" > "$fixture/results/gate-config.tmp"
mv "$fixture/results/gate-config.tmp" "$fixture/results/gate-config.json"
set +e
(
cd "$fixture"
GEM_MODEL_SHA256=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef \
GEM_STREAM_MAX_TOKENS=2 GEM_GATE_RESUME=1 \
"$runner" model.gguf 4098 prompt.txt results "$port" >/dev/null 2>&1
)
provenance_status=$?
set -e
if [ "$provenance_status" -ne 2 ]; then
echo "changed gate provenance returned $provenance_status, expected 2" >&2
exit 1
fi