98 lines
4 KiB
Bash
98 lines
4 KiB
Bash
|
|
#!/usr/bin/env bash
|
||
|
|
#
|
||
|
|
# Opt-in Integrations-Rauchtest gegen einen ECHTEN Docker + llama.cpp-Server.
|
||
|
|
# Läuft NICHT in der normalen pytest-Suite (braucht Docker, GPU-Speicher und ein
|
||
|
|
# echtes GGUF-Modell). Startet einen separaten Container (eigener Name/Port), um
|
||
|
|
# eine ggf. laufende Produktion nicht anzufassen — räumt am Ende auf.
|
||
|
|
#
|
||
|
|
# Voraussetzungen:
|
||
|
|
# - Docker-Daemon erreichbar
|
||
|
|
# - freier GPU-Speicher für das in der Config referenzierte Modell
|
||
|
|
# (ein 21-GB-Modell passt NICHT neben einen bereits laufenden 256k-Server;
|
||
|
|
# ggf. SMOKE_GPU auf eine freie Karte setzen oder Produktion vorher stoppen)
|
||
|
|
#
|
||
|
|
# Konfiguration über Environment-Variablen (alle optional):
|
||
|
|
# CLI Pfad zum CLI (Default: ./.venv/bin/llamacppctl)
|
||
|
|
# SMOKE_CONFIG Config-Datei (Default: llama.cpp.config)
|
||
|
|
# SMOKE_PROFILE --profile <name> (Default: keins)
|
||
|
|
# SMOKE_CONTAINER Container-Name (Default: llamacppctl_smoke)
|
||
|
|
# SMOKE_PORT Host-Port (Default: 8099)
|
||
|
|
# SMOKE_GPU GPU-Device (Default: aus Config)
|
||
|
|
# SMOKE_CTX ctx_size für den Test (Default: 8192, klein = schnell/wenig VRAM)
|
||
|
|
# SMOKE_MAX_TOKENS Chat-Budget (Default: 4000; Reasoning-Modelle brauchen viel)
|
||
|
|
# SMOKE_API_KEY API-Key (Default: zufällig)
|
||
|
|
#
|
||
|
|
# Beispiel:
|
||
|
|
# SMOKE_GPU=1 SMOKE_CTX=8192 scripts/smoke.sh
|
||
|
|
#
|
||
|
|
set -uo pipefail
|
||
|
|
|
||
|
|
CLI=${CLI:-./.venv/bin/llamacppctl}
|
||
|
|
CONFIG=${SMOKE_CONFIG:-llama.cpp.config}
|
||
|
|
CONTAINER=${SMOKE_CONTAINER:-llamacppctl_smoke}
|
||
|
|
PORT=${SMOKE_PORT:-8099}
|
||
|
|
CTX=${SMOKE_CTX:-8192}
|
||
|
|
MAX_TOKENS=${SMOKE_MAX_TOKENS:-4000}
|
||
|
|
API_KEY=${SMOKE_API_KEY:-smoke-$$-$RANDOM}
|
||
|
|
|
||
|
|
base=(--config "$CONFIG" --container-name "$CONTAINER" --host-port "$PORT")
|
||
|
|
[ -n "${SMOKE_PROFILE:-}" ] && base+=(--profile "$SMOKE_PROFILE")
|
||
|
|
[ -n "${SMOKE_GPU:-}" ] && base+=(--gpu "$SMOKE_GPU")
|
||
|
|
|
||
|
|
pass=0
|
||
|
|
fail=0
|
||
|
|
ok() { echo " PASS: $1"; pass=$((pass + 1)); }
|
||
|
|
bad() { echo " FAIL: $1"; fail=$((fail + 1)); }
|
||
|
|
|
||
|
|
cleanup() {
|
||
|
|
echo "== cleanup =="
|
||
|
|
"$CLI" --stop "${base[@]}" >/dev/null 2>&1 || docker rm -f "$CONTAINER" >/dev/null 2>&1 || true
|
||
|
|
}
|
||
|
|
trap cleanup EXIT
|
||
|
|
|
||
|
|
command -v docker >/dev/null 2>&1 || { echo "docker fehlt auf PATH"; exit 2; }
|
||
|
|
docker version >/dev/null 2>&1 || { echo "docker-Daemon nicht erreichbar"; exit 2; }
|
||
|
|
|
||
|
|
echo "== dry-run =="
|
||
|
|
if "$CLI" --start "${base[@]}" --api-key "$API_KEY" --ctx-size "$CTX" --dry-run | grep -q "docker run"; then
|
||
|
|
ok "dry-run zeigt docker-run-Kommando (kein Start)"
|
||
|
|
else
|
||
|
|
bad "dry-run"
|
||
|
|
fi
|
||
|
|
|
||
|
|
echo "== start (api-key gesetzt, ctx=$CTX) =="
|
||
|
|
if "$CLI" --start "${base[@]}" --api-key "$API_KEY" --ctx-size "$CTX"; then
|
||
|
|
ok "start + readiness"
|
||
|
|
else
|
||
|
|
bad "start (Modell/GPU prüfen)"; exit 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
echo "== --check Exit-Code (läuft -> 0) =="
|
||
|
|
rc=0; "$CLI" --check "${base[@]}" >/dev/null 2>&1 || rc=$?
|
||
|
|
[ "$rc" -eq 0 ] && ok "--check == 0" || bad "--check == $rc (erwartet 0)"
|
||
|
|
|
||
|
|
echo "== API-Key erzwungen: ohne Key -> 401 =="
|
||
|
|
code=$(curl -s -o /dev/null -w '%{http_code}' "http://127.0.0.1:$PORT/v1/models")
|
||
|
|
[ "$code" = "401" ] && ok "unauth -> 401" || bad "unauth -> $code (erwartet 401)"
|
||
|
|
|
||
|
|
echo "== API-Key: mit Key -> 200 =="
|
||
|
|
code=$(curl -s -o /dev/null -w '%{http_code}' -H "Authorization: Bearer $API_KEY" "http://127.0.0.1:$PORT/v1/models")
|
||
|
|
[ "$code" = "200" ] && ok "auth -> 200" || bad "auth -> $code (erwartet 200)"
|
||
|
|
|
||
|
|
echo "== chat (Tool sendet Bearer-Key) =="
|
||
|
|
out=$("$CLI" --chat "${base[@]}" --api-key "$API_KEY" --max-tokens "$MAX_TOKENS" -p "Sag in genau einem Satz Hallo." 2>/dev/null)
|
||
|
|
[ -n "$out" ] && ok "chat liefert Text: ${out:0:60}..." || bad "chat leer"
|
||
|
|
|
||
|
|
echo "== stream =="
|
||
|
|
sout=$("$CLI" --chat "${base[@]}" --api-key "$API_KEY" --stream --max-tokens "$MAX_TOKENS" -p "Zähle bis drei." 2>/dev/null)
|
||
|
|
[ -n "$sout" ] && ok "stream liefert Text" || bad "stream leer"
|
||
|
|
|
||
|
|
echo "== stop -> --check == 5 =="
|
||
|
|
rc=0; "$CLI" --stop "${base[@]}" >/dev/null 2>&1 || rc=$?
|
||
|
|
[ "$rc" -eq 0 ] && ok "stop" || bad "stop == $rc"
|
||
|
|
rc=0; "$CLI" --check "${base[@]}" >/dev/null 2>&1 || rc=$?
|
||
|
|
[ "$rc" -eq 5 ] && ok "--check nach stop == 5" || bad "--check nach stop == $rc (erwartet 5)"
|
||
|
|
|
||
|
|
echo
|
||
|
|
echo "== Ergebnis: $pass PASS, $fail FAIL =="
|
||
|
|
[ "$fail" -eq 0 ]
|