Durchtest auf 204 und 131: npm-install-links-Fix, Skript-Optionen, Protokoll-Nachtrag #102

Closed
patrick wants to merge 7 commits from fix/testrun-2026-09-21-dms into integration/dms-gesamtstand
pull from: fix/testrun-2026-09-21-dms
5 changed files with 121 additions and 8 deletions

No files matched your search

+92
View File
@@ -254,3 +254,95 @@ Pruefungen auf 204 (Head nach Merge `6141fc9`, frischer Klon, seriell ueber die
Skips (unveraendert gegenueber dem Lauf zu PR #97): `TestAppendOnly_AppRoleHasNoUpdateOrDeletePrivilege` (`dms_dev` ohne `CREATEROLE`), `TestKoSIT_LiveOutcomeMatchesExpectation` (`TEST_KOSIT_EXPECT` fehlt), 2x clamd, 2x soffice, `TestSign_UsesConfiguredTSA` (keine TSA-Env), 3x S3 (`TEST_S3_*` fehlt), die zwei Latenztests ohne `TEST_PERF=1` im Paketlauf (separat bestanden).
Hinweis zum Wrapper: `RUNHOST_*`-Argumente mit `|` im `-run`-Regex werden von `runhost.sh` durch die Shell zerlegt; Tests einzeln starten.
## Nachtrag: Durchtest auf 204 und 131 (Stand `0d01dfa`, 2026-09-21)
Auftrag: den Integrationsstand `integration/dms-gesamtstand` (`0d01dfa`) auf dem Entwicklungshost 204 und auf der Vorstufe 131 durchtesten. Alle Laeufe seriell ueber die Sperre in `runhost.sh` bzw. `rungate.sh`, jeweils frischer Klon.
### Ergebnis je Host
| Pruefung | 204 (Entwicklung) | 131 (Vorstufe) |
|---|---|---|
| `go vet`, `gofmt -l` | sauber | sauber |
| `go test -count=1 -v ./...` | 74 Pakete `ok`, 0 FAIL, 12 SKIP (3:58 min) | 74 Pakete `ok`, 0 FAIL, 10 SKIP (3:42 min) |
| Latenz `TestSearch_ConcurrentRequestsStayUnderResponseTimeLimit` (`TEST_PERF=1 -p 1`) | PASS, p95 42,2 ms | PASS, p95 65,7 ms |
| Latenz `TestFilters_ResponseTimeWithFiveFilters` (`TEST_PERF=1 -p 1`) | PASS, p95 2,8 ms | PASS, p95 7,8 ms |
| `qa02-foundation-gate.sh` | Exit 0, `govulncheck` ausdruecklich uebersprungen (Werkzeug fehlt auf 204) | Exit 0, alle Stufen PASS, `govulncheck -mode=binary` PASS |
| `check-port-defaults.sh`, `check-route-prefixes.sh` (im Gate) | PASS | PASS |
| Frontend `tsc` und `vitest` | `dms-browser` 143/143, `dms-upload` 17/17, `pdf-viewer` 31/31, `tsc` sauber (nach Fix, siehe unten) | nicht ausgefuehrt (Auftrag: nur 204); Diagnoselauf `pdf-viewer` 31/31, `tsc` sauber |
| Gesamtsystem-Smoke (FDN-19) | Uebergangsmodus 41/41, Token-Modus 46/46, Wiederanlauf 3/3 | **nicht ausgefuehrt** (siehe unten) |
| Rueckbau | Vorher-/Nachher-Snapshot (Dienste, Ports, Datenbanken, Rollen, Manticore-Tabellen, Benutzer, `/opt`) identisch | entfaellt |
Skips: gemeinsam auf beiden Hosts `TestAppendOnly_AppRoleHasNoUpdateOrDeletePrivilege` (kein `CREATEROLE`), `TestKoSIT_LiveOutcomeMatchesExpectation` (`TEST_KOSIT_EXPECT`), `TestHandler_ConvertsDocxToPDF` und `TestHandler_CrashingConverterDoesNotAffectOtherJobs` (`soffice` fehlt), `TestSign_UsesConfiguredTSA` (keine TSA-Umgebung), die zwei Latenztests (nur mit `TEST_PERF=1`, separat bestanden), drei S3-Tests (`TEST_S3_*`). Nur auf 204 zusaetzlich: die zwei `clamd`-Tests (`clamd` fehlt auf 204). Auf 131 laufen sie und bestehen, dort ist `clamav-daemon` installiert.
### Ressourcen im Gesamtbetrieb (204, 4 Kerne, 4 GB RAM)
| Messung | Wert (Ziel) |
|---|---|
| RSS Ruhebetrieb App, Worker, Stellvertreter, KoSIT | 10 + 11 + 7 + 548 = 576 MB (Ziel <= 1,5 GB) |
| nach Smoke-Test | 625 MB, Worker-Spitze 99 MB (cgroup) |
| Host-Speicher belegt, Spitze ueber alle Stichproben | 918 von 4096 MB |
| OOM-Ereignisse | 0 (App, Worker, Stellvertreter, `dmesg`) |
| Load 1 min, Spitze | 4,19 (Ausgangswert 4,19, danach 2,11) |
| Wiederanlauf nach hartem Abbruch, Standardfrist 300 s | 299 s, keine Dubletten, keine offenen Jobs |
| Wiederanlauf mit `NEXARCH_DMS_WORKER_JOB_LEASE_SECONDS=10` (FDN-20) | 30 s, keine Dubletten, keine offenen Jobs |
### Befunde
1. **Frontend unter npm >= 10 (Fix)**: `web/dms-browser`, `web/dms-upload` und `web/pdf-viewer` haengen von `"@nexarch/shl": "file:../shl"` ab. npm 9 (Node 20, 131) kopiert das Verzeichnis, npm 11 (Node 24, 204) legt einen Symlink an. Dann liegt `web/shl` ohne eigenes `react`, `tsc` meldet `Cannot find module 'react'` und 48 (`dms-browser`) bzw. 4 (`pdf-viewer`) Tests scheitern. Ein zusaetzliches `npm install` in `web/shl` liefert ein zweites `react` (Hook-Fehler). Behoben mit `.npmrc` (`install-links=true`) je App, danach auf 204 alle drei Apps gruen. Der CI-Job `web` (`ci.yml`) nutzt dieselbe Installation und ist damit von der npm-Version des Laeufers unabhaengig.
2. **Skript `fdn19-gesamtstart.sh`**: Der Suchindex-Name war nicht einstellbar, der Test haette auf 204 die Tabelle `dms_documents` des Entwicklungsbetriebs benutzt. Neu: `FDN19_INDEX_NAME` (Standard unveraendert) und `FDN19_LEASE_SECONDS`. Beim Rueckbau wird nur die eigene Tabelle entfernt.
3. **Last auf 131 in Containern**: `loadavg` zeigt dort den Wert des Proxmox-Hosts (konstant ca. 11,8) bei ca. 81 % freier CPU und CPU-Druck (PSI `avg10`) 0,01. Als Kriterium "Last niedrig" taugt der Druckwert, nicht `loadavg`.
4. **Reste auf 131**: In der Test-Datenbank stehen vier Schemas `dmstest_*` (angelegt 2026-09-20 zwischen 23:02 und 23:19, Reste abgebrochener Laeufe, nicht von diesem Durchlauf). Nicht entfernt. Auf 204 keine Reste.
5. **`govulncheck` fehlt auf 204**: Das Gate laeuft dort nur mit `QA02_SKIP_VULN=1`. Der Scan ist auf 131 vorhanden und dort PASS.
### Nicht ausgefuehrt: Gesamtsystem-Smoke auf 131
Der Smoke braucht auf 131 eine eigene Wegwerf-Datenbank. Die Rolle in `/etc/nexarch/dms-app.env` darf Datenbanken anlegen (`CREATEDB`, kein Superuser, kein `CREATEROLE`), `nexarch_app` existiert, die Ports 8600 bis 8699 sind bis auf 8610 (KoSIT) frei. Das vorhandene Skript legt dagegen eine eigene Rolle ueber den Postgres-Superuser an. Ein Modus, der die Datenbank ueber die vorhandene Rolle anlegt, wurde vom Sicherheitsfilter blockiert. Es fehlt daher die ausdrueckliche Freigabe, auf 131 (a) eine Datenbank `dms_fdn19` ueber die vorhandene Test-Rolle anzulegen, (b) einen unprivilegierten Systembenutzer und transiente `nexarch-dms-*`-Units zu erzeugen. Bis dahin ist die Vorstufe 131 nur mit Volltest, Gate und Latenz belegt.
## Nachtrag: Gesamtsystem-Smoke auf 131 (2026-09-21)
Ausdrueckliche Freigabe des Users fuer diesen Lauf: eigene Datenbank ueber die vorhandene Test-Rolle, unprivilegierter Systembenutzer mit transienten `nexarch-dms-*`-Units, Entfernen der verwaisten `dmstest_*`-Schemas. Basis: Branch `fix/testrun-2026-09-21-dms` (Skript-Optionen aus `7fb3105`).
### Durchfuehrung
- Nur die Test-Rolle aus `/etc/nexarch/dms-app.env` (`CREATEDB`, weder Superuser noch `CREATEROLE`) wurde benutzt. Neu im Skript: `FDN19_PG_ROLE_DSN` (Rollen-Modus: Datenbank anlegen und loeschen, kein `CREATE ROLE`, kein `su - postgres`) und `FDN19_GO` (auf 131 liegt Go 1.24.4 unter `/usr/bin/go`, die Toolchain 1.25.x laedt sich nach).
- Datenbank `dms_fdn19` (Eigentuemer: Test-Rolle), Systembenutzer `nexarch-fdn19`, transiente Units `nexarch-dms-fdn19-{stub,worker,app}` auf 127.0.0.1:8600/8601/8611, Suchindex `fdn19_smoke131`. KoSIT (127.0.0.1:8610, MET-07) lief bereits und wurde weder gestartet noch veraendert. Build mit `-p 2`, CPU-Druck vor dem Start (PSI `avg10`) 0,03 bis 0,07.
- `dmstest_*`: Die vier Schemas (aus dem Namen abgeleitet 2026-09-20, 14 Stunden alt, keine aktive Sitzung, kein Testlauf) wurden entfernt, vorher wurden Praefix und Alter geprueft. Danach 0 Schemas.
### Ergebnisse
| Pruefung | Ergebnis |
|---|---|
| Smoke Uebergangsmodus (`caller`) | 41 von 41 bestanden |
| Smoke Token-Modus (lokales Test-JWKS) | 46 von 46 bestanden |
| Wiederanlauf nach hartem Abbruch (App und Worker, 1 Job in Bearbeitung, Frist 10 s) | 3 von 3 bestanden, 30 s, 10 Dokumente ohne Dubletten, kein Dead-Letter |
| Ruhebetrieb RSS App, Worker, Stellvertreter, KoSIT | 11 + 13 + 8 + 537 = 569 MB (Ziel <= 1,5 GB) |
| nach Smoke und Neustart | 569 MB, Worker-Spitze 14 MB (cgroup) |
| Host-Speicher belegt, Spitze ueber alle Stichproben | 2382 von 6124 MB (Ausgangswert 2292 bis 2310 MB) |
| OOM-Ereignisse | 0 (App, Worker, Stellvertreter) |
| CPU-Druck (PSI `avg10`), Spitze waehrend des Laufs | 1,40 |
| `loadavg` (zeigt in Containern den Proxmox-Host) | 9,4 vorher, Spitze 11,2, 11,2 nachher; kein Kriterium |
| Postgres RSS gesamt | 418 MB im Ruhebetrieb, 453 MB nach dem Lauf |
### Vergleich 204 und 131
| | 204 | 131 |
|---|---|---|
| Smoke `caller` / Token / Wiederanlauf | 41/41, 46/46, 3/3 | 41/41, 46/46, 3/3 |
| Wiederanlauf mit Frist 10 s | 30 s | 30 s |
| Ruhebetrieb RSS gesamt | 576 MB | 569 MB |
| Host-Speicher belegt, Spitze | 918 von 4096 MB | 2382 von 6124 MB (davon rund 2300 MB Ausgangslast der produktiven Dienste) |
| Zusatzlast des Smoke auf dem Host | nicht separat gemessen (nur Spitze) | rund 90 MB (Spitze 2382 gegen Ausgangswert 2292 bis 2310 MB) |
| Datenbank | `dms_fdn19` ueber `su - postgres` | `dms_fdn19` ueber die Test-Rolle (`CREATEDB`) |
| Go | 1.26.5 | 1.24.4 (Toolchain-Nachladen) |
Die beiden Hosts verhalten sich gleich. Die Produktivdienste von 131 (19 `nexarch-*` laufend) blieben unberuehrt.
### Rueckbau (131)
Vorher-/Nachher-Snapshot (Dienste, Ports, Datenbanken, Rollen, Suchtabellen, Systembenutzer): identisch bis auf das Arbeitsverzeichnis `/opt/nexarch-dms-fdn19`, das beim Vorher-Snapshot bereits angelegt war und nun entfernt ist. Datenbank `dms_fdn19`, Benutzer `nexarch-fdn19`, die drei Units, Port 8600/8601/8611, Suchtabelle `fdn19_smoke131` und `/opt/nexarch-dms-fdn19` sind weg, KoSIT blieb (`keep-kosit`). Suchtabellen `dms_documents` und `mail_documents` unveraendert.
### Hinweise
- Auf 131 stehen sechs Archive-Oneshot-Dienste im Zustand `failed` (`backup-full`, `backup-incremental`, `objectbackup-rotate`, `reconcile`, `restoretest`, `scrub`). Sie standen im Vorher-Snapshot schon so und gehoeren nicht zu diesem Lauf; Klaerung im Archive-Board.
- Der Rollen-Modus legt kein `nexarch_app` an. Fuer ein echtes Deployment bleibt B4 (Rolle vorab durch den Betrieb) bestehen; auf 131 existiert sie bereits.
+26 -8
View File
@@ -28,12 +28,18 @@ KOSIT_PORT=8610
STUB_PORT=8611
PFX=nexarch-dms-fdn19
KOSIT_DIR=/opt/nexarch-kosit
GO=/usr/local/bin/go
GO="${FDN19_GO:-/usr/local/bin/go}"
TERM_WORD=Zinnoberrot
INDEX_NAME="${FDN19_INDEX_NAME:-dms_documents}"
LEASE_SECONDS="${FDN19_LEASE_SECONDS:-300}"
die() { echo "FEHLER: $*" >&2; exit 1; }
rand() { head -c 24 /dev/urandom | od -An -tx1 | tr -d ' \n'; }
pg() { su - postgres -c "psql -qAtX -v ON_ERROR_STOP=1 $*"; }
ROLE_DSN="${FDN19_PG_ROLE_DSN:-}"
# FDN19_PG_ROLE_DSN gesetzt: nur mit dieser (nicht privilegierten) Rolle arbeiten (Datenbank anlegen/loeschen, kein CREATE ROLE, kein Superuser)
pg() {
if [ -n "$ROLE_DSN" ]; then eval "psql -qAtX -v ON_ERROR_STOP=1 \"\$ROLE_DSN\" $*"; else su - postgres -c "psql -qAtX -v ON_ERROR_STOP=1 $*"; fi
}
cmd_snapshot() {
local out="${1:?datei}"
@@ -101,6 +107,7 @@ NEXARCH_DMS_APP_KEK_ENDPOINT_URL=http://127.0.0.1:$STUB_PORT/kek
NEXARCH_DMS_APP_KEK_CLIENT_ID=fdn19
NEXARCH_DMS_APP_KEK_CLIENT_SECRET=stub
NEXARCH_DMS_APP_MANTICORE_ADDR=127.0.0.1:9306
NEXARCH_DMS_APP_SEARCH_INDEX_NAME=$INDEX_NAME
NEXARCH_DMS_APP_CMIS_ENABLED=true
E
if [ "$mode" = token ]; then
@@ -122,6 +129,8 @@ NEXARCH_DMS_WORKER_KEK_ENDPOINT_URL=http://127.0.0.1:$STUB_PORT/kek
NEXARCH_DMS_WORKER_KEK_CLIENT_ID=fdn19
NEXARCH_DMS_WORKER_KEK_CLIENT_SECRET=stub
NEXARCH_DMS_WORKER_MANTICORE_ADDR=127.0.0.1:9306
NEXARCH_DMS_WORKER_SEARCH_INDEX_NAME=$INDEX_NAME
NEXARCH_DMS_WORKER_JOB_LEASE_SECONDS=$LEASE_SECONDS
NEXARCH_DMS_WORKER_KOSIT_ADDR=http://127.0.0.1:$KOSIT_PORT
NEXARCH_DMS_WORKER_KOSIT_RULESET=xrechnung-3.0.2-2026-08-31
NEXARCH_DMS_WORKER_CONCURRENCY=2
@@ -145,9 +154,17 @@ cmd_setup() {
. "$BASE/env/secrets"
[ "$(pg -c "\"select count(*) from pg_roles where rolname='nexarch_app'\"")" = 1 ] || die "Rolle nexarch_app fehlt: Migration 0013 legt sie clusterweit an und braucht dafuer CREATEROLE; vom Betrieb vorab anlegen (CREATE ROLE nexarch_app NOLOGIN)"
if [ "$(pg -c "\"select count(*) from pg_database where datname='$DB'\"")" = 0 ]; then
pg -c "\"CREATE ROLE $DB LOGIN PASSWORD '$DB_PASSWORD'\"" -c "\"CREATE DATABASE $DB OWNER $DB\"" || die "datenbank anlegen"
if [ -n "$ROLE_DSN" ]; then
pg -c "\"CREATE DATABASE $DB\"" || die "datenbank anlegen"
else
pg -c "\"CREATE ROLE $DB LOGIN PASSWORD '$DB_PASSWORD'\"" -c "\"CREATE DATABASE $DB OWNER $DB\"" || die "datenbank anlegen"
fi
fi
if [ -n "$ROLE_DSN" ]; then
echo "$ROLE_DSN" | sed -E "s#/[^/?]*\?#/$DB?#" >"$BASE/env/dsn"
else
echo "postgres://$DB:$DB_PASSWORD@127.0.0.1:5432/$DB?sslmode=disable" >"$BASE/env/dsn"
fi
echo "postgres://$DB:$DB_PASSWORD@127.0.0.1:5432/$DB?sslmode=disable" >"$BASE/env/dsn"
chmod 600 "$BASE/env/dsn"
local dsn; dsn="$(cat "$BASE/env/dsn")"
psql "$dsn" -qAtX -c "CREATE TABLE IF NOT EXISTS users (id UUID PRIMARY KEY DEFAULT gen_random_uuid(), email TEXT NOT NULL UNIQUE, name TEXT NOT NULL, status TEXT NOT NULL DEFAULT 'active', created_at TIMESTAMPTZ NOT NULL DEFAULT now(), updated_at TIMESTAMPTZ NOT NULL DEFAULT now())" || die "users-stand-in"
@@ -239,10 +256,10 @@ cmd_reset() {
cmd_down
if [ -f "$BASE/env/dsn" ]; then
psql "$(cat "$BASE/env/dsn")" -qAtX -c "select id from documents" 2>/dev/null | while read -r id; do
[ -n "$id" ] && curl -s -X POST "http://127.0.0.1:9308/sql?mode=raw" --data-urlencode "query=DELETE FROM dms_documents WHERE document_id = '$id'" >/dev/null
[ -n "$id" ] && curl -s -X POST "http://127.0.0.1:9308/sql?mode=raw" --data-urlencode "query=DELETE FROM $INDEX_NAME WHERE document_id = '$id'" >/dev/null
done
fi
pg -c "\"DROP DATABASE IF EXISTS $DB\"" -c "\"DROP ROLE IF EXISTS $DB\"" || die "reset: datenbank"
if [ -n "$ROLE_DSN" ]; then pg -c "\"DROP DATABASE IF EXISTS $DB\"" || die "reset: datenbank"; else pg -c "\"DROP DATABASE IF EXISTS $DB\"" -c "\"DROP ROLE IF EXISTS $DB\"" || die "reset: datenbank"; fi
rm -rf "$BASE/data/storage" "$BASE/data/staging" "$BASE/env/secrets" "$BASE/env/dsn"
mkdir -p "$BASE/data/storage" "$BASE/data/staging"
cmd_setup
@@ -301,13 +318,14 @@ cmd_teardown() {
# dms_documents und nexarch_app gehoeren dem Entwicklungsbetrieb des Hosts: nur die eigenen Eintraege entfernen
if [ -f "$BASE/env/dsn" ]; then
psql "$(cat "$BASE/env/dsn")" -qAtX -c "select id from documents" 2>/dev/null | while read -r id; do
[ -n "$id" ] && curl -s -X POST "http://127.0.0.1:9308/sql?mode=raw" --data-urlencode "query=DELETE FROM dms_documents WHERE document_id = '$id'" >/dev/null
[ -n "$id" ] && curl -s -X POST "http://127.0.0.1:9308/sql?mode=raw" --data-urlencode "query=DELETE FROM $INDEX_NAME WHERE document_id = '$id'" >/dev/null
done
fi
[ "$INDEX_NAME" != dms_documents ] && curl -s -X POST "http://127.0.0.1:9308/sql?mode=raw" --data-urlencode "query=DROP TABLE IF EXISTS $INDEX_NAME" >/dev/null
if [ "$(pg -c "\"select count(*) from pg_database where datname='$DB'\"")" != 0 ]; then
pg -c "\"DROP DATABASE $DB\"" || echo "WARNUNG: DROP DATABASE"
fi
pg -c "\"DROP ROLE IF EXISTS $DB\"" || true
[ -z "$ROLE_DSN" ] && { pg -c "\"DROP ROLE IF EXISTS $DB\"" || true; }
id "$SVC_USER" >/dev/null 2>&1 && userdel "$SVC_USER"
rm -rf "$BASE" /root/fdn19-*.log
if [ "$keep" != keep-kosit ]; then
+1
View File
@@ -0,0 +1 @@
install-links=true
+1
View File
@@ -0,0 +1 @@
install-links=true
+1
View File
@@ -0,0 +1 @@
install-links=true