backup tile: unknown size shows a dash, not 0 B (R-517 follow-up, measured on 9201)
gates / gates (push) Successful in 14s
gates / gates (push) Successful in 14s
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
@@ -1,3 +1,12 @@
|
|||||||
|
## Unreleased — after v0.243.0 (2026-09-15)
|
||||||
|
|
||||||
|
- **R-517 follow-up — the whole-system tile printed „0 B" for a backup whose size is unknown.**
|
||||||
|
Measured live on demo-hp guest 9201 right after the agent's self-update to 0.131.0: the local tier's
|
||||||
|
success was read back from storage (the agent's in-memory record was empty), and the top card showed
|
||||||
|
„✓ … 0 B · Helyi tároló (local)". It now shows „–" (`guestBackupView.SizeUnknown`). The per-tier rows
|
||||||
|
were already right. Red-proof: without the flag, `TestBuildTierViews_SuccessFromStorageAfterRestart`
|
||||||
|
fails at "tile would print a size it does not know". Ships with the next release; v0.243.0 is live.
|
||||||
|
|
||||||
## v0.243.0 — the file manager gets a real password, the backup page tells the truth per tier, an absent tier stops no app, an OOM-killed worker is seen (2026-09-15, R-513 / R-517 / R-518 / R-514)
|
## v0.243.0 — the file manager gets a real password, the backup page tells the truth per tier, an absent tier stops no app, an OOM-killed worker is seen (2026-09-15, R-513 / R-517 / R-518 / R-514)
|
||||||
|
|
||||||
**MinAgent: 0.131.0** (the per-tier backup status and tier storage presence are agent v0.131.0; the controller supervisor rides the same release)
|
**MinAgent: 0.131.0** (the per-tier backup status and tier storage presence are agent v0.131.0; the controller supervisor rides the same release)
|
||||||
|
|||||||
@@ -114,6 +114,10 @@ type guestBackupView struct {
|
|||||||
|
|
||||||
CanTrigger bool // a backup trigger (quiesce loop) is wired
|
CanTrigger bool // a backup trigger (quiesce loop) is wired
|
||||||
|
|
||||||
|
// SizeUnknown (R-517): the shown success was read back from storage after an agent restart, so
|
||||||
|
// its size is not known. The tile prints „–", never „0 B" (measured live on 9201, 2026-09-15).
|
||||||
|
SizeUnknown bool
|
||||||
|
|
||||||
// Tiers (R-517, agent >= v0.131.0) is the per-tier truth. Empty on an older agent — the tile then
|
// Tiers (R-517, agent >= v0.131.0) is the per-tier truth. Empty on an older agent — the tile then
|
||||||
// renders the single latest record as before.
|
// renders the single latest record as before.
|
||||||
Tiers []guestTierView
|
Tiers []guestTierView
|
||||||
@@ -182,6 +186,7 @@ func buildTierViews(v *guestBackupView, tiers []agentapi.TierBackupState, cadenc
|
|||||||
if tv.HasSuccess && (t.Primary || !v.HasBackup) && (t.Primary || tv.SuccessAt.After(newestOK)) {
|
if tv.HasSuccess && (t.Primary || !v.HasBackup) && (t.Primary || tv.SuccessAt.After(newestOK)) {
|
||||||
v.HasBackup, v.Success = true, true
|
v.HasBackup, v.Success = true, true
|
||||||
v.StartedAt, v.SizeBytes, v.Target = tv.SuccessAt, tv.SizeBytes, tv.Label
|
v.StartedAt, v.SizeBytes, v.Target = tv.SuccessAt, tv.SizeBytes, tv.Label
|
||||||
|
v.SizeUnknown = !tv.SizeKnown
|
||||||
newestOK = tv.SuccessAt
|
newestOK = tv.SuccessAt
|
||||||
}
|
}
|
||||||
v.Tiers = append(v.Tiers, tv)
|
v.Tiers = append(v.Tiers, tv)
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package web
|
package web
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -74,4 +76,24 @@ func TestBuildTierViews_SuccessFromStorageAfterRestart(t *testing.T) {
|
|||||||
if !v.HasBackup || v.Due || v.Tiers[0].SizeKnown {
|
if !v.HasBackup || v.Due || v.Tiers[0].SizeKnown {
|
||||||
t.Fatalf("after restart: want the local success shown, up to date, size unknown: %+v / due=%v", v.Tiers[0], v.Due)
|
t.Fatalf("after restart: want the local success shown, up to date, size unknown: %+v / due=%v", v.Tiers[0], v.Due)
|
||||||
}
|
}
|
||||||
|
// MEASURED LIVE 2026-09-15 on 9201: the top card printed „0 B" for this state.
|
||||||
|
// RED-PROOF (run 2026-09-15, recorded in REPORT.md): without `v.SizeUnknown = !tv.SizeKnown`
|
||||||
|
// this failed at "tile would print a size it does not know".
|
||||||
|
if !v.SizeUnknown {
|
||||||
|
t.Fatal("tile would print a size it does not know (0 B) for a success read back from storage")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The rendered tile says „–", not „0 B", when the size is unknown.
|
||||||
|
func TestBackupTile_UnknownSizeRendersDash(t *testing.T) {
|
||||||
|
s := securityHarness(t)
|
||||||
|
s.loadTemplates()
|
||||||
|
v := &guestBackupView{Available: true, HasBackup: true, Success: true, SizeUnknown: true, Target: "Helyi tároló (local)"}
|
||||||
|
var buf bytes.Buffer
|
||||||
|
if err := s.tmpl.ExecuteTemplate(&buf, "backups", map[string]interface{}{"Page": "backups", "Title": "t", "GuestBackup": v, "Backup": map[string]interface{}{}}); err != nil {
|
||||||
|
t.Skipf("backups page needs more data than this harness gives: %v", err)
|
||||||
|
}
|
||||||
|
if strings.Contains(buf.String(), ">0 B<") {
|
||||||
|
t.Fatal("unknown size rendered as 0 B")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,7 +93,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="stat-card stat-total">
|
<div class="stat-card stat-total">
|
||||||
<div class="stat-value">{{if .HasBackup}}{{fmtBytes .SizeBytes}}{{else}}–{{end}}</div>
|
<div class="stat-value">{{if and .HasBackup (not .SizeUnknown)}}{{fmtBytes .SizeBytes}}{{else}}–{{end}}</div>
|
||||||
<div class="stat-label">{{if .HasBackup}}{{.Target}}{{else}}Méret / cél{{end}}</div>
|
<div class="stat-label">{{if .HasBackup}}{{.Target}}{{else}}Méret / cél{{end}}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="stat-card">
|
<div class="stat-card">
|
||||||
|
|||||||
Reference in New Issue
Block a user