rate_test.go 12 KB

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