tokenlimit_test.go 2.0 KB

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