rate_test.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480
  1. // Copyright 2015 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. //go:build go1.7
  5. // +build go1.7
  6. package rate
  7. import (
  8. "context"
  9. "math"
  10. "runtime"
  11. "sync"
  12. "sync/atomic"
  13. "testing"
  14. "time"
  15. )
  16. func TestLimit(t *testing.T) {
  17. if Limit(10) == Inf {
  18. t.Errorf("Limit(10) == Inf should be false")
  19. }
  20. }
  21. func closeEnough(a, b Limit) bool {
  22. return (math.Abs(float64(a)/float64(b)) - 1.0) < 1e-9
  23. }
  24. func TestEvery(t *testing.T) {
  25. cases := []struct {
  26. interval time.Duration
  27. lim Limit
  28. }{
  29. {0, Inf},
  30. {-1, Inf},
  31. {1 * time.Nanosecond, Limit(1e9)},
  32. {1 * time.Microsecond, Limit(1e6)},
  33. {1 * time.Millisecond, Limit(1e3)},
  34. {10 * time.Millisecond, Limit(100)},
  35. {100 * time.Millisecond, Limit(10)},
  36. {1 * time.Second, Limit(1)},
  37. {2 * time.Second, Limit(0.5)},
  38. {time.Duration(2.5 * float64(time.Second)), Limit(0.4)},
  39. {4 * time.Second, Limit(0.25)},
  40. {10 * time.Second, Limit(0.1)},
  41. {time.Duration(math.MaxInt64), Limit(1e9 / float64(math.MaxInt64))},
  42. }
  43. for _, tc := range cases {
  44. lim := Every(tc.interval)
  45. if !closeEnough(lim, tc.lim) {
  46. t.Errorf("Every(%v) = %v want %v", tc.interval, lim, tc.lim)
  47. }
  48. }
  49. }
  50. const (
  51. d = 100 * time.Millisecond
  52. )
  53. var (
  54. t0 = time.Now()
  55. t1 = t0.Add(time.Duration(1) * d)
  56. t2 = t0.Add(time.Duration(2) * d)
  57. t3 = t0.Add(time.Duration(3) * d)
  58. t4 = t0.Add(time.Duration(4) * d)
  59. t5 = t0.Add(time.Duration(5) * d)
  60. t9 = t0.Add(time.Duration(9) * d)
  61. )
  62. type allow struct {
  63. t time.Time
  64. n int
  65. ok bool
  66. }
  67. func run(t *testing.T, lim *Limiter, allows []allow) {
  68. for i, allow := range allows {
  69. ok := lim.AllowN(allow.t, allow.n)
  70. if ok != allow.ok {
  71. t.Errorf("step %d: lim.AllowN(%v, %v) = %v want %v",
  72. i, allow.t, allow.n, ok, allow.ok)
  73. }
  74. }
  75. }
  76. func TestLimiterBurst1(t *testing.T) {
  77. run(t, NewLimiter(10, 1), []allow{
  78. {t0, 1, true},
  79. {t0, 1, false},
  80. {t0, 1, false},
  81. {t1, 1, true},
  82. {t1, 1, false},
  83. {t1, 1, false},
  84. {t2, 2, false}, // burst size is 1, so n=2 always fails
  85. {t2, 1, true},
  86. {t2, 1, false},
  87. })
  88. }
  89. func TestLimiterBurst3(t *testing.T) {
  90. run(t, NewLimiter(10, 3), []allow{
  91. {t0, 2, true},
  92. {t0, 2, false},
  93. {t0, 1, true},
  94. {t0, 1, false},
  95. {t1, 4, false},
  96. {t2, 1, true},
  97. {t3, 1, true},
  98. {t4, 1, true},
  99. {t4, 1, true},
  100. {t4, 1, false},
  101. {t4, 1, false},
  102. {t9, 3, true},
  103. {t9, 0, true},
  104. })
  105. }
  106. func TestLimiterJumpBackwards(t *testing.T) {
  107. run(t, NewLimiter(10, 3), []allow{
  108. {t1, 1, true}, // start at t1
  109. {t0, 1, true}, // jump back to t0, two tokens remain
  110. {t0, 1, true},
  111. {t0, 1, false},
  112. {t0, 1, false},
  113. {t1, 1, true}, // got a token
  114. {t1, 1, false},
  115. {t1, 1, false},
  116. {t2, 1, true}, // got another token
  117. {t2, 1, false},
  118. {t2, 1, false},
  119. })
  120. }
  121. // Ensure that tokensFromDuration doesn't produce
  122. // rounding errors by truncating nanoseconds.
  123. // See golang.org/issues/34861.
  124. func TestLimiter_noTruncationErrors(t *testing.T) {
  125. if !NewLimiter(0.7692307692307693, 1).Allow() {
  126. t.Fatal("expected true")
  127. }
  128. }
  129. func TestSimultaneousRequests(t *testing.T) {
  130. const (
  131. limit = 1
  132. burst = 5
  133. numRequests = 15
  134. )
  135. var (
  136. wg sync.WaitGroup
  137. numOK = uint32(0)
  138. )
  139. // Very slow replenishing bucket.
  140. lim := NewLimiter(limit, burst)
  141. // Tries to take a token, atomically updates the counter and decreases the wait
  142. // group counter.
  143. f := func() {
  144. defer wg.Done()
  145. if ok := lim.Allow(); ok {
  146. atomic.AddUint32(&numOK, 1)
  147. }
  148. }
  149. wg.Add(numRequests)
  150. for i := 0; i < numRequests; i++ {
  151. go f()
  152. }
  153. wg.Wait()
  154. if numOK != burst {
  155. t.Errorf("numOK = %d, want %d", numOK, burst)
  156. }
  157. }
  158. func TestLongRunningQPS(t *testing.T) {
  159. if testing.Short() {
  160. t.Skip("skipping in short mode")
  161. }
  162. if runtime.GOOS == "openbsd" {
  163. t.Skip("low resolution time.Sleep invalidates test (golang.org/issue/14183)")
  164. return
  165. }
  166. // The test runs for a few seconds executing many requests and then checks
  167. // that overall number of requests is reasonable.
  168. const (
  169. limit = 100
  170. burst = 100
  171. )
  172. var numOK = int32(0)
  173. lim := NewLimiter(limit, burst)
  174. var wg sync.WaitGroup
  175. f := func() {
  176. if ok := lim.Allow(); ok {
  177. atomic.AddInt32(&numOK, 1)
  178. }
  179. wg.Done()
  180. }
  181. start := time.Now()
  182. end := start.Add(5 * time.Second)
  183. for time.Now().Before(end) {
  184. wg.Add(1)
  185. go f()
  186. // This will still offer ~500 requests per second, but won't consume
  187. // outrageous amount of CPU.
  188. time.Sleep(2 * time.Millisecond)
  189. }
  190. wg.Wait()
  191. elapsed := time.Since(start)
  192. ideal := burst + (limit * float64(elapsed) / float64(time.Second))
  193. // We should never get more requests than allowed.
  194. if want := int32(ideal + 1); numOK > want {
  195. t.Errorf("numOK = %d, want %d (ideal %f)", numOK, want, ideal)
  196. }
  197. // We should get very close to the number of requests allowed.
  198. if want := int32(0.999 * ideal); numOK < want {
  199. t.Errorf("numOK = %d, want %d (ideal %f)", numOK, want, ideal)
  200. }
  201. }
  202. type request struct {
  203. t time.Time
  204. n int
  205. act time.Time
  206. ok bool
  207. }
  208. // dFromDuration converts a duration to a multiple of the global constant d
  209. func dFromDuration(dur time.Duration) int {
  210. // Adding a millisecond to be swallowed by the integer division
  211. // because we don't care about small inaccuracies
  212. return int((dur + time.Millisecond) / d)
  213. }
  214. // dSince returns multiples of d since t0
  215. func dSince(t time.Time) int {
  216. return dFromDuration(t.Sub(t0))
  217. }
  218. func runReserve(t *testing.T, lim *Limiter, req request) *Reservation {
  219. return runReserveMax(t, lim, req, InfDuration)
  220. }
  221. func runReserveMax(t *testing.T, lim *Limiter, req request, maxReserve time.Duration) *Reservation {
  222. r := lim.reserveN(req.t, req.n, maxReserve)
  223. if r.ok && (dSince(r.timeToAct) != dSince(req.act)) || r.ok != req.ok {
  224. t.Errorf("lim.reserveN(t%d, %v, %v) = (t%d, %v) want (t%d, %v)",
  225. dSince(req.t), req.n, maxReserve, dSince(r.timeToAct), r.ok, dSince(req.act), req.ok)
  226. }
  227. return &r
  228. }
  229. func TestSimpleReserve(t *testing.T) {
  230. lim := NewLimiter(10, 2)
  231. runReserve(t, lim, request{t0, 2, t0, true})
  232. runReserve(t, lim, request{t0, 2, t2, true})
  233. runReserve(t, lim, request{t3, 2, t4, true})
  234. }
  235. func TestMix(t *testing.T) {
  236. lim := NewLimiter(10, 2)
  237. runReserve(t, lim, request{t0, 3, t1, false}) // should return false because n > Burst
  238. runReserve(t, lim, request{t0, 2, t0, true})
  239. run(t, lim, []allow{{t1, 2, false}}) // not enough tokens - don't allow
  240. runReserve(t, lim, request{t1, 2, t2, true})
  241. run(t, lim, []allow{{t1, 1, false}}) // negative tokens - don't allow
  242. run(t, lim, []allow{{t3, 1, true}})
  243. }
  244. func TestCancelInvalid(t *testing.T) {
  245. lim := NewLimiter(10, 2)
  246. runReserve(t, lim, request{t0, 2, t0, true})
  247. r := runReserve(t, lim, request{t0, 3, t3, false})
  248. r.CancelAt(t0) // should have no effect
  249. runReserve(t, lim, request{t0, 2, t2, true}) // did not get extra tokens
  250. }
  251. func TestCancelLast(t *testing.T) {
  252. lim := NewLimiter(10, 2)
  253. runReserve(t, lim, request{t0, 2, t0, true})
  254. r := runReserve(t, lim, request{t0, 2, t2, true})
  255. r.CancelAt(t1) // got 2 tokens back
  256. runReserve(t, lim, request{t1, 2, t2, true})
  257. }
  258. func TestCancelTooLate(t *testing.T) {
  259. lim := NewLimiter(10, 2)
  260. runReserve(t, lim, request{t0, 2, t0, true})
  261. r := runReserve(t, lim, request{t0, 2, t2, true})
  262. r.CancelAt(t3) // too late to cancel - should have no effect
  263. runReserve(t, lim, request{t3, 2, t4, true})
  264. }
  265. func TestCancel0Tokens(t *testing.T) {
  266. lim := NewLimiter(10, 2)
  267. runReserve(t, lim, request{t0, 2, t0, true})
  268. r := runReserve(t, lim, request{t0, 1, t1, true})
  269. runReserve(t, lim, request{t0, 1, t2, true})
  270. r.CancelAt(t0) // got 0 tokens back
  271. runReserve(t, lim, request{t0, 1, t3, true})
  272. }
  273. func TestCancel1Token(t *testing.T) {
  274. lim := NewLimiter(10, 2)
  275. runReserve(t, lim, request{t0, 2, t0, true})
  276. r := runReserve(t, lim, request{t0, 2, t2, true})
  277. runReserve(t, lim, request{t0, 1, t3, true})
  278. r.CancelAt(t2) // got 1 token back
  279. runReserve(t, lim, request{t2, 2, t4, true})
  280. }
  281. func TestCancelMulti(t *testing.T) {
  282. lim := NewLimiter(10, 4)
  283. runReserve(t, lim, request{t0, 4, t0, true})
  284. rA := runReserve(t, lim, request{t0, 3, t3, true})
  285. runReserve(t, lim, request{t0, 1, t4, true})
  286. rC := runReserve(t, lim, request{t0, 1, t5, true})
  287. rC.CancelAt(t1) // get 1 token back
  288. rA.CancelAt(t1) // get 2 tokens back, as if C was never reserved
  289. runReserve(t, lim, request{t1, 3, t5, true})
  290. }
  291. func TestReserveJumpBack(t *testing.T) {
  292. lim := NewLimiter(10, 2)
  293. runReserve(t, lim, request{t1, 2, t1, true}) // start at t1
  294. runReserve(t, lim, request{t0, 1, t1, true}) // should violate Limit,Burst
  295. runReserve(t, lim, request{t2, 2, t3, true})
  296. }
  297. func TestReserveJumpBackCancel(t *testing.T) {
  298. lim := NewLimiter(10, 2)
  299. runReserve(t, lim, request{t1, 2, t1, true}) // start at t1
  300. r := runReserve(t, lim, request{t1, 2, t3, true})
  301. runReserve(t, lim, request{t1, 1, t4, true})
  302. r.CancelAt(t0) // cancel at t0, get 1 token back
  303. runReserve(t, lim, request{t1, 2, t4, true}) // should violate Limit,Burst
  304. }
  305. func TestReserveSetLimit(t *testing.T) {
  306. lim := NewLimiter(5, 2)
  307. runReserve(t, lim, request{t0, 2, t0, true})
  308. runReserve(t, lim, request{t0, 2, t4, true})
  309. lim.SetLimitAt(t2, 10)
  310. runReserve(t, lim, request{t2, 1, t4, true}) // violates Limit and Burst
  311. }
  312. func TestReserveSetBurst(t *testing.T) {
  313. lim := NewLimiter(5, 2)
  314. runReserve(t, lim, request{t0, 2, t0, true})
  315. runReserve(t, lim, request{t0, 2, t4, true})
  316. lim.SetBurstAt(t3, 4)
  317. runReserve(t, lim, request{t0, 4, t9, true}) // violates Limit and Burst
  318. }
  319. func TestReserveSetLimitCancel(t *testing.T) {
  320. lim := NewLimiter(5, 2)
  321. runReserve(t, lim, request{t0, 2, t0, true})
  322. r := runReserve(t, lim, request{t0, 2, t4, true})
  323. lim.SetLimitAt(t2, 10)
  324. r.CancelAt(t2) // 2 tokens back
  325. runReserve(t, lim, request{t2, 2, t3, true})
  326. }
  327. func TestReserveMax(t *testing.T) {
  328. lim := NewLimiter(10, 2)
  329. maxT := d
  330. runReserveMax(t, lim, request{t0, 2, t0, true}, maxT)
  331. runReserveMax(t, lim, request{t0, 1, t1, true}, maxT) // reserve for close future
  332. runReserveMax(t, lim, request{t0, 1, t2, false}, maxT) // time to act too far in the future
  333. }
  334. type wait struct {
  335. name string
  336. ctx context.Context
  337. n int
  338. delay int // in multiples of d
  339. nilErr bool
  340. }
  341. func runWait(t *testing.T, lim *Limiter, w wait) {
  342. start := time.Now()
  343. err := lim.WaitN(w.ctx, w.n)
  344. delay := time.Since(start)
  345. if (w.nilErr && err != nil) || (!w.nilErr && err == nil) || w.delay != dFromDuration(delay) {
  346. errString := "<nil>"
  347. if !w.nilErr {
  348. errString = "<non-nil error>"
  349. }
  350. t.Errorf("lim.WaitN(%v, lim, %v) = %v with delay %v ; want %v with delay %v",
  351. w.name, w.n, err, delay, errString, d*time.Duration(w.delay))
  352. }
  353. }
  354. func TestWaitSimple(t *testing.T) {
  355. lim := NewLimiter(10, 3)
  356. ctx, cancel := context.WithCancel(context.Background())
  357. cancel()
  358. runWait(t, lim, wait{"already-cancelled", ctx, 1, 0, false})
  359. runWait(t, lim, wait{"exceed-burst-error", context.Background(), 4, 0, false})
  360. runWait(t, lim, wait{"act-now", context.Background(), 2, 0, true})
  361. runWait(t, lim, wait{"act-later", context.Background(), 3, 2, true})
  362. }
  363. func TestWaitCancel(t *testing.T) {
  364. lim := NewLimiter(10, 3)
  365. ctx, cancel := context.WithCancel(context.Background())
  366. runWait(t, lim, wait{"act-now", ctx, 2, 0, true}) // after this lim.tokens = 1
  367. go func() {
  368. time.Sleep(d)
  369. cancel()
  370. }()
  371. runWait(t, lim, wait{"will-cancel", ctx, 3, 1, false})
  372. // should get 3 tokens back, and have lim.tokens = 2
  373. t.Logf("tokens:%v last:%v lastEvent:%v", lim.tokens, lim.last, lim.lastEvent)
  374. runWait(t, lim, wait{"act-now-after-cancel", context.Background(), 2, 0, true})
  375. }
  376. func TestWaitTimeout(t *testing.T) {
  377. lim := NewLimiter(10, 3)
  378. ctx, cancel := context.WithTimeout(context.Background(), d)
  379. defer cancel()
  380. runWait(t, lim, wait{"act-now", ctx, 2, 0, true})
  381. runWait(t, lim, wait{"w-timeout-err", ctx, 3, 0, false})
  382. }
  383. func TestWaitInf(t *testing.T) {
  384. lim := NewLimiter(Inf, 0)
  385. runWait(t, lim, wait{"exceed-burst-no-error", context.Background(), 3, 0, true})
  386. }
  387. func BenchmarkAllowN(b *testing.B) {
  388. lim := NewLimiter(Every(1*time.Second), 1)
  389. now := time.Now()
  390. b.ReportAllocs()
  391. b.ResetTimer()
  392. b.RunParallel(func(pb *testing.PB) {
  393. for pb.Next() {
  394. lim.AllowN(now, 1)
  395. }
  396. })
  397. }
  398. func BenchmarkWaitNNoDelay(b *testing.B) {
  399. lim := NewLimiter(Limit(b.N), b.N)
  400. ctx := context.Background()
  401. b.ReportAllocs()
  402. b.ResetTimer()
  403. for i := 0; i < b.N; i++ {
  404. if err := lim.WaitN(ctx, 1); err != nil {
  405. b.Errorf("failed limiter : %s", err)
  406. }
  407. }
  408. }