Files
serverAppConfigs/tests/frank_large_unit.bats
T
Frank f68bda56c7 frank-large: serve script feeds the launcher its runtime root from the SDK venv
The CIRU launcher gates on hip/lib/libamdhip64.so + rocr/lib/libhsa-runtime64.so
under its runtime root and exits 2 without them; the build links the private
venv through its RUNPATH, so point those entries at the venv's unversioned
devel symlinks (idempotent ln -sfn). Without this the unit crash-looped for
the full 2400s health gate on first deploy.
2026-09-19 03:49:04 -07:00

133 lines
5.9 KiB
Bash
Executable File

#!/usr/bin/env bats
# Seam: the frank-large CIRU v4.4.1 root unit on dankclaw.
#
# The 2026-09-19 cutover moved this service out of the halogen-flash-server
# quadlet and onto the CIRU v4.4.1 runtime (QSA window hotfix) serving
# jcbtc/Qwen3.8-Flash-CIRU-STRIX-Orca, as a ROOT unit on a host build -- the
# same shape as frank-small and frank-medium, because a private-SDK host
# binary has no container image to install and no generated unit to dodge.
# This seam pins what a flag list cannot show: the operator's one-stream /
# full-context shape, the payload the launcher refuses to start without, a
# deploy handler that retires the halogen quadlet without deleting it and
# gates on the port, and the fact that the sweep for a stray benchmark run
# cannot take frank-small down with it.
load helpers
ENV_FILE="$REPO_ROOT/scripts/frank-large.env"
UNIT="$REPO_ROOT/scripts/frank-large.service"
SERVE="$REPO_ROOT/scripts/serve-frank-large.sh"
FETCH="$REPO_ROOT/scripts/download-frank-large-orca.sh"
REMOTE_DEPLOY="$REPO_ROOT/scripts/deploy-remote.sh"
@test "the frank-large unit, env and serve files exist where the deployer installs them from" {
[ -f "$ENV_FILE" ]
[ -f "$UNIT" ]
[ -x "$SERVE" ]
}
@test "frank-large is boot-persistent, self-healing and unprivileged" {
grep -q '^WantedBy=multi-user.target$' "$UNIT"
grep -q '^Restart=on-failure$' "$UNIT"
grep -q '^RestartSec=' "$UNIT"
grep -q '^User=dank$' "$UNIT"
# The engine pins staging buffers and the PLE pager's hot window; the
# memlock budget must be unbounded or the load fails on the RLIMIT.
grep -q '^LimitMEMLOCK=infinity$' "$UNIT"
# The unit runs the repo's own serve script with the repo's env.
grep -q 'ExecStart=/home/dank/serverAppConfigs/scripts/serve-frank-large.sh' "$UNIT"
grep -q 'FRANK_LARGE_ENV_FILE=/home/dank/serverAppConfigs/scripts/frank-large.env' "$UNIT"
}
@test "the operator's shape is one stream of the full trained window" {
local ctx slots
ctx="$(sed -nE 's/^CONTEXT_SIZE=([0-9]+)$/\1/p' "$ENV_FILE")"
slots="$(sed -nE 's/^PARALLEL_SLOTS=([0-9]+)$/\1/p' "$ENV_FILE")"
# 262144 is the model's trained window and the GGUF carries no rope
# scaling; the operator asked for full context.
[ "$ctx" -eq 262144 ]
# One slot. This is also the drafter's constraint: the launcher refuses
# MTP with more than one slot, so the two cannot drift apart silently.
[ "$slots" -eq 1 ]
grep -q '^ENABLE_MTP=1$' "$ENV_FILE"
}
@test "frank-large stays text-only until the projector is enabled" {
grep -q '^ENABLE_VISION=0$' "$ENV_FILE"
# The fleet's image path is frank-small; the projector is on disk and is
# one env flip away, but models.yml declares frank-large text-only.
grep -q -- '--mmproj' "$REPO_ROOT/scripts/serve-frank-small.sh"
}
@test "the serve script pins the hotfix runtime and refuses a missing build" {
grep -q 'ciru-runtime-v4.4.1-qsa-hotfix' "$SERVE"
grep -q 'build-gfx1151-sdk/bin/llama-server' "$SERVE"
grep -q 'run-orca-server.sh' "$SERVE"
# A missing runtime or payload is a deploy error with a pointer, not a
# restart loop.
grep -q 'missing built runtime' "$SERVE"
grep -q 'missing target model' "$SERVE"
# The Qwen3.8 template keeps prior thinking blocks across turns only
# when the kwarg is set; the launcher passes --jinja but no kwargs.
grep -q 'preserve_thinking' "$SERVE"
}
@test "the serve script feeds the launcher its runtime root from the SDK venv" {
# The launcher exits 2 without hip/lib/libamdhip64.so +
# rocr/lib/libhsa-runtime64.so under its runtime root; the build links
# the private venv, so the serve script must point those entries there
# or the unit crash-loops on the gate (seen 2026-09-19).
grep -q '_rocm_sdk_devel/lib' "$SERVE"
grep -q 'runtime/hip/lib/libamdhip64.so' "$SERVE"
grep -q 'runtime/rocr/lib/libhsa-runtime64.so' "$SERVE"
grep -q 'missing SDK venv runtime' "$SERVE"
}
@test "the payload is fetched resumably and verified by sha256" {
grep -q 'jcbtc/Qwen3.8-Flash-CIRU-STRIX-Orca' "$FETCH"
grep -q -- '-fL -C -' "$FETCH"
grep -q 'parts.json' "$FETCH"
grep -q 'sha256sum -c SHA256SUMS' "$FETCH"
# The PLE sidecar is the largest transport part; the script must fetch
# and verify it, not just the GGUF.
grep -q 'ple.payload.bin' "$FETCH"
}
@test "the fleet endpoint and alias survive the cutover" {
grep -q '^HOST=0.0.0.0$' "$ENV_FILE"
grep -q '^PORT=7770$' "$ENV_FILE"
grep -q '^MODEL_DIR=/home/dank/models/Qwen3.8-Flash-CIRU-STRIX-Orca$' "$ENV_FILE"
}
@test "the deploy handler retires the halogen quadlet without deleting it" {
grep -q 'retire_halogen_large_quadlet' "$REMOTE_DEPLOY"
grep -q 'HOME/.AGENTTRASH' "$REMOTE_DEPLOY"
! grep -qE '(^|[^[:alnum:]_])rm (-[a-zA-Z]+ )?.*frank-large' "$REMOTE_DEPLOY"
}
@test "the deploy handler installs the root unit, gates the port and refuses a missing payload" {
grep -q 'relink_unit frank-large' "$REMOTE_DEPLOY"
grep -q 'systemctl enable frank-large.service' "$REMOTE_DEPLOY"
grep -q 'wait_port_free 7770' "$REMOTE_DEPLOY"
grep -q '127.0.0.1:7770/health' "$REMOTE_DEPLOY"
grep -q 'LLM_LARGE_MODEL' "$REMOTE_DEPLOY"
grep -q 'LLM_LARGE_PLE' "$REMOTE_DEPLOY"
}
@test "the stray-run sweep cannot take frank-small down" {
# frank-small on this host is ALSO a llama-server. The sweep must match
# the model path, not the binary name, or a frank-large deploy restarts
# the 3090 endpoint.
grep -q "pkill -f 'Qwen3.8-Flash-CIRU-STRIX-Orca'" "$REMOTE_DEPLOY"
# ...and only inside the large handler: extract it and check there is no
# bare binary-name pkill in it.
local large
large="$(sed -n '/^deploy_llm_large() {/,/^}/p' "$REMOTE_DEPLOY")"
! grep -q 'pkill -x llama-server' <<<"$large"
}
@test "the halogen quadlet is archived, not live" {
[ ! -e "$REPO_ROOT/dankclaw/frank-large/quadlet/frank-large.container" ]
[ -f "$REPO_ROOT/dankclaw/.AGENTTRASH/frank-large.container.halogen" ]
}