@@ -29,39 +29,119 @@ func TestAllow(t *testing.T) {
2929
3030 res , err := l .Allow (ctx , "test_id" , limit )
3131 assert .Nil (t , err )
32- assert .True (t , res .Allowed )
32+ assert .Equal (t , res .Allowed , 1 )
3333 assert .Equal (t , res .Remaining , 9 )
3434 assert .Equal (t , res .RetryAfter , time .Duration (- 1 ))
3535 assert .InDelta (t , res .ResetAfter , 100 * time .Millisecond , float64 (10 * time .Millisecond ))
3636
3737 res , err = l .AllowN (ctx , "test_id" , limit , 2 )
3838 assert .Nil (t , err )
39- assert .True (t , res .Allowed )
39+ assert .Equal (t , res .Allowed , 2 )
4040 assert .Equal (t , res .Remaining , 7 )
4141 assert .Equal (t , res .RetryAfter , time .Duration (- 1 ))
4242 assert .InDelta (t , res .ResetAfter , 300 * time .Millisecond , float64 (10 * time .Millisecond ))
4343
44+ res , err = l .AllowN (ctx , "test_id" , limit , 7 )
45+ assert .Nil (t , err )
46+ assert .Equal (t , res .Allowed , 7 )
47+ assert .Equal (t , res .Remaining , 0 )
48+ assert .Equal (t , res .RetryAfter , time .Duration (- 1 ))
49+ assert .InDelta (t , res .ResetAfter , 999 * time .Millisecond , float64 (10 * time .Millisecond ))
50+
4451 res , err = l .AllowN (ctx , "test_id" , limit , 1000 )
4552 assert .Nil (t , err )
46- assert .False (t , res .Allowed )
53+ assert .Equal (t , res .Allowed , 0 )
4754 assert .Equal (t , res .Remaining , 0 )
4855 assert .InDelta (t , res .RetryAfter , 99 * time .Second , float64 (time .Second ))
56+ assert .InDelta (t , res .ResetAfter , 999 * time .Millisecond , float64 (10 * time .Millisecond ))
57+ }
58+
59+ func TestAllowAtMostN (t * testing.T ) {
60+ ctx := context .Background ()
61+
62+ l := rateLimiter ()
63+ limit := redis_rate .PerSecond (10 )
64+
65+ res , err := l .Allow (ctx , "test_id" , limit )
66+ assert .Nil (t , err )
67+ assert .Equal (t , res .Allowed , 1 )
68+ assert .Equal (t , res .Remaining , 9 )
69+ assert .Equal (t , res .RetryAfter , time .Duration (- 1 ))
70+ assert .InDelta (t , res .ResetAfter , 100 * time .Millisecond , float64 (10 * time .Millisecond ))
71+
72+ res , err = l .AllowAtMostN (ctx , "test_id" , limit , 2 )
73+ assert .Nil (t , err )
74+ assert .Equal (t , res .Allowed , 2 )
75+ assert .Equal (t , res .Remaining , 7 )
76+
77+ res , err = l .AllowN (ctx , "test_id" , limit , 0 )
78+ assert .Nil (t , err )
79+ assert .Equal (t , res .Allowed , 0 )
80+ assert .Equal (t , res .Remaining , 7 )
81+ assert .Equal (t , res .RetryAfter , time .Duration (- 1 ))
4982 assert .InDelta (t , res .ResetAfter , 300 * time .Millisecond , float64 (10 * time .Millisecond ))
83+
84+ res , err = l .AllowAtMostN (ctx , "test_id" , limit , 10 )
85+ assert .Nil (t , err )
86+ assert .Equal (t , res .Allowed , 7 )
87+ assert .Equal (t , res .Remaining , 0 )
88+
89+ res , err = l .AllowN (ctx , "test_id" , limit , 0 )
90+ assert .Nil (t , err )
91+ assert .Equal (t , res .Allowed , 0 )
92+ assert .Equal (t , res .Remaining , 0 )
93+ assert .Equal (t , res .RetryAfter , time .Duration (- 1 ))
94+ assert .InDelta (t , res .ResetAfter , 999 * time .Millisecond , float64 (10 * time .Millisecond ))
95+
96+ res , err = l .AllowAtMostN (ctx , "test_id" , limit , 1000 )
97+ assert .Nil (t , err )
98+ assert .Equal (t , res .Allowed , 0 )
99+ assert .Equal (t , res .Remaining , 0 )
100+
101+ res , err = l .AllowN (ctx , "test_id" , limit , 1000 )
102+ assert .Nil (t , err )
103+ assert .Equal (t , res .Allowed , 0 )
104+ assert .Equal (t , res .Remaining , 0 )
105+ assert .InDelta (t , res .RetryAfter , 99 * time .Second , float64 (time .Second ))
106+ assert .InDelta (t , res .ResetAfter , 999 * time .Millisecond , float64 (10 * time .Millisecond ))
50107}
51108
52109func BenchmarkAllow (b * testing.B ) {
53110 ctx := context .Background ()
54111 l := rateLimiter ()
55- limit := redis_rate .PerSecond (10000 )
112+ limit := redis_rate .PerSecond (1e6 )
56113
57114 b .ResetTimer ()
58115
59116 b .RunParallel (func (pb * testing.PB ) {
60117 for pb .Next () {
61- _ , err := l .Allow (ctx , "foo" , limit )
118+ res , err := l .Allow (ctx , "foo" , limit )
62119 if err != nil {
63120 b .Fatal (err )
64121 }
122+ if res .Allowed == 0 {
123+ panic ("not reached" )
124+ }
125+ }
126+ })
127+ }
128+
129+ func BenchmarkAllowAtMostN (b * testing.B ) {
130+ ctx := context .Background ()
131+ l := rateLimiter ()
132+ limit := redis_rate .PerSecond (1e6 )
133+
134+ b .ResetTimer ()
135+
136+ b .RunParallel (func (pb * testing.PB ) {
137+ for pb .Next () {
138+ res , err := l .AllowAtMostN (ctx , "foo" , limit , 1 )
139+ if err != nil {
140+ b .Fatal (err )
141+ }
142+ if res .Allowed == 0 {
143+ panic ("not reached" )
144+ }
65145 }
66146 })
67147}
0 commit comments