80 lines
1.7 KiB
Go
80 lines
1.7 KiB
Go
package rate
|
|
|
|
import (
|
|
"sync/atomic"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestNewRateLimitConvert(t *testing.T) {
|
|
// 10 Mbps = 10*1024*1024/8 = 1310720 字节/秒
|
|
r := NewRate(10)
|
|
if r.Limit != 1310720 {
|
|
t.Errorf("Limit = %d, want 1310720", r.Limit)
|
|
}
|
|
if r.Surplus != 1310720 {
|
|
t.Errorf("初始 Surplus = %d, want 1310720", r.Surplus)
|
|
}
|
|
}
|
|
|
|
func TestSetLimit(t *testing.T) {
|
|
r := NewRate(10)
|
|
r.SetLimit(0)
|
|
if r.Limit != 0 {
|
|
t.Errorf("SetLimit(0) 后 Limit = %d, want 0", r.Limit)
|
|
}
|
|
r.SetLimit(1)
|
|
if r.Limit != 1*1024*1024/8 {
|
|
t.Errorf("SetLimit(1) 后 Limit = %d, want %d", r.Limit, 1*1024*1024/8)
|
|
}
|
|
}
|
|
|
|
func TestAddWithoutLimit(t *testing.T) {
|
|
r := NewRate(0) // 不限速
|
|
done := make(chan struct{})
|
|
go func() {
|
|
r.Add(1 << 20)
|
|
close(done)
|
|
}()
|
|
select {
|
|
case <-done:
|
|
case <-time.After(time.Second):
|
|
t.Error("不限速时 Add 阻塞了")
|
|
}
|
|
}
|
|
|
|
func TestAddConsumeQuota(t *testing.T) {
|
|
r := NewRate(1) // 1 Mbps = 131072 字节/秒
|
|
r.Add(1000)
|
|
if got := atomic.LoadInt32(&r.Surplus); got != 131072-1000 {
|
|
t.Errorf("Add 后 Surplus = %d, want %d", got, 131072-1000)
|
|
}
|
|
}
|
|
|
|
func TestStartStopReset(t *testing.T) {
|
|
r := NewRate(1)
|
|
r.Start()
|
|
|
|
r.Add(500)
|
|
// 等待配额重置(每秒一次)
|
|
time.Sleep(1100 * time.Millisecond)
|
|
if got := atomic.LoadInt32(&r.Surplus); got != 131072 {
|
|
t.Errorf("重置后 Surplus = %d, want 131072", got)
|
|
}
|
|
|
|
// Stop 应正常返回(IsStop 通道已在 NewRate 中初始化)
|
|
r.Stop()
|
|
|
|
// 重复 Stop 不应 panic:第二次发送时 proc 协程已退出,会阻塞,故放入独立协程
|
|
done := make(chan struct{})
|
|
go func() {
|
|
defer close(done)
|
|
r.Stop()
|
|
}()
|
|
select {
|
|
case <-done:
|
|
case <-time.After(time.Second):
|
|
t.Log("proc 协程已退出,第二次 Stop 阻塞(属预期)")
|
|
}
|
|
}
|