TAR-01: now-unabhaengigkeits-test auf echte getrennte Datensaetze umgestellt
CI / Web-Barrierefreiheitspruefung (axe, Tastatur, Reflow, Textabstaende) (push) Canceled after 0s
CI / Web-Barrierefreiheitspruefung (axe, Tastatur, Reflow, Textabstaende) (pull_request) Canceled after 0s
CI / Core-Modul (Build/Vet/Test) (push) Canceled after 0s
CI / DMS Security-Test-Gate (AC5, Merge-Gate) (push) Canceled after 0s
CI / Connect Security-Test-Gate (QA-01 AC4, Merge-Gate) (push) Canceled after 0s
CI / DMS-Modul Supply-Chain-Scan (govulncheck) (push) Canceled after 0s
CI / Web (dms-browser) (push) Canceled after 0s
CI / Web (pdf-viewer) (push) Canceled after 0s
CI / Web (shl) (push) Canceled after 0s
CI / Web (dms-browser) (pull_request) Canceled after 0s
Archive-Pflichttest-Gate / pflichttest-gate (pull_request) Canceled after 0s
CI / Core-Modul (Build/Vet/Test) (pull_request) Canceled after 0s
CI / DMS Security-Test-Gate (AC5, Merge-Gate) (pull_request) Canceled after 0s
CI / Connect Security-Test-Gate (QA-01 AC4, Merge-Gate) (pull_request) Canceled after 0s
CI / DMS-Modul Supply-Chain-Scan (govulncheck) (pull_request) Canceled after 0s
CI / Web (pdf-viewer) (pull_request) Canceled after 0s
CI / Web (shl) (pull_request) Canceled after 0s
Supply-Chain-Scan (Go) / govulncheck (push) Canceled after 0s
Core-Schnittstellen-Vertragstests / contract-tests (pull_request) Canceled after 0s
Supply-Chain-Scan (Go) / govulncheck (pull_request) Canceled after 0s
Supply-Chain-Scan (npm) / npm-audit (pull_request) Canceled after 0s
Core-Pflichttest-Gate / pflichttest-gate (pull_request) Canceled after 0s
RBAC-Rollenhierarchie-Pflichtgate / rbac-policy-invariant (pull_request) Canceled after 0s
CI / DMS-Modul (Lint/Build/Test/Coverage/Artefakt) (push) Canceled after 0s
CI / DMS-Modul (Lint/Build/Test/Coverage/Artefakt) (pull_request) Canceled after 0s
CI / Web-Barrierefreiheitspruefung (axe, Tastatur, Reflow, Textabstaende) (push) Canceled after 0s
CI / Web-Barrierefreiheitspruefung (axe, Tastatur, Reflow, Textabstaende) (pull_request) Canceled after 0s
CI / Core-Modul (Build/Vet/Test) (push) Canceled after 0s
CI / DMS Security-Test-Gate (AC5, Merge-Gate) (push) Canceled after 0s
CI / Connect Security-Test-Gate (QA-01 AC4, Merge-Gate) (push) Canceled after 0s
CI / DMS-Modul Supply-Chain-Scan (govulncheck) (push) Canceled after 0s
CI / Web (dms-browser) (push) Canceled after 0s
CI / Web (pdf-viewer) (push) Canceled after 0s
CI / Web (shl) (push) Canceled after 0s
CI / Web (dms-browser) (pull_request) Canceled after 0s
Archive-Pflichttest-Gate / pflichttest-gate (pull_request) Canceled after 0s
CI / Core-Modul (Build/Vet/Test) (pull_request) Canceled after 0s
CI / DMS Security-Test-Gate (AC5, Merge-Gate) (pull_request) Canceled after 0s
CI / Connect Security-Test-Gate (QA-01 AC4, Merge-Gate) (pull_request) Canceled after 0s
CI / DMS-Modul Supply-Chain-Scan (govulncheck) (pull_request) Canceled after 0s
CI / Web (pdf-viewer) (pull_request) Canceled after 0s
CI / Web (shl) (pull_request) Canceled after 0s
Supply-Chain-Scan (Go) / govulncheck (push) Canceled after 0s
Core-Schnittstellen-Vertragstests / contract-tests (pull_request) Canceled after 0s
Supply-Chain-Scan (Go) / govulncheck (pull_request) Canceled after 0s
Supply-Chain-Scan (npm) / npm-audit (pull_request) Canceled after 0s
Core-Pflichttest-Gate / pflichttest-gate (pull_request) Canceled after 0s
RBAC-Rollenhierarchie-Pflichtgate / rbac-policy-invariant (pull_request) Canceled after 0s
CI / DMS-Modul (Lint/Build/Test/Coverage/Artefakt) (push) Canceled after 0s
CI / DMS-Modul (Lint/Build/Test/Coverage/Artefakt) (pull_request) Canceled after 0s
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
ecea9bcc8c
commit
bc60e11b4c
2 files changed
+23
-22
No files matched your search
@@ -15,9 +15,9 @@ Ergebnis: PASS. Alle 50 Fristen nach Migration bitgenau identisch zur Quelle (`t
|
||||
|
||||
Test: `TestMigrateAll_ResultIndependentOfInjectedNow`.
|
||||
|
||||
Zwei vollständig unabhängige Migrationsläufe gegen zwei getrennte Zieldatenbanken, mit demselben Quellobjekt (`retain_until` = 2040-06-15), aber mit injiziertem `now`-Parameter, der künstlich um 73 Jahre auseinanderliegt (2026-10-14 vs. 2099-12-31). `now` fließt im Migrator ausschließlich in `Result.RanAt` (Protokoll-Metadatum) ein, nie in die Frist-Übernahme (`retention.SetRetainUntil` nimmt die Quellfrist unverändert).
|
||||
Zwei Migrationsläufe gegen dieselbe Zieldatenbank, aber auf zwei voneinander unabhängigen Quellobjekten (`object_reference` `doc-clock-test-a` bzw. `doc-clock-test-b`, dieselbe Quellfrist `retain_until` = 2030-06-15), mit injiziertem `now`-Parameter, der künstlich um 73 Jahre auseinanderliegt (2026-01-01 vs. 2099-01-01). `now` fließt im Migrator ausschließlich in `Result.RanAt` (Protokoll-Metadatum) ein, nie in die Frist-Übernahme (`retention.SetRetainUntil` nimmt die Quellfrist unverändert).
|
||||
|
||||
Ergebnis: PASS. Beide Läufe liefern exakt dieselbe `retain_until` in der Zieldatenbank, unabhängig vom injizierten `now`.
|
||||
Ergebnis: PASS. Beide (unabhängigen) Datensätze erhalten exakt dieselbe `retain_until`, unabhängig vom injizierten `now`. Gegenprobe durchgeführt: wird `now` testweise künstlich in die Fristberechnung eingebaut, schlägt der Test fehl (Vergleich `gotA.Equal(gotB)`), was belegt, dass der Test tatsächlich scharf ist; der Eingriff wurde danach wieder zurückgenommen und nicht committet.
|
||||
|
||||
## Prüfung 3 – Objekte ohne Quellfrist bleiben ohne Frist
|
||||
|
||||
@@ -36,7 +36,7 @@ Migration `archive/migrations/0017_retention_objects_retain_until.{up,down}.sql`
|
||||
| Prüfung | Ergebnis |
|
||||
|---|---|
|
||||
| 1 – 50 Stichproben, Frist exakt identisch | PASS |
|
||||
| 2 – keine Berechnung aus aktuellem Datum (zwei Läufe, unterschiedliches `now`) | PASS |
|
||||
| 2 – keine Berechnung aus aktuellem Datum (zwei unabhängige Datensätze, unterschiedliches `now`) | PASS |
|
||||
| 3 – keine Frist ohne Quellfrist | PASS |
|
||||
| Bestehende `archive/internal/retention`-Tests weiterhin grün | PASS (3 PASS, 1 SKIP mangels zweiter Tenant-DSN, unverändert zum Vorzustand) |
|
||||
| `go vet ./...` (archive-Modul) | clean |
|
||||
|
||||
@@ -144,36 +144,37 @@ func TestMigrateAll_ObjectsWithoutSourceDeadlineStayWithoutOne(t *testing.T) {
|
||||
|
||||
// TestMigrateAll_ResultIndependentOfInjectedNow ist Pruefung 2
|
||||
// (Akzeptanzkriterium 2): zwei Migrationslaeufe mit weit auseinander
|
||||
// liegenden "jetzt"-Zeitpunkten liefern IDENTISCHE retain_until-Werte -
|
||||
// echter Nachweis statt Behauptung, dass now() an keiner Stelle in die
|
||||
// berechnete Frist einfliesst.
|
||||
// liegenden "jetzt"-Zeitpunkten, auf zwei voneinander unabhaengigen
|
||||
// Datensaetzen (unterschiedliche ObjectReference, gleiche Quellfrist),
|
||||
// liefern IDENTISCHE retain_until-Werte - echter Nachweis statt
|
||||
// Behauptung, dass now() an keiner Stelle in die berechnete Frist
|
||||
// einfliesst. Wuerde now faelschlich einfliessen, muessten sich die
|
||||
// beiden Ergebnisse unterscheiden (naeher am jeweils injizierten now).
|
||||
func TestMigrateAll_ResultIndependentOfInjectedNow(t *testing.T) {
|
||||
poolA := requireTestPool(t)
|
||||
poolB := requireTestPool(t)
|
||||
pool := requireTestPool(t)
|
||||
|
||||
due := time.Date(2040, time.June, 15, 12, 0, 0, 0, time.UTC)
|
||||
source := func() *fixtureSource {
|
||||
return &fixtureSource{objects: []SourceObject{
|
||||
{ObjectType: "dms_document", ObjectReference: "doc-clock-test", RetainUntil: &due},
|
||||
}}
|
||||
}
|
||||
due := time.Date(2030, time.June, 15, 12, 0, 0, 0, time.UTC)
|
||||
|
||||
nowA := time.Date(2026, time.October, 14, 0, 0, 0, 0, time.UTC)
|
||||
nowB := time.Date(2099, time.December, 31, 23, 59, 59, 0, time.UTC)
|
||||
nowA := time.Date(2026, time.January, 1, 0, 0, 0, 0, time.UTC)
|
||||
nowB := time.Date(2099, time.January, 1, 0, 0, 0, 0, time.UTC)
|
||||
|
||||
mA := NewMigrator(poolA, source())
|
||||
mA := NewMigrator(pool, &fixtureSource{objects: []SourceObject{
|
||||
{ObjectType: "dms_document", ObjectReference: "doc-clock-test-a", RetainUntil: &due},
|
||||
}})
|
||||
if _, err := mA.MigrateAll(context.Background(), nowA); err != nil {
|
||||
t.Fatalf("migrateall (now=A): %v", err)
|
||||
}
|
||||
mB := NewMigrator(poolB, source())
|
||||
mB := NewMigrator(pool, &fixtureSource{objects: []SourceObject{
|
||||
{ObjectType: "dms_document", ObjectReference: "doc-clock-test-b", RetainUntil: &due},
|
||||
}})
|
||||
if _, err := mB.MigrateAll(context.Background(), nowB); err != nil {
|
||||
t.Fatalf("migrateall (now=B): %v", err)
|
||||
}
|
||||
|
||||
idA := objectID(t, poolA, "dms_document", "doc-clock-test")
|
||||
idB := objectID(t, poolB, "dms_document", "doc-clock-test")
|
||||
gotA, okA := mustRetainUntil(t, poolA, idA)
|
||||
gotB, okB := mustRetainUntil(t, poolB, idB)
|
||||
idA := objectID(t, pool, "dms_document", "doc-clock-test-a")
|
||||
idB := objectID(t, pool, "dms_document", "doc-clock-test-b")
|
||||
gotA, okA := mustRetainUntil(t, pool, idA)
|
||||
gotB, okB := mustRetainUntil(t, pool, idB)
|
||||
if !okA || !okB {
|
||||
t.Fatalf("erwartet beide laeufe mit gesetzter frist, okA=%v okB=%v", okA, okB)
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user