test(acceptance): 验证厂商三类额度与优先路由

为 provider-burst 固定三平台并发、RPM、TPM 和优先级组合,使用稳定 token 用量的本地视频负载验证同级按容量分流及低优先级溢出。\n\n报告升级为 v2,强制校验三类额度峰值精确命中上限、不越界、队列回收、三 Worker 分发以及重复提交和回调安全。\n\n验证:\n- env -u AI_GATEWAY_TEST_DATABASE_URL go test ./... -count=1\n- go vet ./...\n- bash -n scripts/acceptance/provider-burst.sh scripts/acceptance/run-local-acceptance.sh\n- shellcheck -x scripts/acceptance/provider-burst.sh scripts/acceptance/run-local-acceptance.sh
This commit is contained in:
2026-08-03 11:48:54 +08:00
parent aa4f8532bb
commit 8485f14bc4
5 changed files with 129 additions and 32 deletions
+18 -7
View File
@@ -78,11 +78,12 @@ type Report struct {
}
type videoTask struct {
ID string
Model string
CreatedAt time.Time
ReadyAt time.Time
ImageRefs []imageReference
ID string
Model string
CreatedAt time.Time
ReadyAt time.Time
UsageTokens int
ImageRefs []imageReference
}
type imageReference struct {
@@ -243,7 +244,7 @@ func (s *Server) submitVideo(w http.ResponseWriter, r *http.Request) {
id := "acceptance-video-" + strconv.FormatUint(s.nextID.Add(1), 10)
task := videoTask{
ID: id, Model: strings.TrimSpace(stringValue(body["model"])),
CreatedAt: s.now(), ReadyAt: s.now().Add(delay), ImageRefs: refs,
CreatedAt: s.now(), ReadyAt: s.now().Add(delay), UsageTokens: videoUsageTokens(body), ImageRefs: refs,
}
s.mu.Lock()
if existingID := s.videoByIdempotency[idempotencyKey]; existingID != "" {
@@ -298,7 +299,7 @@ func (s *Server) getVideo(w http.ResponseWriter, r *http.Request) {
writeJSON(w, http.StatusOK, map[string]any{
"id": id, "model": task.Model, "status": status, "content": content,
"created_at": task.CreatedAt.Unix(),
"usage": map[string]any{"completion_tokens": 1, "total_tokens": 1},
"usage": map[string]any{"completion_tokens": task.UsageTokens, "total_tokens": task.UsageTokens},
})
}
@@ -674,12 +675,22 @@ func videoDelay(body map[string]any, longRun bool) time.Duration {
if longRun {
return 2*time.Minute + time.Duration(seed%61)*time.Second
}
if videoPromptContains(body, "acceptance-provider-quota") {
return 5*time.Second + time.Duration(seed%6)*time.Second
}
if videoPromptContains(body, "acceptance-capacity-ladder") {
return 30*time.Second + time.Duration(seed%16)*time.Second
}
return 5*time.Second + time.Duration(seed%11)*time.Second
}
func videoUsageTokens(body map[string]any) int {
if videoPromptContains(body, "acceptance-provider-quota") {
return 7
}
return 1
}
func videoPromptContains(body map[string]any, marker string) bool {
content, _ := body["content"].([]any)
for _, raw := range content {