Files
nexarch/scripts/preflight_test.sh
2026-09-18 22:03:31 +02:00

76 lines
4.0 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
here="$(cd "$(dirname "$0")" && pwd)"
pre="$here/preflight.sh"
tmp="$(mktemp -d)"
listener=""
trap '[ -n "$listener" ] && kill "$listener" 2>/dev/null; rm -rf "$tmp"' EXIT
free_port() { python3 -c 'import socket; s=socket.socket(); s.bind(("127.0.0.1",0)); print(s.getsockname()[1])'; }
port="$(free_port)"
root="$tmp/root"
mkdir -p "$root/deploy" "$root/dms/cmd/app" "$root/dms/migrations/tenant" "$tmp/units"
printf 'dms\t%s\t%s\n' "$port" "$port" > "$root/deploy/ports.tsv"
printf 'package main\nvar addr = ":%s"\n' "$port" > "$root/dms/cmd/app/main.go"
touch "$root/dms/migrations/tenant/0001_documents.up.sql"
export NEXARCH_PREFLIGHT_UNIT_DIR="$tmp/units"
expect_fail() {
if "$pre" "$@" >/dev/null 2>"$tmp/err"; then echo "FAIL: $1 nicht erkannt" >&2; exit 1; fi
local want="${*: -1}"
grep -q "$want" "$tmp/err" || { echo "FAIL: meldung fehlt ($want)" >&2; cat "$tmp/err" >&2; exit 1; }
}
run() { "$pre" "$@" >/dev/null 2>"$tmp/err" || { echo "FAIL: freies system abgelehnt" >&2; cat "$tmp/err" >&2; exit 1; }; }
# Freies System besteht.
run --skip-db --modules dms "$root"
# Belegter Port: Meldung nennt Port und Modul.
python3 -c "import socket,time; s=socket.socket(); s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1); s.bind(('127.0.0.1',$port)); s.listen(1); time.sleep(60)" &
listener=$!
for _ in $(seq 20); do (exec 3<>"/dev/tcp/127.0.0.1/$port") 2>/dev/null && break; sleep 0.1; done
if "$pre" --skip-db --modules dms "$root" >/dev/null 2>"$tmp/err"; then echo "FAIL: belegter port nicht erkannt" >&2; exit 1; fi
grep -q "port $port (dms" "$tmp/err" || { echo "FAIL: meldung ohne port/modul" >&2; cat "$tmp/err" >&2; exit 1; }
# Bei --upgrade darf der eigene Dienst den Port halten.
run --upgrade --skip-db --modules dms "$root"
kill "$listener"; wait "$listener" 2>/dev/null || true; listener=""
# Vorhandene Unit.
touch "$tmp/units/nexarch-dms-worker.service"
expect_fail --skip-db --modules dms "$root" "nexarch-dms-worker.service existiert bereits"
run --upgrade --skip-db --modules dms "$root"
rm "$tmp/units/nexarch-dms-worker.service"
# Fehlende DB-Konfiguration ist ein Fehler, kein stilles Ueberspringen.
env -u NEXARCH_DMS_APP_TENANT_DSN "$pre" --modules dms "$root" >/dev/null 2>"$tmp/err" && { echo "FAIL: fehlende DSN nicht erkannt" >&2; exit 1; }
grep -q "DSN nicht gesetzt" "$tmp/err" || { echo "FAIL: DSN-meldung fehlt" >&2; exit 1; }
# Datenbank-Pruefungen gegen echte PostgreSQL (nur mit TEST_TENANT_DSN).
if [ -n "${TEST_TENANT_DSN:-}" ] && command -v psql >/dev/null 2>&1; then
schema="preflight_$$_$RANDOM"
psql "$TEST_TENANT_DSN" -qc "CREATE SCHEMA $schema" >/dev/null
trap 'psql "$TEST_TENANT_DSN" -qc "DROP SCHEMA IF EXISTS $schema CASCADE" >/dev/null 2>&1; [ -n "$listener" ] && kill "$listener" 2>/dev/null; rm -rf "$tmp"' EXIT
export PGOPTIONS="-c search_path=$schema"
export NEXARCH_DMS_APP_TENANT_DSN="$TEST_TENANT_DSN"
sql() { psql "$TEST_TENANT_DSN" -qc "$1" >/dev/null; }
run --modules dms "$root" # leeres Schema
sql "CREATE TABLE dms_schema_migrations (version TEXT PRIMARY KEY, applied_at TIMESTAMPTZ DEFAULT now())"
run --modules dms "$root" # Tabelle leer
sql "INSERT INTO dms_schema_migrations (version) VALUES ('0001_documents')"
expect_fail --modules dms "$root" "bestehende Installation"
run --upgrade --modules dms "$root"
sql "INSERT INTO dms_schema_migrations (version) VALUES ('9999_fremd')"
expect_fail --upgrade --modules dms "$root" "9999_fremd ist diesem Stand unbekannt"
# Fremde generische schema_migrations stoert nicht (FDN-13).
sql "DELETE FROM dms_schema_migrations WHERE version = '9999_fremd'; CREATE TABLE schema_migrations (version TEXT); INSERT INTO schema_migrations VALUES ('0001_core')"
run --upgrade --modules dms "$root"
NEXARCH_DMS_APP_TENANT_DSN="postgres://nobody@127.0.0.1:1/none?connect_timeout=2" expect_fail --modules dms "$root" "nicht erreichbar"
else
echo "hinweis: DB-pruefungen uebersprungen (TEST_TENANT_DSN/psql fehlt)"
fi
echo "preflight_test ok"