1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: Apache-2.0
17 var _ = Suite(&limiterSuite{})
19 type limiterSuite struct{}
21 func (*limiterSuite) TestInitialLimit(c *C) {
22 ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(time.Minute))
24 rl := requestLimiter{}
27 wg.Add(int(requestLimiterInitialLimit))
28 for i := int64(0); i < requestLimiterInitialLimit; i++ {
35 c.Check(rl.current, Equals, requestLimiterInitialLimit)
36 wg.Add(int(requestLimiterInitialLimit))
37 for i := int64(0); i < requestLimiterInitialLimit; i++ {
44 c.Check(rl.current, Equals, int64(0))
47 func (*limiterSuite) TestCancelWhileWaitingForAcquire(c *C) {
48 ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(time.Minute))
50 rl := requestLimiter{}
54 ctxShort, cancel := context.WithDeadline(ctx, time.Now().Add(time.Millisecond))
57 c.Check(rl.current, Equals, int64(2))
58 c.Check(ctxShort.Err(), NotNil)
61 c.Check(rl.current, Equals, int64(0))
64 func (*limiterSuite) TestReducedLimitAndQuietPeriod(c *C) {
65 ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(time.Minute))
67 rl := requestLimiter{}
69 // Use a short quiet period to make tests faster
70 defer func(orig time.Duration) { requestLimiterQuietPeriod = orig }(requestLimiterQuietPeriod)
71 requestLimiterQuietPeriod = time.Second / 10
73 for i := 0; i < 5; i++ {
76 rl.Report(&http.Response{StatusCode: http.StatusServiceUnavailable}, nil)
77 c.Check(rl.limit, Equals, requestLimiterInitialLimit/2)
78 for i := 0; i < 5; i++ {
82 // Even with all slots released, we can't Acquire in the quiet
85 // (a) If our context expires before the end of the quiet
86 // period, we get back DeadlineExceeded -- without waiting for
87 // the end of the quiet period.
89 ctxShort, cancel := context.WithDeadline(ctx, time.Now().Add(requestLimiterQuietPeriod/10))
92 c.Check(ctxShort.Err(), Equals, context.DeadlineExceeded)
93 c.Check(time.Since(acquire) < requestLimiterQuietPeriod/2, Equals, true)
94 c.Check(rl.quietUntil.Sub(time.Now()) > requestLimiterQuietPeriod/2, Equals, true)
97 // (b) If our context does not expire first, Acquire waits for
98 // the end of the quiet period.
99 ctxLong, cancel := context.WithDeadline(ctx, time.Now().Add(requestLimiterQuietPeriod*2))
103 c.Check(time.Since(acquire) > requestLimiterQuietPeriod/10, Equals, true)
104 c.Check(time.Since(acquire) < requestLimiterQuietPeriod, Equals, true)
105 c.Check(ctxLong.Err(), IsNil)
108 // OK to call Report() with nil Response and non-nil error.
109 rl.Report(nil, errors.New("network error"))