Files
nexarch/archive/docs/BAK-06-PRUEFPROTOKOLL.md
T
sysops c761cf9b93 feat(archive): BAK-06 Restore-Testverfahren
internal/restoretest wiederholt BAK-03s eigene Pruefdiskt als
Produktcode: echter Restore der neuesten Sicherung, echter Kurzstart
einer isolierten Postgres-Instanz, echte SELECT-1-Abfrage; Objekt-Seite
echter restic-Restore + Inhaltspruefung. JSONL-Historie (append-only),
sichtbare Warnung ueber denselben OPS-05-Pull-Weg wie BAK-08, eigenes
/metrics-Modul (archive-restoretest). Zwei reale Defekte gefunden und
behoben: Unix-Socket-Pfadlaenge unter tief verschachtelten Testpfaden,
restic-stderr-Vermischung beim JSON-Parsen unter dem Dienstnutzer.
Real auf 131 verdrahtet und ausgeloest (beide Testarten erfolgreich,
End-zu-Ende ueber OPS-03 bestaetigt).
2026-08-30 00:31:34 +02:00

5.9 KiB
Raw Blame History

BAK-06 Prüfprotokoll: Restore-Testverfahren

Voraussetzung BAK-03 erledigt, siehe eigenes Protokoll.

Grundsatzentscheidung: Produktcode statt Testcode für den echten Nachweis

Produkt-DNA: "Wiederherstellung ist Routine, nicht Ausnahmefall regelmäßig getestet." Ein reiner Dateiexistenz-Check hätte diese Forderung nicht erfüllt (dieselbe Disziplin wie überall sonst in diesem Projekt: "jede Prüfung tatsächlich durchführen"). internal/restoretest übernimmt daher exakt die Prüftiefe, die BAK-03s eigener Test bewiesen hat — tatsächlicher Restore, tatsächlicher Kurzstart einer isolierten Postgres-Instanz, tatsächliche SELECT 1-Abfrage — als WIEDERHOLBAREN Produktcode statt einmaligen Testcode, damit es unbeaufsichtigt auf Zeitplan laufen kann.

Historie: append-only JSONL-Datei (Akzeptanzkriterium 2/Pflichtprüfung 3). Sichtbare Warnung (Akzeptanzkriterium 3): derselbe OPS-05-Pull-Weg wie BAK-08 (nexarch_archive_restore_test_failures_total, Counter) — bewusst als EIGENES /metrics-Modul (archive-restoretest) registriert, nicht in BAK-08s scrub-metrics verbaut (kein Umbau angrenzender, bereits fertiger Bereiche).

Drei reale Defekte während der Implementierung gefunden und behoben

  1. Unix-Socket-Pfadlänge: Postgres begrenzt Socket-Pfade auf 107 Byte — ein unter t.TempDir() verschachtelter Pfad reißt dieses Limit leicht. Fix: eigenes, kurzes Socket-Verzeichnis (os.MkdirTemp("", ...)), nicht unter dem Testverzeichnis.
  2. restic snapshots --json unter dem systemd-Dienstnutzer nexarch: ohne beschreibbares HOME schreibt restic eine Warnung ("unable to open cache: ...") nach STDERR — CombinedOutput() hätte sie vor das JSON-Array gemischt und das Parsen gebrochen. Fix: nur cmd.Output() (stdout), stderr separat für Fehlermeldungen.
  3. Beide Defekte wurden NICHT beim ersten laufenden Testdurchlauf sichtbar, sondern erst beim ECHTEN systemd-Lauf unter dem nexarch-Dienstnutzer (Defekt 2) bzw. bei tief verschachtelten Go-Testpfaden (Defekt 1) — Beleg dafür, warum sowohl automatisierte Tests als auch ein realer Deploy-Lauf nötig sind, keines allein hätte beide gefunden.

