diff options
| author | Paul Buetow <paul@buetow.org> | 2026-03-11 18:49:14 +0200 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-03-11 18:49:14 +0200 |
| commit | ad84bcb992ba0552d582f8a6d53ac330f799a955 (patch) | |
| tree | 2c3d386e090a8a52a45f52b0b424abb4143c0062 /internal/cli/throttle_test.go | |
| parent | 0011f18e8494a4e57dc277b826d56c0a1df041ce (diff) | |
feat(sync): enforce daily repo sync intervals
Diffstat (limited to 'internal/cli/throttle_test.go')
| -rw-r--r-- | internal/cli/throttle_test.go | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/internal/cli/throttle_test.go b/internal/cli/throttle_test.go new file mode 100644 index 0000000..6833fe4 --- /dev/null +++ b/internal/cli/throttle_test.go @@ -0,0 +1,108 @@ +package cli + +import ( + "strings" + "testing" + "time" + + "codeberg.org/snonux/gitsyncer/internal/state" +) + +func TestEvaluateSyncPolicy_SkipsRepoSyncedWithinDay(t *testing.T) { + st := &state.State{} + st.SetLastRepoSync("repo", time.Now().Add(-23*time.Hour)) + + decision := evaluateSyncPolicy("repo", st, false, false, false) + + if !decision.Skip { + t.Fatal("expected repo synced within 24 hours to be skipped") + } + if !strings.Contains(decision.Message, "Use --force to override.") { + t.Fatalf("expected force override hint, got %q", decision.Message) + } +} + +func TestEvaluateSyncPolicy_AllowsRepoAfterDailyWindow(t *testing.T) { + st := &state.State{} + st.SetLastRepoSync("repo", time.Now().Add(-25*time.Hour)) + + decision := evaluateSyncPolicy("repo", st, false, false, false) + + if decision.Skip { + t.Fatalf("expected repo synced more than 24 hours ago to proceed, got %q", decision.Message) + } +} + +func TestEvaluateSyncPolicy_ForceBypassesDailyAndThrottleLimits(t *testing.T) { + t.Setenv("HOME", t.TempDir()) + + st := &state.State{} + now := time.Now() + st.SetRepoSync("repo", now.Add(-1*time.Hour), now.Add(30*24*time.Hour)) + + decision := evaluateSyncPolicy("repo", st, false, true, true) + + if decision.Skip { + t.Fatalf("expected --force to bypass sync limits, got %q", decision.Message) + } + if decision.SetNextAllowed { + t.Fatal("did not expect --force to request throttle-window persistence") + } +} + +func TestEvaluateSyncPolicy_ThrottleSetsWindowWhenRepoIsIdle(t *testing.T) { + t.Setenv("HOME", t.TempDir()) + + start := time.Now() + decision := evaluateSyncPolicy("repo", &state.State{}, false, false, true) + end := time.Now() + + if !decision.Skip { + t.Fatal("expected idle repo to be skipped when throttle is enabled") + } + if !decision.SetNextAllowed { + t.Fatal("expected throttle evaluation to request a persisted next-allowed time") + } + + minAllowed := start.Add(throttleMinDays * 24 * time.Hour) + maxAllowed := end.Add(throttleMaxDays*24*time.Hour + time.Minute) + if decision.NextAllowed.Before(minAllowed) || decision.NextAllowed.After(maxAllowed) { + t.Fatalf("expected throttle window between %s and %s, got %s", minAllowed, maxAllowed, decision.NextAllowed) + } +} + +func TestRecordRepoSync_ClearsThrottleWindowWhenThrottleDisabled(t *testing.T) { + st := &state.State{} + st.SetRepoSync("repo", time.Now().Add(-72*time.Hour), time.Now().Add(72*time.Hour)) + + recordRepoSync("repo", st, false) + + if st.GetLastRepoSync("repo").IsZero() { + t.Fatal("expected last sync time to be recorded") + } + if !st.GetNextRepoSyncAllowed("repo").IsZero() { + t.Fatal("expected throttle window to be cleared when throttle is disabled") + } +} + +func TestRecordRepoSync_SetsThrottleWindowWhenThrottleEnabled(t *testing.T) { + st := &state.State{} + + recordRepoSync("repo", st, true) + + lastSync := st.GetLastRepoSync("repo") + if lastSync.IsZero() { + t.Fatal("expected last sync time to be recorded") + } + + nextAllowed := st.GetNextRepoSyncAllowed("repo") + if nextAllowed.IsZero() { + t.Fatal("expected throttle window to be recorded") + } + + minAllowed := lastSync.Add(throttleMinDays * 24 * time.Hour) + maxAllowed := lastSync.Add(throttleMaxDays*24*time.Hour + time.Minute) + if nextAllowed.Before(minAllowed) || nextAllowed.After(maxAllowed) { + t.Fatalf("expected throttle window between %s and %s, got %s", minAllowed, maxAllowed, nextAllowed) + } +} |
