Skip to content

Commit 6678579

Browse files
authored
localCounter: Add more robust table-driven tests (#35)
1 parent bff9ca6 commit 6678579

File tree

3 files changed

+115
-55
lines changed

3 files changed

+115
-55
lines changed

go.mod

+2
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,5 @@ module github.com/go-chi/httprate
33
go 1.17
44

55
require github.com/cespare/xxhash/v2 v2.3.0
6+
7+
require golang.org/x/sync v0.7.0 // indirect

go.sum

+2
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,5 @@ github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cb
22
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
33
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
44
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
5+
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
6+
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=

local_counter_test.go

+111-55
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import (
66
"sync"
77
"testing"
88
"time"
9+
10+
"golang.org/x/sync/errgroup"
911
)
1012

1113
func TestLocalCounter(t *testing.T) {
@@ -16,74 +18,128 @@ func TestLocalCounter(t *testing.T) {
1618
windowLength: time.Second,
1719
}
1820

19-
// Time = NOW()
2021
currentWindow := time.Now().UTC().Truncate(time.Second)
2122
previousWindow := currentWindow.Add(-time.Second)
2223

23-
for i := 0; i < 5; i++ {
24-
curr, prev, _ := limitCounter.Get(fmt.Sprintf("key-%v", i), currentWindow, previousWindow)
25-
if curr != 0 {
26-
t.Errorf("unexpected curr = %v, expected %v", curr, 0)
27-
}
28-
if prev != 0 {
29-
t.Errorf("unexpected prev = %v, expected %v", prev, 0)
30-
}
31-
32-
_ = limitCounter.IncrementBy(fmt.Sprintf("key-%v", i), currentWindow, 1)
33-
_ = limitCounter.IncrementBy(fmt.Sprintf("key-%v", i), currentWindow, 99)
34-
35-
curr, prev, _ = limitCounter.Get(fmt.Sprintf("key-%v", i), currentWindow, previousWindow)
36-
if curr != 100 {
37-
t.Errorf("unexpected curr = %v, expected %v", curr, 100)
38-
}
39-
if prev != 0 {
40-
t.Errorf("unexpected prev = %v, expected %v", prev, 0)
41-
}
24+
type test struct {
25+
name string // In each test do the following:
26+
advanceTime time.Duration // 1. advance time
27+
incrBy int // 2. increase counter
28+
prev int // 3. check previous window counter
29+
curr int // and current window counter
4230
}
4331

44-
// Time++
45-
currentWindow = currentWindow.Add(time.Second)
46-
previousWindow = previousWindow.Add(time.Second)
47-
48-
for i := 0; i < 5; i++ {
49-
curr, prev, _ := limitCounter.Get(fmt.Sprintf("key-%v", i), currentWindow, previousWindow)
50-
if curr != 0 {
51-
t.Errorf("unexpected curr = %v, expected %v", curr, 0)
52-
}
53-
if prev != 100 {
54-
t.Errorf("unexpected prev = %v, expected %v", prev, 100)
55-
}
56-
_ = limitCounter.IncrementBy(fmt.Sprintf("key-%v", i), currentWindow, 50)
32+
tests := []test{
33+
{
34+
name: "t=0s: init",
35+
prev: 0,
36+
curr: 0,
37+
},
38+
{
39+
name: "t=0s: increment 1",
40+
incrBy: 1,
41+
prev: 0,
42+
curr: 1,
43+
},
44+
{
45+
name: "t=0s: increment by 99",
46+
incrBy: 99,
47+
prev: 0,
48+
curr: 100,
49+
},
50+
{
51+
name: "t=1s: move clock by 1s",
52+
advanceTime: time.Second,
53+
prev: 100,
54+
curr: 0,
55+
},
56+
{
57+
name: "t=1s: increment by 20",
58+
incrBy: 20,
59+
prev: 100,
60+
curr: 20,
61+
},
62+
{
63+
name: "t=1s: increment by 20",
64+
incrBy: 20,
65+
prev: 100,
66+
curr: 40,
67+
},
68+
{
69+
name: "t=2s: move clock by 1s",
70+
advanceTime: time.Second,
71+
prev: 40,
72+
curr: 0,
73+
},
74+
{
75+
name: "t=2s: incr++",
76+
incrBy: 1,
77+
prev: 40,
78+
curr: 1,
79+
},
80+
{
81+
name: "t=2s: incr+=9",
82+
incrBy: 9,
83+
prev: 40,
84+
curr: 10,
85+
},
86+
{
87+
name: "t=2s: incr+=20",
88+
incrBy: 20,
89+
prev: 40,
90+
curr: 30,
91+
},
92+
{
93+
name: "t=4s: move clock by 2s",
94+
advanceTime: 2 * time.Second,
95+
prev: 0,
96+
curr: 0,
97+
},
5798
}
5899

59-
// Time++
60-
currentWindow = currentWindow.Add(time.Second)
61-
previousWindow = previousWindow.Add(time.Second)
100+
concurrentRequests := 1000
62101

63-
for i := 0; i < 5; i++ {
64-
curr, prev, _ := limitCounter.Get(fmt.Sprintf("key-%v", i), currentWindow, previousWindow)
65-
if curr != 0 {
66-
t.Errorf("unexpected curr = %v, expected %v", curr, 0)
102+
for _, tt := range tests {
103+
if tt.advanceTime > 0 {
104+
currentWindow = currentWindow.Add(tt.advanceTime)
105+
previousWindow = previousWindow.Add(tt.advanceTime)
67106
}
68-
if prev != 50 {
69-
t.Errorf("unexpected prev = %v, expected %v", prev, 50)
70-
}
71-
_ = limitCounter.IncrementBy(fmt.Sprintf("key-%v", i), currentWindow, 99)
72-
}
73107

74-
// Time += 10
75-
currentWindow = currentWindow.Add(10 * time.Second)
76-
previousWindow = previousWindow.Add(10 * time.Second)
108+
if tt.incrBy > 0 {
109+
var g errgroup.Group
110+
for i := 0; i < concurrentRequests; i++ {
111+
i := i
112+
g.Go(func() error {
113+
key := fmt.Sprintf("key:%v", i)
114+
return limitCounter.IncrementBy(key, currentWindow, tt.incrBy)
115+
})
116+
}
117+
if err := g.Wait(); err != nil {
118+
t.Errorf("%s: %v", tt.name, err)
119+
}
120+
}
77121

78-
for i := 0; i < 5; i++ {
79-
curr, prev, _ := limitCounter.Get(fmt.Sprintf("key-%v", i), currentWindow, previousWindow)
80-
if curr != 0 {
81-
t.Errorf("unexpected curr = %v, expected %v", curr, 0)
122+
var g errgroup.Group
123+
for i := 0; i < concurrentRequests; i++ {
124+
i := i
125+
g.Go(func() error {
126+
key := fmt.Sprintf("key:%v", i)
127+
curr, prev, err := limitCounter.Get(key, currentWindow, previousWindow)
128+
if err != nil {
129+
return fmt.Errorf("%q: %w", key, err)
130+
}
131+
if curr != tt.curr {
132+
return fmt.Errorf("%q: unexpected curr = %v, expected %v", key, curr, tt.curr)
133+
}
134+
if prev != tt.prev {
135+
return fmt.Errorf("%q: unexpected prev = %v, expected %v", key, prev, tt.prev)
136+
}
137+
return nil
138+
})
82139
}
83-
if prev != 0 {
84-
t.Errorf("unexpected prev = %v, expected %v", prev, 0)
140+
if err := g.Wait(); err != nil {
141+
t.Errorf("%s: %v", tt.name, err)
85142
}
86-
_ = limitCounter.IncrementBy(fmt.Sprintf("key-%v", i), currentWindow, 99)
87143
}
88144
}
89145

0 commit comments

Comments
 (0)