Files
serverAppConfigs/scripts/test-changed.sh
T
Frank 05c0d3a00a frank-medium: llama.cpp layer split across both R9700s, DFlash2 drafting
The vllm-radiance replica pair could not use both cards for one model: TP=2
needs a cross-card collective and the second R9700 cannot dispatch one. The
same wall blocks vLLM's pipeline parallelism, whose stage handoff is an RCCL
send/recv of the hidden state (distributed/parallel_state.py) -- a fact worth
writing down, because the obvious reading of the ask ('use PP to dodge the
atomics problem') is exactly backwards.

llama.cpp's layer split needs no collective at all: layers are distributed and
the boundary activation is a per-backend copy, once per forward pass. One
process, both cards, one model. The runtime is mainline llama.cpp at fb27a525
(the ref is pinned by DFlash2 AND qwen35 MTP; the ROCmFPX fork this host had
before has neither), built for gfx1201 against the private ROCm 7.14 toolchain
the earlier build already used, and bundled next to the binary.

Server: ajgazin Swift-Qwen3.8-27B-Uncensored UD-Q8_K_XL with the model's MTP
head in the file, plus the z-lab DFlash2 Q8_0 block-diffusion drafter at depth
7 (its block is 8, so 7 is the ceiling llama.cpp allows). Text only: vision
stays on frank-small.

Retired into the trash rather than deleted: the three vLLM quadlets, the
radiance entrypoint/healthcheck, the routing proxy and its tests, and the two
bench scripts that drove 'vllm bench serve' inside the retired image. The
deploy handler now stops them, waits for 7770 to be released, installs the
ROOT unit and refuses to start anything when the runtime or payload is
missing. The planner maps the scripts/ trio to frank-medium only, and the
scoping seam asserts the retired service dir is gone rather than merely
unmapped.
2026-09-16 14:59:23 -07:00

296 lines
12 KiB
Bash
Executable File

#!/usr/bin/env bash
# Run only the Bats tests affected by the staged paths.
#
# Usage:
# scripts/test-changed.sh # inspect the staged commit
# scripts/test-changed.sh --list # print selected test files
# scripts/test-changed.sh --paths FILE ...
#
# --paths is intended for tests and local experimentation. The normal mode is
# deliberately staged-only so a pre-commit hook cannot accidentally validate
# an unrelated dirty working-tree file.
set -euo pipefail
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
LIST_ONLY=0
USE_PATHS=0
declare -a CHANGED=()
die() {
printf 'ERROR: %s\n' "$*" >&2
exit 2
}
while [ "$#" -gt 0 ]; do
case "$1" in
--list)
LIST_ONLY=1
shift
;;
--paths)
USE_PATHS=1
shift
while [ "$#" -gt 0 ] && [[ "$1" != --* ]]; do
CHANGED+=("$1")
shift
done
;;
--)
shift
CHANGED+=("$@")
break
;;
*)
die "unknown option '$1' (use --list or --paths FILE ...)"
;;
esac
done
cd "$REPO_ROOT"
if [ "$USE_PATHS" -eq 0 ]; then
while IFS= read -r -d '' path; do
CHANGED+=("$path")
done < <(git diff --cached --name-only -z --diff-filter=ACMRTUXB)
fi
[ "${#CHANGED[@]}" -gt 0 ] || {
printf 'No staged paths; no focused tests to run.\n'
exit 0
}
declare -a TESTS=()
add_test() {
local test="$1"
local existing
for existing in "${TESTS[@]:-}"; do
[ "$existing" != "$test" ] || return 0
done
TESTS+=("$test")
}
for path in "${CHANGED[@]}"; do
case "$path" in
tests/*.bats)
add_test "$path"
;;
tests/helpers.bash|tests/run.sh)
die "$path is shared test infrastructure; run ./tests/run.sh explicitly"
;;
.githooks/*)
add_test tests/changed_tests.bats
;;
dankserver/compose.yaml|dankclaw/compose.yaml)
add_test tests/compose_validity.bats
add_test tests/env_consistency.bats
add_test tests/deployment_scoping.bats
;;
dankserver/Caddyfile|dankclaw/Caddyfile)
add_test tests/caddyfile.bats
add_test tests/deployment_scoping.bats
;;
tests/e2e/*)
add_test tests/e2e_scaffold.bats
;;
dankserver/.env.example|dankclaw/.env.example)
add_test tests/env_consistency.bats
;;
shared/homepage/*)
add_test tests/homepage_caddy.bats
add_test tests/homepage_config.bats
add_test tests/homepage_deploy.bats
add_test tests/homepage_pages.bats
add_test tests/homepage_checker.bats
add_test tests/deployment_scoping.bats
;;
shared/searxng/*)
add_test tests/searxng_limiter.bats
add_test tests/searxng_quadlet.bats
add_test tests/deployment_scoping.bats
;;
# The five observability containers left compose for Quadlet units on
# 2026-09-11. Their seam pins boot persistence and the loopback-only
# publish posture that keeps them off every host interface. This case
# precedes the dankclaw/*/quadlet/*.container fallback below, which
# would otherwise swallow it into unrelated seams.
dankclaw/observability/*)
add_test tests/observability_quadlet.bats
add_test tests/caddyfile.bats
add_test tests/deployment_scoping.bats
add_test tests/docs_completeness.bats
;;
# Caddy left compose.yaml on 2026-08-26 for a quadlet; caddyfile.bats
# now asserts against the quadlet itself. Route every change under
# dankclaw/caddy/ to both seams (this block must precede the
# dankclaw/*.container glob, which would otherwise swallow the unit).
dankclaw/caddy/*)
add_test tests/caddy_quadlet.bats
add_test tests/caddyfile.bats
add_test tests/docs_completeness.bats
add_test tests/deployment_scoping.bats
;;
dankclaw/*.container|dankclaw/*.network)
add_test tests/open_webui_quadlet.bats
add_test tests/pihole.bats
add_test tests/searxng_quadlet.bats
add_test tests/deployment_scoping.bats
;;
# Anubis is a quadlet + Caddyfile pair: the chain (public listener ->
# anubis:8923 -> internal :8016 listener) spans both, so any change
# under the service dir must re-run the caddyfile seam too. This case
# precedes the dankclaw/*/quadlet/*.container fallback below, which
# would otherwise swallow it into unrelated seams.
dankclaw/anubis/*)
add_test tests/anubis.bats
add_test tests/caddyfile.bats
add_test tests/homepage_caddy.bats
add_test tests/deployment_scoping.bats
;;
# frank-large is a rootless quadlet again since 2026-09-16 (the
# halogen-flash-server restore). Its unit carries the fleet's GPU and
# podman posture, so it gets its own seam rather than the generic
# fallback below.
dankclaw/frank-large/*)
add_test tests/frank_large_unit.bats
add_test tests/deployment_scoping.bats
add_test tests/docs_completeness.bats
;;
# Quadlets live under dankclaw/<svc>/quadlet/ (reorganized out of the
# top-level dankclaw/*.container globs above). Map the whole subtree so
# changes to the pihole, open-webui, searxng, and gitea quadlets hit
# their seam tests. The pihole-specific block must come first: shell
# case matches the first pattern, and dankclaw/pihole/quadlet/*.container
# also satisfies the dankclaw/*/quadlet/*.container fallback.
dankclaw/pihole/*)
add_test tests/pihole.bats
add_test tests/docs_completeness.bats
add_test tests/deployment_scoping.bats
;;
dankclaw/*/quadlet/*.container|dankclaw/*/quadlet/*.network)
add_test tests/open_webui_quadlet.bats
add_test tests/pihole.bats
add_test tests/searxng_quadlet.bats
add_test tests/docs_completeness.bats
add_test tests/deployment_scoping.bats
;;
scripts/deploy.sh|scripts/deploy-remote.sh|scripts/deploy-plan.py|scripts/deploy-*-quadlet.sh)
add_test tests/deployment_flow.bats
add_test tests/deployment_scoping.bats
add_test tests/scripts_syntax.bats
;;
scripts/mount-entropy.sh)
add_test tests/mount_entropy.bats
;;
# frank-medium is llama.cpp on the two R9700s as a ROOT unit since
# 2026-09-16: a native gfx1201 HIP binary, so (like frank-small) its
# env, unit and serve script all live in scripts/, and this case has to
# precede the generic scripts/*.service fallback below. The retired
# vllm-radiance service dir is under dankserver/.AGENTTRASH/, which is
# archive material and maps to nothing.
scripts/frank-medium.*|scripts/serve-frank-medium.sh)
add_test tests/frank_medium_unit.bats
add_test tests/llm_units.bats
add_test tests/deployment_scoping.bats
add_test tests/scripts_syntax.bats
;;
# frank-small is llama.cpp on the 3090 as a ROOT unit: a native CUDA
# binary, so no generated quadlet is involved. Its env, unit and serve
# script all live in scripts/, which is why this case has to precede
# the generic scripts/*.service and scripts/* fallbacks below.
scripts/frank-small.*|scripts/serve-frank-small.sh)
add_test tests/frank_small_unit.bats
add_test tests/llm_units.bats
add_test tests/deployment_scoping.bats
add_test tests/scripts_syntax.bats
;;
scripts/*.service)
add_test tests/llm_units.bats
add_test tests/scripts_syntax.bats
add_test tests/deployment_scoping.bats
;;
scripts/*)
add_test tests/scripts_syntax.bats
;;
serverAppConfigs-docs/*)
add_test tests/docs_completeness.bats
add_test tests/deployment_scoping.bats
;;
dankclaw/hermes/*)
add_test tests/docs_completeness.bats
;;
README.md|AGENTS.md)
# Project guidance changes can affect the documented deployment
# contract; validate the docs vault and scoped deployment seams.
add_test tests/docs_completeness.bats
add_test tests/deployment_scoping.bats
;;
dankclaw/comfyui/*)
add_test tests/docs_completeness.bats
add_test tests/deployment_scoping.bats
;;
# loki and alloy images are built from this repo's Containerfiles; the
# loki one carries the healthcheck command (see its comment), so both
# seams read it.
dankclaw/loki/*|dankclaw/alloy/*)
add_test tests/observability_quadlet.bats
add_test tests/caddyfile.bats
add_test tests/deployment_scoping.bats
;;
dankclaw/udev/*)
# Host-level udev rules are applied by manual sudo install + udevadm
# trigger, not dispatched as a service; nothing here is bats-testable.
;;
.AGENTTRASH/*)
# Trash moves are not testable; skip.
;;
.gitignore|.env.example)
# Ignore/ignore-list changes change nothing at runtime; not testable.
;;
old/scripts/*|old/scripts/**)
add_test tests/scripts_syntax.bats
;;
# Cutover-era dankserver quadlet units (romm trio, jellyfin, calibre-web,
# copyparty, plex, tautulli): the seam checks boot-persistence +
# v1-generator contract; deploy-flow seams guard the deployer routing.
dankserver/romm/*|dankserver/jellyfin/*|dankserver/calibre-web/*|dankserver/copyparty/*|dankserver/plex/*|dankserver/tautulli/*)
add_test tests/dankserver_quadlet.bats
add_test tests/deployment_flow.bats
add_test tests/deployment_scoping.bats
;;
# FrankBook-Pro units live inside the podman machine VM; the seam
# pins boot persistence, the gluetun netns invariant, and the
# plan-locked volume layout. Deployer changes route here too.
frankbook-pro/*)
add_test tests/frankbook_quadlet.bats
add_test tests/deployment_flow.bats
add_test tests/deployment_scoping.bats
;;
# Seerr unit on dankclaw: boot persistence, loopback-only port
# posture, and the deployer routing that installs it.
dankclaw/seerr/*)
add_test tests/seerr_quadlet.bats
add_test tests/deployment_flow.bats
add_test tests/deployment_scoping.bats
;;
report/*)
# Frozen audit reports are point-in-time artifacts; not testable.
;;
*)
die "no focused-test mapping for '$path'; add one before committing"
;;
esac
done
# Mapped-but-untestable paths (udev rules, trash moves) legitimately produce an
# empty selection; that is a pass, not a bats usage error.
[ "${#TESTS[@]}" -gt 0 ] || exit 0
if [ "$LIST_ONLY" -eq 1 ]; then
printf '%s\n' "${TESTS[@]}"
exit 0
fi
command -v bats >/dev/null 2>&1 || die 'bats is not installed'
printf 'Running focused tests for %d changed path(s):\n' "${#CHANGED[@]}"
printf ' %s\n' "${TESTS[@]}"
bats --print-output-on-failure "${TESTS[@]}"