2022-01-31 00:31:04 +00:00
|
|
|
package system
|
|
|
|
|
|
|
|
import (
|
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
. "github.com/franela/goblin"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestRate(t *testing.T) {
|
|
|
|
g := Goblin(t)
|
|
|
|
|
|
|
|
g.Describe("Rate", func() {
|
|
|
|
g.It("properly rate limits a bucket", func() {
|
|
|
|
r := NewRate(10, time.Millisecond*100)
|
|
|
|
|
|
|
|
for i := 0; i < 100; i++ {
|
|
|
|
ok := r.Try()
|
|
|
|
if i < 10 && !ok {
|
|
|
|
g.Failf("should not have allowed take on try %d", i)
|
|
|
|
} else if i >= 10 && ok {
|
|
|
|
g.Failf("should have blocked take on try %d", i)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
g.It("handles rate limiting in chunks", func() {
|
|
|
|
var out []int
|
|
|
|
r := NewRate(12, time.Millisecond*10)
|
|
|
|
|
|
|
|
for i := 0; i < 100; i++ {
|
|
|
|
if i%20 == 0 {
|
|
|
|
// Give it time to recover.
|
|
|
|
time.Sleep(time.Millisecond * 10)
|
|
|
|
}
|
|
|
|
if r.Try() {
|
|
|
|
out = append(out, i)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
g.Assert(len(out)).Equal(60)
|
|
|
|
g.Assert(out[0]).Equal(0)
|
|
|
|
g.Assert(out[12]).Equal(20)
|
|
|
|
g.Assert(out[len(out)-1]).Equal(91)
|
|
|
|
})
|
|
|
|
|
|
|
|
g.It("resets back to zero when called", func() {
|
|
|
|
r := NewRate(10, time.Second)
|
|
|
|
for i := 0; i < 100; i++ {
|
2022-02-23 22:01:03 +00:00
|
|
|
if i%10 == 0 {
|
2022-01-31 00:31:04 +00:00
|
|
|
r.Reset()
|
|
|
|
}
|
|
|
|
g.Assert(r.Try()).IsTrue()
|
|
|
|
}
|
|
|
|
g.Assert(r.Try()).IsFalse("final attempt should not allow taking")
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func BenchmarkRate_Try(b *testing.B) {
|
|
|
|
r := NewRate(10, time.Millisecond*100)
|
|
|
|
|
|
|
|
b.ReportAllocs()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
r.Try()
|
|
|
|
}
|
|
|
|
}
|