github.com/m3db/m3@v1.5.1-0.20231129193456-75a402aa583b/src/aggregator/rate/limiter_test.go (about) 1 // Copyright (c) 2017 Uber Technologies, Inc. 2 // 3 // Permission is hereby granted, free of charge, to any person obtaining a copy 4 // of this software and associated documentation files (the "Software"), to deal 5 // in the Software without restriction, including without limitation the rights 6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 // copies of the Software, and to permit persons to whom the Software is 8 // furnished to do so, subject to the following conditions: 9 // 10 // The above copyright notice and this permission notice shall be included in 11 // all copies or substantial portions of the Software. 12 // 13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 // THE SOFTWARE. 20 21 package rate 22 23 import ( 24 "math" 25 "testing" 26 "time" 27 28 "github.com/stretchr/testify/require" 29 30 xtime "github.com/m3db/m3/src/x/time" 31 ) 32 33 func xnow() xtime.UnixNano { 34 return xtime.ToUnixNano(time.Now().Truncate(time.Second)) 35 } 36 37 func BenchmarkLimiter(b *testing.B) { 38 var ( 39 allowedPerSecond int64 = 100 40 now = xnow() 41 limiter = NewLimiter(allowedPerSecond) 42 ) 43 44 b.RunParallel(func(pb *testing.PB) { 45 for pb.Next() { 46 var allowed bool 47 for i := int64(0); i <= allowedPerSecond+1; i++ { 48 allowed = limiter.IsAllowed(1, now) 49 } 50 51 if allowed { 52 b.Fatalf("expected limit to be hit") 53 } 54 } 55 }) 56 require.Equal(b, allowedPerSecond, limiter.Limit()) 57 } 58 59 func TestLimiterLimit(t *testing.T) { 60 var allowedPerSecond int64 = 10 61 62 limiter := NewLimiter(allowedPerSecond) 63 require.Equal(t, allowedPerSecond, limiter.Limit()) 64 } 65 66 func TestLimiterIsAllowed(t *testing.T) { 67 var ( 68 allowedPerSecond int64 = 10 69 now = xnow() 70 ) 71 72 limiter := NewLimiter(allowedPerSecond) 73 require.True(t, limiter.IsAllowed(5, now)) 74 for i := 0; i < 5; i++ { 75 now += xtime.UnixNano(100 * time.Millisecond) 76 require.True(t, limiter.IsAllowed(1, now)) 77 } 78 require.False(t, limiter.IsAllowed(1, now)) 79 80 // Advance time to the next second and confirm the quota is reset. 81 now += xtime.UnixNano(time.Second) 82 require.True(t, limiter.IsAllowed(5, now)) 83 } 84 85 func TestLimiterUnlimited(t *testing.T) { 86 var ( 87 unlimitedLimit int64 = 0 88 now = xnow() 89 ) 90 91 limiter := NewLimiter(unlimitedLimit) 92 require.True(t, limiter.IsAllowed(math.MaxInt64, now)) 93 94 limiter.Reset(1) 95 require.False(t, limiter.IsAllowed(2, now)) 96 } 97 98 func TestLimiterReset(t *testing.T) { 99 var ( 100 allowedPerSecond int64 = 10 101 now = xnow() 102 ) 103 104 limiter := NewLimiter(allowedPerSecond) 105 require.False(t, limiter.IsAllowed(20, now)) 106 107 // Resetting to a higher limit and confirm all requests are allowed. 108 limiter.Reset(20) 109 require.True(t, limiter.IsAllowed(20, now)) 110 }