package diskreadings import ( "encoding/json" "strings" "testing" "time" "git.novox.be/novox/mesh-sdk/go/catalogue" ) // ADR 0571 clause 3: a reading keeps its seven-day peak and is written only when it changes; a partial size is no peak. func TestAReadingKeepsItsPeakAndIsWrittenOnlyWhenItChanges(t *testing.T) { at := time.Date(2026, 10, 29, 12, 0, 0, 0, time.UTC) var prev *Reading for i, step := range []struct { day, size int64 partial, wrote bool peak int64 }{{20, 100, false, true, 100}, {20, 100, false, false, 100}, {21, 300, false, true, 300}, {22, 50, false, true, 300}, {23, 9000, true, true, 300}, {29, 10, false, true, 50}, {30, 10, false, true, 10}} { now := time.Date(2026, 10, int(step.day), 1, 0, 0, 0, time.UTC) size := step.size m := Measured{SizeBytes: &size, MeasuredAt: &now, Precision: "exact"} if step.partial { m.Precision = "partial: stopped" } r, wrote := NextReading(prev, "ace", catalogue.PlacedDataItem{Module: "pg", ID: "data", Path: "/srv/pg"}, m, now) raw, _ := json.Marshal(r) back, err := DecodeReading(raw) if wrote != step.wrote || r.Peak == nil || *r.Peak != step.peak || err != nil || back.ID != "data" { t.Fatalf("reading %d: wrote %v, peak %v, read back %v", i, wrote, r.Peak, err) } prev = &r } // The first reading sets FirstSeen and every one after keeps it, as it keeps a retirement; an older reading reads as before. if first := time.Date(2026, 10, 20, 1, 0, 0, 0, time.UTC); !prev.FirstSeen.Equal(first) { t.Fatalf("first seen %s, not %s", prev.FirstSeen, first) } retired := *prev retired.RetiredAt, retired.RetiredWhy = at, "its module left ace" if r, _ := NextReading(&retired, "ace", retired.PlacedDataItem, retired.Measured, at.Add(time.Hour)); !r.RetiredAt.Equal(at) || r.RetiredWhy != "its module left ace" || !r.FirstSeen.Equal(prev.FirstSeen) { t.Fatalf("a retired reading moved on as %+v", r) } if old, err := DecodeReading([]byte(`{"v":1,"node":"ace","module":"pg","item":"data"}`)); err != nil || !old.FirstSeen.IsZero() { t.Fatalf("a reading of before read as %+v: %v", old, err) } if raw, _ := json.Marshal(Reading{V: ReadingVersion}); strings.Contains(string(raw), "first_seen") || strings.Contains(string(raw), "retired") { t.Fatalf("zero fields were written: %s", raw) } if ReadingKey("ace", "pg", "data") != "ace.pg.data" || ReadingsBucket != "disk-load_readings" { t.Fatal("the readings' key or bucket moved") } }