155 lines
4.2 KiB
Go
155 lines
4.2 KiB
Go
package dispatch
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func healthyChannel(id int64, tier Tier, weight float64) Channel {
|
|
return Channel{
|
|
ID: id,
|
|
Tier: tier,
|
|
BaseWeight: weight,
|
|
SuccEwma: 1.0,
|
|
RampElapsedMs: -1,
|
|
}
|
|
}
|
|
|
|
func TestEffectiveWeight_FullHealthBaseline(t *testing.T) {
|
|
pol := DefaultRoutingPolicy()
|
|
w, bd := EffectiveWeight(healthyChannel(1, TierPrimary, 10), pol)
|
|
assert.InDelta(t, 10.0, w, 1e-9)
|
|
assert.Equal(t, 1.0, bd.Tier)
|
|
assert.Equal(t, 1.0, bd.Health)
|
|
assert.Equal(t, 1.0, bd.Headroom)
|
|
assert.Equal(t, 1.0, bd.Cost)
|
|
assert.Equal(t, 1.0, bd.Ramp)
|
|
}
|
|
|
|
func TestEffectiveWeight_TierBias(t *testing.T) {
|
|
pol := DefaultRoutingPolicy()
|
|
wp, _ := EffectiveWeight(healthyChannel(1, TierPrimary, 10), pol)
|
|
ws, _ := EffectiveWeight(healthyChannel(2, TierSecondary, 10), pol)
|
|
wr, _ := EffectiveWeight(healthyChannel(3, TierReserve, 10), pol)
|
|
assert.InDelta(t, wp*0.15, ws, 1e-9)
|
|
assert.InDelta(t, wp*0.02, wr, 1e-9)
|
|
|
|
// 未知层级(策略未配置)权重为 0
|
|
wu, _ := EffectiveWeight(healthyChannel(4, Tier("unknown"), 10), pol)
|
|
assert.Zero(t, wu)
|
|
}
|
|
|
|
func TestEffectiveWeight_HealthFactor(t *testing.T) {
|
|
pol := DefaultRoutingPolicy() // alpha=2
|
|
|
|
c := healthyChannel(1, TierPrimary, 10)
|
|
c.SuccEwma = 0.9
|
|
_, bd := EffectiveWeight(c, pol)
|
|
assert.InDelta(t, 0.81, bd.Health, 1e-9, "succ=0.9 → 0.81")
|
|
|
|
c.SuccEwma = 0.5
|
|
_, bd = EffectiveWeight(c, pol)
|
|
assert.InDelta(t, 0.25, bd.Health, 1e-9)
|
|
|
|
// 下限保护:极低成功率不至于权重归零(区别于熔断硬排除)
|
|
c.SuccEwma = 0.001
|
|
w, _ := EffectiveWeight(c, pol)
|
|
assert.Greater(t, w, 0.0)
|
|
|
|
// 延迟惩罚:超过 latRef 按比例衰减,最多减半
|
|
c = healthyChannel(1, TierPrimary, 10)
|
|
c.LatEwmaMs = 6000 // latRef=3000 → penalty 0.5
|
|
_, bd = EffectiveWeight(c, pol)
|
|
assert.InDelta(t, 0.5, bd.Health, 1e-9)
|
|
|
|
c.LatEwmaMs = 100000 // penalty 钳制在 0.5
|
|
_, bd = EffectiveWeight(c, pol)
|
|
assert.InDelta(t, 0.5, bd.Health, 1e-9)
|
|
|
|
// 无健康数据(新渠道)视为满分
|
|
c = Channel{ID: 9, Tier: TierPrimary, BaseWeight: 10, RampElapsedMs: -1}
|
|
_, bd = EffectiveWeight(c, pol)
|
|
assert.Equal(t, 1.0, bd.Health)
|
|
}
|
|
|
|
func TestEffectiveWeight_HeadroomFactor(t *testing.T) {
|
|
pol := DefaultRoutingPolicy() // gamma=2
|
|
|
|
c := healthyChannel(1, TierPrimary, 10)
|
|
c.SoftLimit = 10
|
|
c.Inflight = 5
|
|
_, bd := EffectiveWeight(c, pol)
|
|
assert.InDelta(t, 0.25, bd.Headroom, 1e-9, "余量 0.5 → 0.5^2")
|
|
|
|
// 饱和 → 权重坍缩为 0
|
|
c.Inflight = 10
|
|
w, _ := EffectiveWeight(c, pol)
|
|
assert.Zero(t, w)
|
|
|
|
// 超卖同样为 0
|
|
c.Inflight = 15
|
|
w, _ = EffectiveWeight(c, pol)
|
|
assert.Zero(t, w)
|
|
|
|
// 无容量信息恒为 1
|
|
c.SoftLimit = 0
|
|
c.Inflight = 999
|
|
_, bd = EffectiveWeight(c, pol)
|
|
assert.Equal(t, 1.0, bd.Headroom)
|
|
}
|
|
|
|
func TestEffectiveWeight_CostFactor(t *testing.T) {
|
|
pol := DefaultRoutingPolicy() // beta=0.5, clamp [0.5, 2.0]
|
|
|
|
c := healthyChannel(1, TierPrimary, 10)
|
|
c.CostRatio = 0.8 // 八折渠道 → (1/0.8)^0.5 ≈ 1.118
|
|
_, bd := EffectiveWeight(c, pol)
|
|
assert.InDelta(t, 1.118, bd.Cost, 0.001)
|
|
|
|
c.CostRatio = 100 // 极贵渠道钳制在下限
|
|
_, bd = EffectiveWeight(c, pol)
|
|
assert.Equal(t, 0.5, bd.Cost)
|
|
|
|
c.CostRatio = 0.0001 // 极便宜钳制在上限
|
|
_, bd = EffectiveWeight(c, pol)
|
|
assert.Equal(t, 2.0, bd.Cost)
|
|
|
|
c.CostRatio = 0 // 未配置视为等价
|
|
_, bd = EffectiveWeight(c, pol)
|
|
assert.Equal(t, 1.0, bd.Cost)
|
|
}
|
|
|
|
func TestEffectiveWeight_RampFactor(t *testing.T) {
|
|
pol := DefaultRoutingPolicy() // window=120s, floor=0.05
|
|
|
|
c := healthyChannel(1, TierPrimary, 10)
|
|
|
|
c.RampElapsedMs = 0
|
|
_, bd := EffectiveWeight(c, pol)
|
|
assert.Equal(t, 0.05, bd.Ramp, "刚恢复从 floor 开始")
|
|
|
|
c.RampElapsedMs = 60_000
|
|
_, bd = EffectiveWeight(c, pol)
|
|
assert.InDelta(t, 0.5, bd.Ramp, 1e-9)
|
|
|
|
c.RampElapsedMs = 120_000
|
|
_, bd = EffectiveWeight(c, pol)
|
|
assert.Equal(t, 1.0, bd.Ramp)
|
|
|
|
c.RampElapsedMs = -1
|
|
_, bd = EffectiveWeight(c, pol)
|
|
assert.Equal(t, 1.0, bd.Ramp, "非爬坡期恒为 1")
|
|
}
|
|
|
|
func TestEffectiveWeight_NonPositiveBaseWeight(t *testing.T) {
|
|
pol := DefaultRoutingPolicy()
|
|
c := healthyChannel(1, TierPrimary, 0)
|
|
w, _ := EffectiveWeight(c, pol)
|
|
assert.Zero(t, w)
|
|
|
|
c.BaseWeight = -5
|
|
w, _ = EffectiveWeight(c, pol)
|
|
assert.Zero(t, w)
|
|
}
|