Files
easyai-ai-gateway/apps/api/internal/runner/route_prober_test.go
T
wangbo 7786692d32 feat(routing): 引入多执行池智能调度
将 Worker 发现、路由画像、容量与执行传输抽象为平台无关接口,新增 Kubernetes 和静态容量适配器,并以 shadow 模式接入生产配置。

实现网络与容量评分、路由防抖、池队列、同步 Worker 租约、一次性执行令牌,以及提交状态不明时禁止重复分配的安全语义。

新增 0105 兼容迁移、管理接口、指标、OpenAPI 和回归测试。已执行全量 Go 测试、go vet、OpenAPI、迁移安全、Compose 与 Kustomize 验证。
2026-08-05 22:25:37 +08:00

50 lines
2.1 KiB
Go

package runner
import (
"testing"
"time"
"github.com/easyai/easyai-ai-gateway/apps/api/internal/executionpool"
"github.com/easyai/easyai-ai-gateway/apps/api/internal/store"
)
func TestNextRouteHealthRequiresFailuresAndRecoverySamples(t *testing.T) {
now := time.Now()
health := executionpool.RouteHealth{}
for index := 0; index < 2; index++ {
health = nextRouteHealth(health, "pool", "route", executionpool.ProbeResult{SampledAt: now.Add(time.Duration(index) * time.Second), ErrorClass: "network"})
if health.State == executionpool.RouteUnreachable {
t.Fatalf("became unreachable after %d failures", index+1)
}
}
health = nextRouteHealth(health, "pool", "route", executionpool.ProbeResult{SampledAt: now.Add(2 * time.Second), ErrorClass: "network"})
if health.State != executionpool.RouteUnreachable {
t.Fatalf("state=%s, want unreachable", health.State)
}
health = nextRouteHealth(health, "pool", "route", executionpool.ProbeResult{SampledAt: now.Add(3 * time.Second), Reachable: true, TCPDuration: 5 * time.Millisecond, FirstByte: 20 * time.Millisecond})
if health.State != executionpool.RouteDegraded {
t.Fatalf("state=%s, want degraded during recovery", health.State)
}
health = nextRouteHealth(health, "pool", "route", executionpool.ProbeResult{SampledAt: now.Add(4 * time.Second), Reachable: true, TCPDuration: 5 * time.Millisecond, FirstByte: 20 * time.Millisecond})
if health.State != executionpool.RouteHealthy {
t.Fatalf("state=%s, want healthy", health.State)
}
if health.ExpiresAt.Sub(health.SampledAt) != 45*time.Second {
t.Fatalf("health TTL=%s", health.ExpiresAt.Sub(health.SampledAt))
}
}
func TestPinCandidatesToRoutingAssignment(t *testing.T) {
candidates := []store.RuntimeModelCandidate{
{PlatformID: "platform-a", PlatformModelID: "model-a"},
{PlatformID: "platform-b", PlatformModelID: "model-b"},
}
pinned := pinCandidatesToRoutingAssignment(candidates, "platform-b", "model-b")
if len(pinned) != 1 || pinned[0].PlatformModelID != "model-b" {
t.Fatalf("pinned=%+v", pinned)
}
if got := pinCandidatesToRoutingAssignment(candidates, "platform-a", "missing"); len(got) != 0 {
t.Fatalf("unexpected fallback: %+v", got)
}
}