hi-server/pkg/limit/tokenlimit_test.go
2025-10-10 07:13:36 -07:00

81 lines
1.5 KiB
Go

package limit
import (
"context"
"testing"
"time"
"github.com/redis/go-redis/v9"
"github.com/alicebob/miniredis/v2"
"github.com/stretchr/testify/assert"
)
func TestTokenLimit_WithCtx(t *testing.T) {
const (
total = 100
rate = 5
burst = 10
)
store, _ := CreateRedisWithClean(t)
l := NewTokenLimiter(rate, burst, store, "tokenlimit")
ctx, cancel := context.WithCancel(context.Background())
ok := l.AllowCtx(ctx)
assert.True(t, ok)
cancel()
for i := 0; i < total; i++ {
ok := l.AllowCtx(ctx)
assert.False(t, ok)
assert.False(t, l.monitorStarted)
}
}
func TestTokenLimit_Take(t *testing.T) {
store, _ := CreateRedisWithClean(t)
const (
total = 100
rate = 5
burst = 10
)
l := NewTokenLimiter(rate, burst, store, "tokenlimit")
var allowed int
for i := 0; i < total; i++ {
time.Sleep(time.Second / time.Duration(total))
if l.Allow() {
allowed++
}
}
assert.True(t, allowed >= burst+rate)
}
func TestTokenLimit_TakeBurst(t *testing.T) {
store, _ := CreateRedisWithClean(t)
const (
total = 100
rate = 5
burst = 10
)
l := NewTokenLimiter(rate, burst, store, "tokenlimit")
var allowed int
for i := 0; i < total; i++ {
if l.Allow() {
allowed++
}
}
assert.True(t, allowed >= burst)
}
// CreateRedisWithClean returns an in process redis.Redis and a clean function.
func CreateRedisWithClean(t *testing.T) (r *redis.Client, clean func()) {
mr := miniredis.RunT(t)
return redis.NewClient(&redis.Options{
Addr: mr.Addr(),
}), mr.Close
}