mirror of
https://github.com/shadow1ng/fscan.git
synced 2026-09-26 05:01:53 +08:00
test: 补充单元测试覆盖率 29.9% → 36.6%
新建 18 个测试文件,追加 30 个已有测试文件,覆盖协议解析、 错误分类、CEL 表达式求值、YAML 反序列化、字节编码等纯函数。
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
@@ -152,3 +153,121 @@ func TestAdaptivePool_Wait(t *testing.T) {
|
||||
|
||||
t.Logf("Wait 测试通过: %v", duration)
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// maybeReduceTarget 补充覆盖
|
||||
// =============================================================================
|
||||
|
||||
// TestMaybeReduceTarget_NoOpWhenRTTLow rttRatio <= 3.0 时不修改 target
|
||||
func TestMaybeReduceTarget_NoOpWhenRTTLow(t *testing.T) {
|
||||
metrics := &ScanMetrics{}
|
||||
pool, err := NewAdaptivePool(100, 100, func(interface{}) {}, metrics)
|
||||
if err != nil {
|
||||
t.Fatalf("创建线程池失败: %v", err)
|
||||
}
|
||||
defer pool.Release()
|
||||
|
||||
initialTarget := atomic.LoadInt32(&pool.target)
|
||||
|
||||
// RTTRatio 样本不足(< 20)返回 1.0,远低于 3.0 阈值
|
||||
pool.maybeReduceTarget()
|
||||
|
||||
afterTarget := atomic.LoadInt32(&pool.target)
|
||||
if afterTarget != initialTarget {
|
||||
t.Errorf("rttRatio <= 3.0 时 target 不应改变: %d -> %d", initialTarget, afterTarget)
|
||||
}
|
||||
}
|
||||
|
||||
// TestMaybeReduceTarget_ReducesWhenRTTHigh rttRatio > 3.0 时压低 target 10%
|
||||
func TestMaybeReduceTarget_ReducesWhenRTTHigh(t *testing.T) {
|
||||
metrics := &ScanMetrics{}
|
||||
pool, err := NewAdaptivePool(200, 200, func(interface{}) {}, metrics)
|
||||
if err != nil {
|
||||
t.Fatalf("创建线程池失败: %v", err)
|
||||
}
|
||||
defer pool.Release()
|
||||
|
||||
// 伪造 RTT:让 fastEMA >> slowEMA,ratio > 3.0
|
||||
// 方法:先用大 RTT 建立 fastEMA,再用小 RTT 建立 slowEMA
|
||||
// 更直接:直接操作 atomic 字段(包内测试可以访问)
|
||||
for i := 0; i < 25; i++ {
|
||||
metrics.RecordConnect(10 * time.Millisecond) // 先建 baseline
|
||||
}
|
||||
// 现在把 fastEMA 人为拉高(写入一个远大于 slowEMA 的值)
|
||||
pool.metrics.rttFastNs.Store(int64(400 * time.Millisecond))
|
||||
pool.metrics.rttSlowNs.Store(int64(10 * time.Millisecond))
|
||||
|
||||
initialTarget := atomic.LoadInt32(&pool.target)
|
||||
|
||||
pool.maybeReduceTarget()
|
||||
|
||||
afterTarget := atomic.LoadInt32(&pool.target)
|
||||
if afterTarget >= initialTarget {
|
||||
t.Errorf("rttRatio > 3.0 时 target 应被压低: %d -> %d", initialTarget, afterTarget)
|
||||
}
|
||||
|
||||
// 验证是 ×0.9
|
||||
expected := int32(float64(initialTarget) * 0.9)
|
||||
if afterTarget != expected {
|
||||
t.Errorf("target 应为 %d (×0.9), 实际 %d", expected, afterTarget)
|
||||
}
|
||||
}
|
||||
|
||||
// TestMaybeReduceTarget_ClampToMinTarget target 压低后不低于 ceiling/5 或 10
|
||||
func TestMaybeReduceTarget_ClampToMinTarget(t *testing.T) {
|
||||
metrics := &ScanMetrics{}
|
||||
// ceiling=20, minTarget = max(20/5, 10) = 10
|
||||
// target=10, newTarget = int(10*0.9) = 9 → 被 clamp 到 10 → newTarget == target → 不更新
|
||||
pool, err := NewAdaptivePool(10, 20, func(interface{}) {}, metrics)
|
||||
if err != nil {
|
||||
t.Fatalf("创建线程池失败: %v", err)
|
||||
}
|
||||
defer pool.Release()
|
||||
|
||||
// 强制设置 target=10(初始值就是 10,但确认一下)
|
||||
atomic.StoreInt32(&pool.target, 10)
|
||||
|
||||
// 伪造 rttRatio > 3.0
|
||||
for i := 0; i < 25; i++ {
|
||||
metrics.RecordConnect(10 * time.Millisecond)
|
||||
}
|
||||
pool.metrics.rttFastNs.Store(int64(400 * time.Millisecond))
|
||||
pool.metrics.rttSlowNs.Store(int64(10 * time.Millisecond))
|
||||
|
||||
pool.maybeReduceTarget()
|
||||
|
||||
afterTarget := atomic.LoadInt32(&pool.target)
|
||||
// newTarget=9 < minTarget=10 → clamp 到 10 → 10 == target → 不写入
|
||||
if afterTarget != 10 {
|
||||
t.Errorf("clamp 后 target 应保持 10, 实际 %d", afterTarget)
|
||||
}
|
||||
}
|
||||
|
||||
// TestMaybeReduceTarget_LargeCeilingMinTarget ceiling 足够大时 minTarget = ceiling/5
|
||||
func TestMaybeReduceTarget_LargeCeilingMinTarget(t *testing.T) {
|
||||
metrics := &ScanMetrics{}
|
||||
// ceiling=100, minTarget = 100/5 = 20
|
||||
// target=21 → newTarget = int(21*0.9) = 18 → clamp 到 20
|
||||
pool, err := NewAdaptivePool(21, 100, func(interface{}) {}, metrics)
|
||||
if err != nil {
|
||||
t.Fatalf("创建线程池失败: %v", err)
|
||||
}
|
||||
defer pool.Release()
|
||||
|
||||
atomic.StoreInt32(&pool.target, 21)
|
||||
atomic.StoreInt32(&pool.ceiling, 100)
|
||||
|
||||
for i := 0; i < 25; i++ {
|
||||
metrics.RecordConnect(10 * time.Millisecond)
|
||||
}
|
||||
pool.metrics.rttFastNs.Store(int64(400 * time.Millisecond))
|
||||
pool.metrics.rttSlowNs.Store(int64(10 * time.Millisecond))
|
||||
|
||||
pool.maybeReduceTarget()
|
||||
|
||||
afterTarget := atomic.LoadInt32(&pool.target)
|
||||
// newTarget=18 < minTarget=20 → store 20; 20 < 21 → 更新
|
||||
if afterTarget != 20 {
|
||||
t.Errorf("应 clamp 到 minTarget=20, 实际 %d", afterTarget)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user