Files
nexarch/internal/opsdocs/opsdocs_test.go
T
patrickandClaude Sonnet 5 692be05d2a
Supply-Chain-Scan (Go) / govulncheck (push) Failing after 2m8s
OPS-07: betriebs-gate-mtls-aktivierungspflicht-beim-wechsel-auf-verteilten-betrieb
Readiness-Warnung (internal/health.Registry.RegisterWarning) plus
internal/mtls.GateCheck erkennen verteilten Betrieb (>1 Instanz/Host) ohne
aktives mTLS und machen das als "mtls-gate"-Warnung im Readiness-Antwort-
koerper sichtbar, ohne den Dienst als "nicht bereit" zu melden. Neue
Betriebs-Checkliste (docs/BETRIEBS-CHECKLISTE-STUFENWECHSEL.md) haelt die
mTLS-Aktivierung als Pflichtschritt beim Wechsel Stufe 1 -> Stufe 2 fest,
SKALIERUNGSKONZEPT.md verweist darauf.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QPsyieCYwvbUBsnN598SbP
2026-09-17 12:06:02 +02:00

91 lines
4.0 KiB
Go

package opsdocs
import (
"os"
"path/filepath"
"strings"
"testing"
)
func readPlan(t *testing.T) string {
t.Helper()
// Test laeuft aus internal/opsdocs/ heraus, Repo-Root ist zwei Ebenen hoeher.
path := filepath.Join("..", "..", IncidentResponsePlanPath)
data, err := os.ReadFile(path)
if err != nil {
t.Fatalf("incident-response-plan nicht lesbar (%s): %v", path, err)
}
return string(data)
}
func readStufenwechselChecklist(t *testing.T) string {
t.Helper()
path := filepath.Join("..", "..", StufenwechselChecklistPath)
data, err := os.ReadFile(path)
if err != nil {
t.Fatalf("betriebs-checkliste stufenwechsel nicht lesbar (%s): %v", path, err)
}
return string(data)
}
func requireContains(t *testing.T, content, substr, why string) {
t.Helper()
if !strings.Contains(content, substr) {
t.Fatalf("erwartet %q im incident-response-plan (%s), nicht gefunden", substr, why)
}
}
// Akzeptanzkriterium 1: Ablaufplan dokumentiert Erkennung/Eskalation/
// Meldefristen/Verantwortlichkeiten.
func TestPlan_DocumentsDetectionEscalationAndResponsibilities(t *testing.T) {
content := readPlan(t)
requireContains(t, content, "Erkennung", "Abschnitt Erkennung fehlt")
requireContains(t, content, "Eskalationskette", "Abschnitt Eskalation fehlt")
requireContains(t, content, "Incident Commander", "Verantwortlichkeits-Rolle fehlt")
requireContains(t, content, "Datenschutzbeauftragter", "DSB-Rolle fehlt")
}
// Akzeptanzkriterium 2: DSGVO-72-Stunden-Meldefrist ist als Prozessschritt
// mit Verantwortlichem hinterlegt.
func TestPlan_Documents72HourGDPRDeadlineWithResponsibleRole(t *testing.T) {
content := readPlan(t)
requireContains(t, content, "72 Stunden", "72-Stunden-Frist fehlt")
requireContains(t, content, "Art. 33", "Verweis auf Art. 33 DSGVO fehlt")
requireContains(t, content, "Verantwortlich für die Meldung", "Zuständigkeit für die Meldung fehlt")
}
// Akzeptanzkriterium 3: Plan verweist konkret auf die Audit-Log-Quellen
// (Core AUD-01/AUD-03/AUD-05), die im Vorfall herangezogen werden.
func TestPlan_ReferencesConcreteAuditLogSources(t *testing.T) {
content := readPlan(t)
requireContains(t, content, "AUD-01", "Verweis auf AUD-01 fehlt")
requireContains(t, content, "AUD-03", "Verweis auf AUD-03 (Export) fehlt")
requireContains(t, content, "internal/audit", "konkreter Code-Pfad zum Audit-Log fehlt")
requireContains(t, content, "StreamCSV", "konkrete Export-Funktion fehlt")
}
// Zusaetzliche Absicherung: die drei geforderten Pruefungen sind im
// Dokument tatsaechlich mit einem Ergebnis (PASS/OFFEN) festgehalten,
// nicht nur als Vorhaben erwaehnt — verhindert, dass "durchgefuehrt"
// behauptet wird, ohne das Ergebnis schriftlich festzuhalten (Ticket-
// Vorgabe: "Nicht durchgefuehrte Pruefungen zaehlen als offen").
func TestPlan_RecordsAllThreeRequiredCheckResults(t *testing.T) {
content := readPlan(t)
requireContains(t, content, "Prüfung 1", "Ergebnis der Tabletop-Übung fehlt")
requireContains(t, content, "Prüfung 2", "Ergebnis der Meldefrist-Vollständigkeitsprüfung fehlt")
requireContains(t, content, "Prüfung 3", "Ergebnis der Kontaktlisten-Prüfung fehlt")
requireContains(t, content, "Status: OFFEN", "ehrlicher Offen-Status fuer die nicht durchfuehrbare Kontaktlisten-Pruefung fehlt")
}
// Core OPS-07 / Akzeptanzkriterium 2 + Pruefung 3: die Betriebs-Checkliste
// fuer den Wechsel Stufe 1 -> Stufe 2 enthaelt mTLS-Aktivierung als
// Pflichtschritt und verweist auf den konkreten Gate-Mechanismus.
func TestStufenwechselChecklist_ContainsMTLSAsMandatoryStep(t *testing.T) {
content := readStufenwechselChecklist(t)
requireContains(t, content, "Stufe 1", "Bezug zur Ausgangsstufe fehlt")
requireContains(t, content, "Stufe 2", "Bezug zur Zielstufe fehlt")
requireContains(t, content, "mTLS zwischen Modul-Instanzen aktivieren (Pflichtschritt)", "mTLS als Pflichtschritt fehlt")
requireContains(t, content, "internal/mtls", "Verweis auf den mTLS-Code fehlt")
requireContains(t, content, "mtls-gate", "Verweis auf den konkreten Gate-Mechanismus (Warnungsname) fehlt")
}