package scheduler import ( "testing" "time" ) func TestSchedulerLoopSleepCapsManualPollWithoutForcingAutoRun(t *testing.T) { now := time.Date(2026, 5, 20, 10, 0, 0, 0, time.UTC) nextAutoAt := now.Add(time.Minute) got := schedulerLoopSleep(now, nextAutoAt) if got != schedulerManualPollInterval { t.Fatalf("schedulerLoopSleep() = %s, want %s", got, schedulerManualPollInterval) } } func TestNextIntervalAutoAtUsesLastRunOnInitialStart(t *testing.T) { now := time.Date(2026, 5, 20, 10, 0, 0, 0, time.UTC) last := now.Add(-time.Minute) got := nextIntervalAutoAt(now, 5*time.Minute, true, &last) want := last.Add(5 * time.Minute) if !got.Equal(want) { t.Fatalf("nextIntervalAutoAt() = %s, want %s", got, want) } } func TestNextIntervalAutoAtRunsImmediatelyWhenOverdue(t *testing.T) { now := time.Date(2026, 5, 20, 10, 0, 0, 0, time.UTC) last := now.Add(-10 * time.Minute) got := nextIntervalAutoAt(now, 5*time.Minute, true, &last) if !got.Equal(now) { t.Fatalf("nextIntervalAutoAt() = %s, want %s", got, now) } } func TestNextIntervalAutoAtSchedulesAfterCurrentCompletion(t *testing.T) { now := time.Date(2026, 5, 20, 10, 0, 0, 0, time.UTC) got := nextIntervalAutoAt(now, 5*time.Minute, false, nil) want := now.Add(5 * time.Minute) if !got.Equal(want) { t.Fatalf("nextIntervalAutoAt() = %s, want %s", got, want) } } func TestIsEmptySuccessRunRequiresConfiguredZeroMetrics(t *testing.T) { stats := map[string]any{ "hydrated_count": 0, "claimed_count": 0, } config := map[string]any{ "suppress_empty_success_runs": true, "empty_success_metric_keys": []any{"hydrated_count", "claimed_count"}, } if !isEmptySuccessRun(stats, config) { t.Fatal("expected empty success run to be suppressed") } } func TestIsEmptySuccessRunKeepsRunsWithOutput(t *testing.T) { stats := map[string]any{ "recoverable_count": 1, "republished_count": 0, } config := map[string]any{ "suppress_empty_success_runs": true, "empty_success_metric_keys": []any{"recoverable_count", "republished_count"}, } if isEmptySuccessRun(stats, config) { t.Fatal("expected non-empty success run to be retained") } } func TestShouldSuppressEmptySuccessRunOnlyForAutoNonDryRun(t *testing.T) { config := map[string]any{"suppress_empty_success_runs": true} if !shouldSuppressEmptySuccessRun("auto", false, config) { t.Fatal("expected auto non-dry-run to allow suppression") } if shouldSuppressEmptySuccessRun("manual", false, config) { t.Fatal("manual runs must not be suppressed") } if shouldSuppressEmptySuccessRun("auto", true, config) { t.Fatal("dry runs must not be suppressed") } }