Files
viettranx 3b4004946e chore: apply go fix syntax upgrades (min/max, switch patterns)
Apply Go 1.21+ min/max builtins and improved switch pattern matching
across test files and utilities. No functional changes.
2026-04-15 11:24:57 +07:00

109 lines
3.0 KiB
Go

package gateway
import (
"testing"
)
// TestRateLimiter_DisabledWhenZeroRPM verifies that rpm=0 means always-allow.
func TestRateLimiter_DisabledWhenZeroRPM(t *testing.T) {
rl := NewRateLimiter(0, 5)
if rl.Enabled() {
t.Fatal("expected disabled when rpm=0")
}
for range 100 {
if !rl.Allow("key") {
t.Fatal("expected allow when disabled")
}
}
}
// TestRateLimiter_DisabledWhenNegativeRPM verifies that rpm<0 means always-allow.
func TestRateLimiter_DisabledWhenNegativeRPM(t *testing.T) {
rl := NewRateLimiter(-1, 5)
if rl.Enabled() {
t.Fatal("expected disabled when rpm<0")
}
if !rl.Allow("key") {
t.Fatal("expected allow when disabled")
}
}
// TestRateLimiter_EnabledWhenPositiveRPM verifies Enabled() returns true for rpm>0.
func TestRateLimiter_EnabledWhenPositiveRPM(t *testing.T) {
rl := NewRateLimiter(60, 5)
if !rl.Enabled() {
t.Fatal("expected enabled when rpm>0")
}
}
// TestRateLimiter_BurstAllowed verifies that up to burst requests pass immediately.
func TestRateLimiter_BurstAllowed(t *testing.T) {
burst := 3
// 1 RPM so refill is negligible during burst; burst=3 so first 3 should pass.
rl := NewRateLimiter(1, burst)
key := "test-burst"
allowed := 0
for range burst {
if rl.Allow(key) {
allowed++
}
}
if allowed != burst {
t.Errorf("expected %d burst-allowed requests, got %d", burst, allowed)
}
}
// TestRateLimiter_BlocksAfterBurst verifies that requests beyond burst are blocked.
func TestRateLimiter_BlocksAfterBurst(t *testing.T) {
// 1 RPM, burst=2 → 2 tokens available, 3rd request in same instant is blocked.
rl := NewRateLimiter(1, 2)
key := "test-block"
// Drain the burst
rl.Allow(key)
rl.Allow(key)
// Next request should be rate-limited
if rl.Allow(key) {
t.Error("expected request to be rate-limited after burst exhausted")
}
}
// TestRateLimiter_PerKeyIsolation verifies that different keys have independent limiters.
func TestRateLimiter_PerKeyIsolation(t *testing.T) {
// Very small RPM with burst=1 so each key gets exactly 1 request before blocking.
rl := NewRateLimiter(1, 1)
key1, key2 := "user1", "user2"
// Both keys should pass their first request.
if !rl.Allow(key1) {
t.Error("key1 first request should be allowed")
}
if !rl.Allow(key2) {
t.Error("key2 first request should be allowed (independent from key1)")
}
// Both should now be blocked.
if rl.Allow(key1) {
t.Error("key1 second request should be rate-limited")
}
if rl.Allow(key2) {
t.Error("key2 second request should be rate-limited")
}
}
// TestRateLimiter_DefaultBurstWhenZero verifies that burst<=0 defaults to 5.
func TestRateLimiter_DefaultBurstWhenZero(t *testing.T) {
// burst=0 → default to 5; rpm=600 so refill is fast but we test burst size
rl := NewRateLimiter(600, 0)
key := "burst-default"
// Should be able to consume at least 5 tokens from the default burst.
allowed := 0
for range 5 {
if rl.Allow(key) {
allowed++
}
}
if allowed < 5 {
t.Errorf("expected at least 5 burst requests with default burst, got %d", allowed)
}
}