feat: 统一服务缓存 + 指纹驱动插件匹配

将 webServiceCache 扩展为通用 serviceCache,所有指纹识别结果
统一缓存,插件匹配时端口不命中则回退到服务名称匹配。

删除多余的 service_cache.go,复用已有的 ServiceInfo 体系。
补充 nil 防御、Explicit 标记、大量单元/集成/回归测试。
This commit is contained in:
ZacharyZcR
2026-06-14 22:23:47 +08:00
parent 2ab7c4d9b2
commit 5ad914a1bb
44 changed files with 1533 additions and 142 deletions
+28 -10
View File
@@ -60,7 +60,7 @@ func TestClassifyNetwork(t *testing.T) {
t.Run("公网 RTT 分布(低丢包)", func(t *testing.T) {
rtts := makeDurations([]int{60, 70, 80, 90, 100, 110, 120, 150, 200, 300}) // ms
p := classifyNetwork(rtts, 0, 10) // 无丢包
p := classifyNetwork(rtts, 0, 10) // 无丢包
if p.Env != EnvInternet {
t.Errorf("env = %v, want Internet", p.Env)
@@ -72,7 +72,7 @@ func TestClassifyNetwork(t *testing.T) {
t.Run("高丢包归类为慢速", func(t *testing.T) {
rtts := makeDurations([]int{60, 70, 80, 90, 100}) // ms, 5 responded
p := classifyNetwork(rtts, 5, 10) // 50% loss
p := classifyNetwork(rtts, 5, 10) // 50% loss
if p.Env != EnvSlow {
t.Errorf("env = %v, want Slow (高丢包)", p.Env)
@@ -96,14 +96,14 @@ func TestClassifyNetwork(t *testing.T) {
func TestRecommendConcurrency(t *testing.T) {
tests := []struct {
env NetworkEnv
lossRate float64
userT int
explicit bool
wantTMin int
wantTMax int
wantCeil int
desc string
env NetworkEnv
lossRate float64
userT int
explicit bool
wantTMin int
wantTMax int
wantCeil int
desc string
}{
{EnvLAN, 0.0, 600, false, 800, 1000, -1, "内网自动: ×1.5"},
{EnvWAN, 0.0, 600, false, 550, 650, -1, "局域网自动: ×1.0"},
@@ -156,6 +156,24 @@ func TestPickSamples(t *testing.T) {
}
}
func TestNetworkProbeAddressUsesJoinHostPort(t *testing.T) {
tests := []struct {
host string
port int
want string
}{
{"127.0.0.1", 80, "127.0.0.1:80"},
{"::1", 443, "[::1]:443"},
{"2001:db8::1", 22, "[2001:db8::1]:22"},
}
for _, tt := range tests {
if got := networkProbeAddress(tt.host, tt.port); got != tt.want {
t.Fatalf("networkProbeAddress(%q, %d) = %q, want %q", tt.host, tt.port, got, tt.want)
}
}
}
// =============================================================================
// 辅助
// =============================================================================