Umsetzung

  • internal/restoretest.RunDatabaseTest — neueste Generation ermitteln (backup.ListGenerations), backup.Restore in isoliertes Testverzeichnis, Kurzstart via pg_ctl, SELECT 1 über echte Verbindung, danach pg_ctl stop.
  • internal/restoretest.RunObjectTest — neuesten Snapshot ermitteln, objectbackup.Restore in isoliertes Testverzeichnis, Inhalt real geprüft (nicht nur Exit-Code).
  • internal/restoretest.AppendHistory/ReadHistory — JSONL, append-only.
  • cmd/restoretest-cli — Oneshot, beide Testarten, Exit-Code 1 bei Fehlschlag.
  • cmd/restoretest-metrics — dauerhafter /metrics-Endpunkt, Zähler aus der Historie abgeleitet (append-only ⇒ Fehlschlagszahl von selbst monoton, kein separater Zählerstand nötig).

Prüfungen

# Prüfung Ergebnis
1 Geplanter Testlauf gegen aktuelle Sicherung erfolgreich durchgeführt und protokolliert bestandenTestRunDatabaseTest_SucceedsAgainstRealBackup, TestRunObjectTest_SucceedsAgainstRealSnapshot; real auf 131: systemctl start nexarch-archive-restoretest.service → beide Testarten erfolg=true, in history.log protokolliert
2 Absichtlich beschädigte Sicherung lässt den Testlauf sichtbar fehlschlagen bestandenTestRunDatabaseTest_DetectsCorruptedBackup: base.tar.gz durch Datenmüll ersetzt, RunDatabaseTest liefert Success=false mit aussagekräftigem Detail
3 Protokollhistorie zeigt mehrere zurückliegende Testläufe nachvollziehbar an bestandenTestHistory_ShowsMultiplePastRunsInOrder: drei Einträge angehängt, in exakt derselben Reihenfolge gelesen

Echte Verdrahtung auf 192.168.1.131

  • restoretest-cli, restoretest-metrics gebaut nach /opt/nexarch-archive/bin/
  • /etc/nexarch/archive-restoretest.env (0600)
  • nexarch-archive-restoretest.timer installiert/aktiviert (wöchentlich So. 07:00 UTC), nexarch-archive-restoretest-metrics.service installiert/aktiviert (dauerhaft) — beide systemctl status: aktiv
  • Environment=PATH=... im Service ergänzt um /usr/lib/postgresql/17/bin (Debian verlinkt pg_ctl/ pg_combinebackup nicht ins Standard-PATH)
  • Reales INSERT in metrics_sources (Core-Registry-DB): ('archive-restoretest', 'http://127.0.0.1:8091/metrics')
  • End-to-End über OPS-03 bestätigt: curl http://127.0.0.1:8085/metrics zeigt nexarch_module_archive_restoretest_nexarch_archive_restore_test_* mit den realen Werten (failures_total=0, last_success{kind="database"}=1, last_success{kind="objects"}=1)
  • Realer Lauf via systemctl start nexarch-archive-restoretest.service: beide Testarten erfolgreich, Journal zeigt Details, /metrics und OPS-03-Aggregation stimmen überein

Build/Test-Ergebnis (192.168.1.131, make check)

go build ./...  -> clean
go vet ./...    -> clean
golangci-lint run ./...  -> 0 issues
go test ./... -p 1 -count=1  -> 6/6 Pakete mit Tests ok (backup, objectbackup, reconcile, restore, restoretest, scrub), 0 Fehlschläge

Hinweis wie bei BAK-03: die Datenbank-Restore-Tests (TestRunDatabaseTest_*) brauchen pg_ctl/pg_combinebackup im PATH und laufen NICHT als root — separat als postgres-Systemnutzer verifiziert (7/7 internal/restoretest-Tests bestanden), im normalen root-make check-Lauf werden sie mit klarer Meldung übersprungen.

Gesamtergebnis

Bestanden. Alle drei Akzeptanzkriterien und alle drei Pflichtprüfungen real erfüllt — sowohl testgetrieben als auch über einen echten, unbeaufsichtigten systemd-Lauf mit OPS-03/OPS-05-Sichtbarkeit nachgewiesen. Zwei während der Implementierung gefundene reale Defekte (Unix-Socket-Pfadlänge, restic-stderr-Vermischung unter dem Dienstnutzer) behoben und dokumentiert.