hub v0.90.1 — the digest's per-app lines stop repeating the filesystem figures (R-182)
gates / gates (push) Successful in 7s
gates / gates (push) Successful in 7s
Found by reading the first REAL digest, not by design. Every app row ended with the same usage clause the mail already prints once on its own Filesystem line. On a two-app box that is untidy; down a list of a dozen it is the same forty characters twelve times, pushing the part that DIFFERS off a phone screen at 07:00 — the only moment this mail has to work. The reserve's refusal message is authored for a single-app alert where naming the filesystem is right, so the message is unchanged; the digest trims the duplicate when rendering. trimRepeatedUsage removes ONLY an exact "— <target path>:" suffix, so an unrelated reason is untouched and a reason that is nothing but the usage clause is left alone rather than emptied. Also updates TestRecoveryUnitCaptureFailed_NeverReachesTheCustomer, which required the OPERATOR to be emailed a per-app capture failure. That was correct when the event was the only signal and is wrong now that it is the record and the digest is the notification. Its customer-safety claim is unchanged and is why the test still exists; the operator assertion is inverted with the reasoning written in place, and R-158's guarantee is shown to have MOVED, not weakened.
This commit is contained in:
@@ -264,3 +264,38 @@ func TestPerAppFailure_IsRecordedButNotMailed(t *testing.T) {
|
||||
"anywhere is the measured defect of 2026-08-03", len(seen), len(apps), seen)
|
||||
}
|
||||
}
|
||||
|
||||
// The per-app reason must not repeat the filesystem figures the digest already prints once. Reviewed
|
||||
// as copy against the first real digest, not designed in the abstract.
|
||||
func TestDigestEmail_ReasonDoesNotRepeatTheUsageLine(t *testing.T) {
|
||||
reason := "refused: below the reserve (reserve: 97% used or 1.0 GiB free) — /mnt/sys_drive: 65.0/68.7 GB used (95%), 0.2 GB free"
|
||||
details := `{"run_id":"r","run_kind":"nightly","failed":1,"attempted":2,"target_path":"/mnt/sys_drive",` +
|
||||
`"used_gb":65,"avail_gb":0.2,"total_gb":68.7,"used_percent":95,"space_known":true,` +
|
||||
`"apps":[{"app":"opengist","leg":"whole app","reason":"` + reason + `"}]}`
|
||||
_, body := FormatOperatorEmail("demo-hp", "backup_run_failures", "error", "1 of 2 failed", details)
|
||||
|
||||
// The figures appear ONCE, on the Filesystem line — not again on every app row.
|
||||
if strings.Count(body, "65.0/68.7 GB used") != 1 {
|
||||
t.Fatalf("the usage clause appears %d times; it must appear once, on its own line — repeated "+
|
||||
"down a list of a dozen apps it pushes the part that DIFFERS off a phone screen:\n%s",
|
||||
strings.Count(body, "65.0/68.7 GB used"), body)
|
||||
}
|
||||
// But the reason itself survives — trimming must not eat the diagnosis.
|
||||
if !strings.Contains(body, "below the reserve") {
|
||||
t.Fatalf("the reason was trimmed away entirely:\n%s", body)
|
||||
}
|
||||
}
|
||||
|
||||
// A reason naming a DIFFERENT path, or none, must be left completely alone.
|
||||
func TestTrimRepeatedUsage_LeavesUnrelatedReasonsAlone(t *testing.T) {
|
||||
for _, c := range []struct{ reason, target string }{
|
||||
{"pg_dump: connection refused", "/mnt/sys_drive"},
|
||||
{"tar failed — /mnt/other: 1/2 GB used (50%), 1 GB free", "/mnt/sys_drive"},
|
||||
{"boom", ""},
|
||||
{"", "/mnt/sys_drive"},
|
||||
} {
|
||||
if got := trimRepeatedUsage(c.reason, c.target); got != c.reason {
|
||||
t.Errorf("reason %q (target %q) was altered to %q", c.reason, c.target, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user