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
+13 -4
View File
@@ -279,7 +279,7 @@ func parseOptions() (options, error) {
return options{}, errors.New("requests must be between 0 and 10000")
}
switch opts.profile {
case "simulated-smoke", "simulated-all", "gemini-baseline", "gemini-multi-image", "gemini-large", "gemini-peak", "video-throughput", "video-capacity", "video-recovery",
case "simulated-smoke", "simulated-all", "gemini-baseline", "gemini-multi-image", "gemini-large", "gemini-peak", "video-throughput", "video-capacity", "video-provider-quota", "video-recovery",
"mixed-soak", "mixed-overload":
if opts.emulatorURL == "" {
return options{}, errors.New("AI_GATEWAY_ACCEPTANCE_EMULATOR_URL is required for simulated profiles")
@@ -371,6 +371,12 @@ func run(ctx context.Context, opts options) ([]phaseResult, error) {
requests = opts.requestCount
}
result = runVideo(ctx, client, opts, name, opts.shardRequestCount(requests), false, opts.emulatorFixtureURLs(), false, opts.shardIndex, opts.shardCount)
case "video-provider-quota":
requests := 24
if opts.requestCount > 0 {
requests = opts.requestCount
}
result = runVideo(ctx, client, opts, name, opts.shardRequestCount(requests), false, opts.emulatorFixtureURLs(), false, opts.shardIndex, opts.shardCount)
case "video-recovery":
result = runVideo(ctx, client, opts, name, opts.shardRequestCount(96), true, opts.emulatorFixtureURLs(), false, opts.shardIndex, opts.shardCount)
case "mixed-soak", "mixed-overload":
@@ -657,18 +663,21 @@ func runVideo(
if len(combo) > imageCount {
combo = combo[:imageCount]
}
if !realUpstream && logicalIndex%4 == 0 {
if !realUpstream && name != "video-provider-quota" && logicalIndex%4 == 0 {
combo[0] = imageURLs[12+(logicalIndex/4)%4]
}
content := make([]any, 0, len(combo)+1)
prompt := "多参考图生成连续运镜视频,保持人物、服装和场景一致"
if name == "video-provider-quota" {
prompt = "acceptance-provider-quota"
}
if longRun {
prompt += " acceptance-long-recovery"
}
if name == "video-capacity" {
prompt += " acceptance-capacity-ladder"
}
if !realUpstream && logicalIndex%4 == 0 {
if !realUpstream && name != "video-provider-quota" && logicalIndex%4 == 0 {
prompt += " acceptance-force-conversion"
}
content = append(content, map[string]any{"type": "text", "text": prompt})
@@ -716,7 +725,7 @@ func runVideo(
err = withOperation("video_submit", err)
mu.Lock()
latencies[index] = time.Since(requestStarted)
if !realUpstream && logicalIndex%4 == 0 {
if !realUpstream && name != "video-provider-quota" && logicalIndex%4 == 0 {
forcedConversions++
}
if err != nil {