go.temporal.io/server@v1.23.0/common/quotas/delayed_request_rate_limiter_test.go (about) 1 // The MIT License 2 // 3 // Copyright (c) 2020 Temporal Technologies Inc. All rights reserved. 4 // 5 // Copyright (c) 2020 Uber Technologies, Inc. 6 // 7 // Permission is hereby granted, free of charge, to any person obtaining a copy 8 // of this software and associated documentation files (the "Software"), to deal 9 // in the Software without restriction, including without limitation the rights 10 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 // copies of the Software, and to permit persons to whom the Software is 12 // furnished to do so, subject to the following conditions: 13 // 14 // The above copyright notice and this permission notice shall be included in 15 // all copies or substantial portions of the Software. 16 // 17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 // THE SOFTWARE. 24 25 package quotas_test 26 27 import ( 28 "testing" 29 "time" 30 31 "github.com/stretchr/testify/assert" 32 "github.com/stretchr/testify/require" 33 "go.temporal.io/server/common/clock" 34 "go.temporal.io/server/common/quotas" 35 ) 36 37 // disallowingRateLimiter is a rate limiter whose Allow method always returns false. 38 type disallowingRateLimiter struct { 39 // RequestRateLimiter is an embedded field so that disallowingRateLimiter implements that interface. It doesn't 40 // actually delegate to this rate limiter, and this field should be left nil. 41 quotas.RequestRateLimiter 42 } 43 44 func (rl disallowingRateLimiter) Allow(time.Time, quotas.Request) bool { 45 return false 46 } 47 48 func TestNewDelayedRequestRateLimiter_NegativeDelay(t *testing.T) { 49 t.Parallel() 50 51 _, err := quotas.NewDelayedRequestRateLimiter( 52 quotas.NoopRequestRateLimiter, 53 -time.Nanosecond, 54 clock.NewRealTimeSource(), 55 ) 56 assert.ErrorIs(t, err, quotas.ErrNegativeDelay) 57 } 58 59 func TestNewDelayedRequestRateLimiter_ZeroDelay(t *testing.T) { 60 t.Parallel() 61 62 timeSource := clock.NewEventTimeSource() 63 drl, err := quotas.NewDelayedRequestRateLimiter(disallowingRateLimiter{}, 0, timeSource) 64 require.NoError(t, err) 65 assert.False(t, drl.Allow(time.Time{}, quotas.Request{}), "expected Allow to return false because we "+ 66 "immediately switched to the disallowing rate limiter due to the zero delay") 67 } 68 69 func TestDelayedRequestRateLimiter_Allow(t *testing.T) { 70 t.Parallel() 71 72 timeSource := clock.NewEventTimeSource() 73 drl, err := quotas.NewDelayedRequestRateLimiter(disallowingRateLimiter{}, time.Second, timeSource) 74 require.NoError(t, err) 75 timeSource.Advance(time.Second - time.Nanosecond) 76 assert.True(t, drl.Allow(time.Time{}, quotas.Request{}), "expected Allow to return true because the "+ 77 "timer hasn't expired yet") 78 timeSource.Advance(time.Nanosecond) 79 assert.False(t, drl.Allow(time.Time{}, quotas.Request{}), "expected Allow to return false because the "+ 80 "timer expired, and we switched to the disallowing rate limiter") 81 } 82 83 func TestDelayedRequestRateLimiter_Cancel(t *testing.T) { 84 t.Parallel() 85 86 timeSource := clock.NewEventTimeSource() 87 drl, err := quotas.NewDelayedRequestRateLimiter(disallowingRateLimiter{}, time.Second, timeSource) 88 require.NoError(t, err) 89 timeSource.Advance(time.Second - time.Nanosecond) 90 assert.True(t, drl.Cancel(), "expected Cancel to return true because the timer was stopped before it "+ 91 "expired") 92 timeSource.Advance(time.Nanosecond) 93 assert.True(t, drl.Allow(time.Time{}, quotas.Request{}), "expected Allow to return true because the "+ 94 "timer was stopped before it could expire") 95 assert.False(t, drl.Cancel(), "expected Cancel to return false because the timer was already stopped") 96 }