diff options
Diffstat (limited to 'internal/stats')
| -rw-r--r-- | internal/stats/stats.go | 8 | ||||
| -rw-r--r-- | internal/stats/stats_test.go | 9 |
2 files changed, 14 insertions, 3 deletions
diff --git a/internal/stats/stats.go b/internal/stats/stats.go index d79025a..bd91e20 100644 --- a/internal/stats/stats.go +++ b/internal/stats/stats.go @@ -29,6 +29,10 @@ var windowSeconds int64 = int64(defaultWindow.Seconds()) var errLockWouldBlock = errors.New("stats: lock would block") +// nowFunc is the clock source for event timestamps and pruning cutoffs. +// Replaced in tests to control time without sleeping. +var nowFunc = time.Now + // SetWindow sets the sliding window used for pruning and aggregation. func SetWindow(d time.Duration) { if d < time.Second { @@ -117,7 +121,7 @@ func Update(ctx context.Context, provider, model string, sentBytes, recvBytes in path := filepath.Join(dir, fileName) sf := readStatsFile(path) - now := time.Now() + now := nowFunc() win := Window() sf.WindowSeconds = int(win.Seconds()) sf.Events = append(sf.Events, Event{ @@ -260,7 +264,7 @@ func TakeSnapshot() (Snapshot, error) { if win <= 0 { win = Window() } - cutoff := time.Now().Add(-win) + cutoff := nowFunc().Add(-win) snap := Snapshot{Providers: make(map[string]ProviderEntry), Window: win} for _, ev := range sf.Events { if ev.TS.Before(cutoff) { diff --git a/internal/stats/stats_test.go b/internal/stats/stats_test.go index a9b3d22..47e3068 100644 --- a/internal/stats/stats_test.go +++ b/internal/stats/stats_test.go @@ -33,10 +33,17 @@ func TestUpdate_PrunesOld_ByWindow(t *testing.T) { t.Setenv("XDG_CACHE_HOME", t.TempDir()) SetWindow(2 * time.Second) ctx := context.Background() + + // Inject a fake clock so we can advance time without sleeping. + fakeNow := time.Now() + nowFunc = func() time.Time { return fakeNow } + defer func() { nowFunc = time.Now }() + if err := Update(ctx, "p", "m", 1, 1); err != nil { t.Fatal(err) } - time.Sleep(2200 * time.Millisecond) + // Advance fake time past the 2-second window so the first event is pruned. + fakeNow = fakeNow.Add(3 * time.Second) if err := Update(ctx, "p", "m", 2, 2); err != nil { t.Fatal(err) } |
