v0.193.1 — the refusal's size estimate is rendered in bytes, not "0.00 GiB" (R-181 follow-on)
gates / gates (push) Successful in 9s

Found by v0.193.0's own live proof run. The estimate was printed fixed to two
decimal GiB, so every app under ~10 MB rendered as "estimated 0.00 GiB write" —
which reads as "no estimate was available" and is the opposite of what happened.
Observed live on demo-hp 08:59:46: opengist's real 178 KB estimate printed as
0.00 GiB.

Shipped in the same session because it is the same defect class R-181 is about:
a message an operator cannot rely on is worse than no message.

The arithmetic is unchanged and still in GiB — the reserve's own unit, so the
comparison against FloorFreeGiB reads directly. Only the rendering moved to
humanizeBytes. estimatedWriteGiB -> estimatedWriteBytes, with the GiB conversion
done once at the point of comparison.
This commit is contained in:
2026-08-03 11:05:02 +02:00
parent fef07c3923
commit 6c43bf6156
4 changed files with 42 additions and 18 deletions
+8 -8
View File
@@ -426,7 +426,7 @@ func TestAdmission_SizeTermRefusesAnAppWhoseOwnWriteWouldCrossTheReserve(t *test
if !strings.Contains(h.logs.String(), "(size)") {
t.Fatalf("the refusal was not attributed to the SIZE term:\n%s", h.logs.String())
}
if !strings.Contains(h.events[0].err, "last backup was 2.00 GiB") {
if !strings.Contains(h.events[0].err, "last backup was 2.0 GB") {
t.Fatalf("the alert does not carry the estimate that produced the refusal: %q", h.events[0].err)
}
if len(h.volDumped) != 0 {
@@ -443,8 +443,8 @@ func TestAdmission_FirstEverBackupIsAdmitted(t *testing.T) {
h := newAdmissionHarness(t, "brandnew")
h.setSpace("brandnew", 40, 600, 1000) // ample room, and NO previous unit on disk
if est, ok := h.m.estimatedWriteGiB("brandnew"); ok || est != 0 {
t.Fatalf("estimatedWriteGiB = (%v, %v) for an app with no history, want (0, false)", est, ok)
if est, ok := h.m.estimatedWriteBytes("brandnew"); ok || est != 0 {
t.Fatalf("estimatedWriteBytes = (%v, %v) for an app with no history, want (0, false)", est, ok)
}
h.runOneBackupRun()
@@ -558,16 +558,16 @@ func TestAdmission_UnreadableFilesystemAdmitsEveryLegAndDoesNotWarn(t *testing.T
// ── The estimator, through the production path (no seam) ─────────────────────────────────────────
func TestEstimatedWriteGiB_SumsTheAppsPreviousDumpsFromRealFiles(t *testing.T) {
func TestEstimatedWriteBytes_SumsTheAppsPreviousDumpsFromRealFiles(t *testing.T) {
h := newAdmissionHarness(t, "opengist")
h.seedUnit(t, "opengist", 3<<30) // 3 GiB sparse tar + a small .sql
est, ok := h.m.estimatedWriteGiB("opengist")
est, ok := h.m.estimatedWriteBytes("opengist")
if !ok {
t.Fatal("history on disk was not recognised as history")
}
if est < 3.0 || est > 3.001 {
t.Fatalf("estimate = %.4f GiB, want ~3.0 (the .tar plus the small .sql)", est)
if est < 3<<30 || est > (3<<30)+4096 {
t.Fatalf("estimate = %d B, want ~%d (the .tar plus the small .sql)", est, int64(3)<<30)
}
// An app whose unit exists but holds no dumps yet is history-LESS, not a zero-byte estimate.
@@ -575,7 +575,7 @@ func TestEstimatedWriteGiB_SumsTheAppsPreviousDumpsFromRealFiles(t *testing.T) {
if err := os.MkdirAll(other, 0o755); err != nil {
t.Fatal(err)
}
if est, ok := h.m.estimatedWriteGiB("empty"); ok || est != 0 {
if est, ok := h.m.estimatedWriteBytes("empty"); ok || est != 0 {
t.Fatalf("an empty unit reported history (%v, %v) — an absent dump is not a 0-byte one", est, ok)
}
}