package main import ( "go/ast" "go/parser" "go/token" "testing" "time" ) // R-363 / R-547: the fill watcher ran once a day (plus once after start), so a filesystem that filled // right after the 03:30 run went unannounced for ~24 h, and a disk held at 96 % for ten minutes raised // nothing. The consequence pinned here: main.go registers the SAME fillWatcher.Check on a periodic // job whose interval is no longer than the shortest measured silent window (10 min), so any such // window contains a check. Edge-triggering (no repeat mails at a faster cadence) is pinned in // internal/fillwatch (TestWarnsOnceThenIsSilent, TestEdgeStateSurvivesARestart). func TestFillWatchRunsOnAnInterval(t *testing.T) { const measuredSilentWindow = 10 * time.Minute // R-547, chaos night 2026-09-17 if fillWatchInterval <= 0 || fillWatchInterval > measuredSilentWindow { t.Errorf("fillWatchInterval = %s; it must be >0 and <= %s, or a fill window like R-547's can pass unseen", fillWatchInterval, measuredSilentWindow) } fset := token.NewFileSet() f, err := parser.ParseFile(fset, "main.go", nil, 0) if err != nil { t.Fatal(err) } periodic := 0 ast.Inspect(f, func(n ast.Node) bool { call, ok := n.(*ast.CallExpr) if !ok { return true } sel, ok := call.Fun.(*ast.SelectorExpr) if !ok || sel.Sel.Name != "Every" || len(call.Args) != 3 { return true } iv, ok := call.Args[1].(*ast.Ident) if !ok || iv.Name != "fillWatchInterval" { return true } // The job body must call fillWatcher.Check — the same edge-triggered check, not a new one. ast.Inspect(call.Args[2], func(m ast.Node) bool { if c, ok := m.(*ast.CallExpr); ok { if s, ok := c.Fun.(*ast.SelectorExpr); ok && s.Sel.Name == "Check" { if x, ok := s.X.(*ast.Ident); ok && x.Name == "fillWatcher" { periodic++ } } } return true }) return true }) if periodic != 1 { t.Errorf("R-363: main.go registers fillWatcher.Check on a periodic (sched.Every, fillWatchInterval) job %d times, want 1 — without it the fill check is daily only", periodic) } }