1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
|
package ratelimit
import (
"sync"
"testing"
)
func TestTokenBucket(t *testing.T) {
b := NewTokenBucket(100)
// Initial retrieve
avail, ok := b.Retrieve(10)
if !ok {
t.Fatalf("expect tokens to be retrieved")
}
if e, a := uint(90), avail; e != a {
t.Fatalf("expect %v available, got %v", e, a)
}
avail, ok = b.Retrieve(91)
if ok {
t.Fatalf("expect no tokens to be retrieved")
}
if e, a := uint(90), avail; e != a {
t.Fatalf("expect %v available, got %v", e, a)
}
// Refunding
b.Refund(1)
// Retrieve all
avail, ok = b.Retrieve(92)
if ok {
t.Fatalf("expect no tokens to be retrieved")
}
if e, a := uint(91), avail; e != a {
t.Fatalf("expect %v available, got %v", e, a)
}
avail, ok = b.Retrieve(91)
if !ok {
t.Fatalf("expect tokens to be retrieved")
}
if e, a := uint(0), avail; e != a {
t.Fatalf("expect %v available, got %v", e, a)
}
// Retrieve empty
avail, ok = b.Retrieve(1)
if ok {
t.Fatalf("expect no tokens to be retrieved")
}
if e, a := uint(0), avail; e != a {
t.Fatalf("expect %v available, got %v", e, a)
}
// Retrieve after refund
b.Refund(1)
avail, ok = b.Retrieve(1)
if !ok {
t.Fatalf("expect tokens to be retrieved")
}
if e, a := uint(0), avail; e != a {
t.Fatalf("expect %v available, got %v", e, a)
}
// Resize
b.Refund(50)
avail = b.Resize(110)
if e, a := uint(50), avail; e != a {
t.Fatalf("expect %v available, got %v", e, a)
}
avail, ok = b.Retrieve(1)
if !ok {
t.Fatalf("expect tokens to be retrieved")
}
if e, a := uint(49), avail; e != a {
t.Fatalf("expect %v available, got %v", e, a)
}
avail = b.Resize(25)
if e, a := uint(25), avail; e != a {
t.Fatalf("expect %v available, got %v", e, a)
}
avail, ok = b.Retrieve(1)
if !ok {
t.Fatalf("expect tokens to be retrieved")
}
if e, a := uint(24), avail; e != a {
t.Fatalf("expect %v available, got %v", e, a)
}
}
func TestTokenBucketParallel(t *testing.T) {
bucket := NewTokenBucket(100)
var wg sync.WaitGroup
wg.Add(3)
count := 1000
go func() {
for i := 0; i < count; i++ {
bucket.Retrieve(1)
}
wg.Done()
}()
go func() {
for i := 0; i < count; i++ {
bucket.Refund(1)
}
wg.Done()
}()
go func() {
for i := 0; i < count; i++ {
bucket.Resize(uint(i))
}
wg.Done()
}()
wg.Wait()
}
|