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 阻塞(属预期)") } }