github.com/lingyao2333/mo-zero@v1.4.1/core/limit/tokenlimit_test.go (about) 1 package limit 2 3 import ( 4 "context" 5 "testing" 6 "time" 7 8 "github.com/alicebob/miniredis/v2" 9 "github.com/lingyao2333/mo-zero/core/logx" 10 "github.com/lingyao2333/mo-zero/core/stores/redis" 11 "github.com/lingyao2333/mo-zero/core/stores/redis/redistest" 12 "github.com/stretchr/testify/assert" 13 ) 14 15 func init() { 16 logx.Disable() 17 } 18 19 func TestTokenLimit_WithCtx(t *testing.T) { 20 s, err := miniredis.Run() 21 assert.Nil(t, err) 22 23 const ( 24 total = 100 25 rate = 5 26 burst = 10 27 ) 28 l := NewTokenLimiter(rate, burst, redis.New(s.Addr()), "tokenlimit") 29 defer s.Close() 30 31 ctx, cancel := context.WithCancel(context.Background()) 32 ok := l.AllowCtx(ctx) 33 assert.True(t, ok) 34 35 cancel() 36 for i := 0; i < total; i++ { 37 ok := l.AllowCtx(ctx) 38 assert.False(t, ok) 39 assert.False(t, l.monitorStarted) 40 } 41 } 42 43 func TestTokenLimit_Rescue(t *testing.T) { 44 s, err := miniredis.Run() 45 assert.Nil(t, err) 46 47 const ( 48 total = 100 49 rate = 5 50 burst = 10 51 ) 52 l := NewTokenLimiter(rate, burst, redis.New(s.Addr()), "tokenlimit") 53 s.Close() 54 55 var allowed int 56 for i := 0; i < total; i++ { 57 time.Sleep(time.Second / time.Duration(total)) 58 if i == total>>1 { 59 assert.Nil(t, s.Restart()) 60 } 61 if l.Allow() { 62 allowed++ 63 } 64 65 // make sure start monitor more than once doesn't matter 66 l.startMonitor() 67 } 68 69 assert.True(t, allowed >= burst+rate) 70 } 71 72 func TestTokenLimit_Take(t *testing.T) { 73 store, clean, err := redistest.CreateRedis() 74 assert.Nil(t, err) 75 defer clean() 76 77 const ( 78 total = 100 79 rate = 5 80 burst = 10 81 ) 82 l := NewTokenLimiter(rate, burst, store, "tokenlimit") 83 var allowed int 84 for i := 0; i < total; i++ { 85 time.Sleep(time.Second / time.Duration(total)) 86 if l.Allow() { 87 allowed++ 88 } 89 } 90 91 assert.True(t, allowed >= burst+rate) 92 } 93 94 func TestTokenLimit_TakeBurst(t *testing.T) { 95 store, clean, err := redistest.CreateRedis() 96 assert.Nil(t, err) 97 defer clean() 98 99 const ( 100 total = 100 101 rate = 5 102 burst = 10 103 ) 104 l := NewTokenLimiter(rate, burst, store, "tokenlimit") 105 var allowed int 106 for i := 0; i < total; i++ { 107 if l.Allow() { 108 allowed++ 109 } 110 } 111 112 assert.True(t, allowed >= burst) 113 }