Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
overlord/state: warnings/notices pruning not persisted
Signed-off-by: Harry Pidcock <harry.pidcock@canonical.com>
  • Loading branch information
hpidcock committed Sep 23, 2026
commit 4c117f1a4935faaaa90ba1ee1adce0bbbb6ba067
29 changes: 29 additions & 0 deletions overlord/state/notices_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -701,6 +701,35 @@ func (s *noticesSuite) TestCheckpoint(c *C) {
c.Check(n["key"], Equals, "foo.com/bar")
}

func (s *noticesSuite) TestPruneNoticesCheckpoint(c *C) {
backend := &fakeStateBackend{}
st := state.New(backend)
st.Lock()
old := time.Now().Add(-8 * 24 * time.Hour)
addNotice(c, st, nil, state.ChangeUpdateNotice, "123", &state.AddNoticeOptions{
Time: old,
})
addNotice(c, st, nil, state.ChangeUpdateNotice, "456", nil)
st.Unlock()
c.Assert(backend.checkpoints, HasLen, 1)

st.Lock()
st.Prune(time.Now(), 0, 0, 0)
st.Unlock()
// Pruning the expired notice must mark the state modified so that the
// removal is checkpointed on unlock.
c.Assert(backend.checkpoints, HasLen, 2)

st, err := state.ReadState(nil, bytes.NewReader(backend.checkpoints[1]))
c.Assert(err, IsNil)
st.Lock()
defer st.Unlock()
notices := st.Notices(nil)
c.Assert(notices, HasLen, 1)
n := noticeToMap(c, notices[0])
c.Check(n["key"], Equals, "456")
}

func (s *noticesSuite) TestDeleteExpired(c *C) {
st := state.New(nil)
st.Lock()
Expand Down
2 changes: 2 additions & 0 deletions overlord/state/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,7 @@ func (s *State) pruneWarnings(now time.Time) {
defer s.warningsMu.Unlock()
for k, w := range s.warnings {
if w.ExpiredBefore(now) {
s.writing()
delete(s.warnings, k)
}
}
Expand All @@ -584,6 +585,7 @@ func (s *State) pruneNotices(now time.Time) {
defer s.noticesMu.Unlock()
for k, n := range s.notices {
if n.Expired(now) {
s.writing()
delete(s.notices, k)
}
}
Expand Down
27 changes: 27 additions & 0 deletions overlord/state/warning_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,33 @@ func (stateSuite) TestCheckpoint(c *check.C) {
c.Check(fmt.Sprintf("%q", ws), check.Equals, `["hello"]`)
}

func (stateSuite) TestPruneWarningsCheckpoint(c *check.C) {
b := &fakeStateBackend{}
st := state.New(b)
st.Lock()
st.AddWarning("old", &state.AddWarningOptions{
Time: time.Now().Add(-30 * 24 * time.Hour),
})
st.Warnf("new")
st.Unlock()
c.Assert(b.checkpoints, check.HasLen, 1)

st.Lock()
st.Prune(time.Now(), 0, 0, 0)
st.Unlock()
// Pruning the expired warning must mark the state modified so that the
// removal is checkpointed on unlock.
c.Assert(b.checkpoints, check.HasLen, 2)

st, err := state.ReadState(nil, bytes.NewReader(b.checkpoints[1]))
c.Assert(err, check.IsNil)
st.Lock()
defer st.Unlock()
ws := st.AllWarnings()
c.Assert(ws, check.HasLen, 1)
c.Check(ws[0].String(), check.Equals, "new")
}

func (stateSuite) TestWarningsSummaryReturnsLastLastAdded(c *check.C) {
st := state.New(nil)
st.Lock()
Expand Down
Loading