v0.324.0: the database password comes back with the data (R-1106, R-127b, R-926); restic 0.19.1 (R-1107); R-1108, R-1065, R-1017; dashboard hardening (R-983, R-976)
gates / gates (push) Successful in 44s

This commit is contained in:
2026-10-16 22:46:00 +02:00
parent 00a0d91976
commit f75b3aa778
212 changed files with 2414 additions and 398 deletions
@@ -12,13 +12,13 @@ import (
"time"
)
// R-1105: the off-site code was measured against restic 0.14.0; v0.323.0 ships 0.18.1. The fixtures in
// R-1105: the off-site code was measured against restic 0.14.0; v0.323.0 shipped 0.18.1, v0.324.0 ships 0.19.1 (R-1107). The fixtures in
// testdata/restic/<version>/ are REAL outputs of both official binaries, captured 2026-10-16 on one shared scratch
// repository (made by 0.14.0, so both versions read the same snapshot set; paths rewritten to /data/x). Each
// repository (made by 0.14.0, so every version reads the same snapshot set — recaptured for all three on 2026-10-16 20:10 UTC; paths rewritten to /data/x). Each
// assumption the code makes about restic's output is asserted for BOTH versions through the code's own functions —
// so a future restic that rewords one of them fails here, by name, instead of moving a failure to `unknown` on a
// customer's box (07-backup-architecture.md §6.7, §6.8).
var r1105Versions = []string{"0.14.0", "0.18.1"}
var r1105Versions = []string{"0.14.0", "0.18.1", "0.19.1"} // [0] is the measured baseline; v0.324.0 ships the last
func r1105Fixture(t *testing.T, version, name string) []byte {
t.Helper()
@@ -162,7 +162,7 @@ func TestR1105_TheJSONTheCodeReadsStillParses(t *testing.T) {
t.Errorf("restic %s: no status line carried the totals the progress bar shows", v)
}
}
if counts["0.14.0"] != counts["0.18.1"] {
if counts["0.14.0"] != counts["0.18.1"] || counts["0.14.0"] != counts["0.19.1"] {
t.Errorf("the two versions list a different number of snapshots of ONE repository: %v", counts)
}
}
@@ -213,40 +213,42 @@ func TestR1105_TheForgetPlanOnlyEverKeepsMore(t *testing.T) {
t.Errorf("restic %s: the guard refuses the honest plan: %s", v, refuse)
}
}
for id := range plans["0.18.1"] {
if !plans["0.14.0"][id] {
t.Errorf("0.18.1 removes snapshot %s, which 0.14.0 keeps — the new restic removes MORE", id)
for _, v := range r1105Versions[1:] { // every newer version against 0.14.0, the measured baseline
for id := range plans[v] {
if !plans["0.14.0"][id] {
t.Errorf("%s removes snapshot %s, which 0.14.0 keeps — the new restic removes MORE", v, id)
}
}
}
// Every snapshot only 0.14.0 removes is one 0.18.1 keeps as the „oldest" of a window with unused slots.
var groups []struct {
Reasons []struct {
Snapshot struct {
ID string `json:"id"`
} `json:"snapshot"`
Matches []string `json:"matches"`
} `json:"reasons"`
}
if err := json.Unmarshal(r1105Fixture(t, "0.18.1", "forget-dryrun.json"), &groups); err != nil {
t.Fatal(err)
}
why := map[string]string{}
for _, g := range groups {
for _, r := range g.Reasons {
why[r.Snapshot.ID] = strings.Join(r.Matches, ",")
// Every snapshot only 0.14.0 removes is one the newer version keeps as the „oldest" of a window with unused slots.
var groups []struct {
Reasons []struct {
Snapshot struct {
ID string `json:"id"`
} `json:"snapshot"`
Matches []string `json:"matches"`
} `json:"reasons"`
}
}
extra := 0
for id := range plans["0.14.0"] {
if plans["0.18.1"][id] {
continue
if err := json.Unmarshal(r1105Fixture(t, v, "forget-dryrun.json"), &groups); err != nil {
t.Fatal(err)
}
extra++
if !strings.Contains(why[id], "oldest") {
t.Errorf("0.18.1 keeps snapshot %s that 0.14.0 removes, for a reason other than “oldest”: %q", id, why[id])
why := map[string]string{}
for _, g := range groups {
for _, r := range g.Reasons {
why[r.Snapshot.ID] = strings.Join(r.Matches, ",")
}
}
extra := 0
for id := range plans["0.14.0"] {
if plans[v][id] {
continue
}
extra++
if !strings.Contains(why[id], "oldest") {
t.Errorf("%s keeps snapshot %s that 0.14.0 removes, for a reason other than “oldest”: %q", v, id, why[id])
}
}
if extra == 0 {
t.Errorf("%s: the fixture no longer shows the 0.17+ “oldest” keep — it no longer tests the difference it documents", v)
}
}
if extra == 0 {
t.Error("the fixture no longer shows the 0.17+ “oldest” keep — it no longer tests the difference it documents")
}
}