package windsurf import ( "testing" "time" ) func TestComputeColdThreshold(t *testing.T) { cfg := ColdThresholdConfig{ Base: 15 * time.Second, PerKChar: 6 * time.Second, Max: 90 * time.Second, } tests := []struct { name string inputChars int upstreamCap time.Duration want time.Duration }{ {"empty prompt → base", 0, 0, 15 * time.Second}, {"under 1k → still base", 999, 0, 15 * time.Second}, {"1k → base + per-k", 1000, 0, 21 * time.Second}, {"5k → base + 5*per-k", 5000, 0, 45 * time.Second}, {"50k → base + 50*per-k clamped to max", 50000, 0, 90 * time.Second}, {"100k → max", 100000, 0, 90 * time.Second}, {"upstreamCap below max wins", 50000, 60 * time.Second, 60 * time.Second}, {"upstreamCap above max no-op", 50000, 200 * time.Second, 90 * time.Second}, {"negative input treated as 0", -100, 0, 15 * time.Second}, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { got := ComputeColdThreshold(cfg, tc.inputChars, tc.upstreamCap) if got != tc.want { t.Fatalf("got %v, want %v", got, tc.want) } }) } } func TestAdaptiveColdThreshold_DefaultsHonorEnv(t *testing.T) { // Note: DefaultColdThresholdConfig caches via sync.Once, so this test // exercises the public path but cannot assert overridden values without // resetting the singleton. We verify the function returns a sensible // value for representative inputs. got := AdaptiveColdThreshold(5000, 200*time.Second) if got <= 0 { t.Fatalf("expected positive threshold, got %v", got) } if got > 200*time.Second { t.Fatalf("expected <= upstreamCap, got %v", got) } } func TestComputeColdThreshold_PreservesLegacyDefaults(t *testing.T) { // Regression: pre-PR-2 behaviour used base=30s, perKChar=5s/1500 chars, // cap=180s. New defaults (base=30s, perKChar=5s/1000 chars, cap=90s) // must NOT shorten timeouts for sub-12k inputs that already worked. cfg := ColdThresholdConfig{Base: 30 * time.Second, PerKChar: 5 * time.Second, Max: 90 * time.Second} for _, chars := range []int{0, 500, 1500, 6000, 12000} { got := ComputeColdThreshold(cfg, chars, 180*time.Second) legacy := 30*time.Second + time.Duration(chars/1500)*5*time.Second if legacy > 180*time.Second { legacy = 180 * time.Second } if got < legacy { t.Fatalf("chars=%d: new=%v shorter than legacy=%v", chars, got, legacy) } } } func TestComputeColdThreshold_OverflowGuard(t *testing.T) { // Without the overflow guard, inputChars near math.MaxInt would make // the duration multiplication wrap negative, returning a "stalled // immediately" timeout. Verify the result is always >= Base and clamped // to Max, never negative. cfg := ColdThresholdConfig{Base: 15 * time.Second, PerKChar: 6 * time.Second, Max: 90 * time.Second} for _, chars := range []int{1 << 31, 1 << 40, 1<<63 - 1} { got := ComputeColdThreshold(cfg, chars, 200*time.Second) if got <= 0 { t.Fatalf("chars=%d: expected positive duration, got %v", chars, got) } if got != cfg.Max { t.Fatalf("chars=%d: expected clamped to Max=%v, got %v", chars, cfg.Max, got) } } }