test(acceptance): 增加视频容量阶梯场景

新增 30 至 45 秒模拟上游等待的视频容量场景,使单 Worker 自适应控制在每级突发负载中获得连续占满窗口,同时保持提交、轮询、结果处理和回调全链路。\n\n未修改生产 Worker 和厂商限流逻辑。已执行完整 Go 测试、go vet、gofmt、bash -n、ShellCheck 和生产验收脚本测试。
This commit is contained in:
2026-08-03 10:45:09 +08:00
parent 75b3ed4748
commit 0d33400e09
4 changed files with 40 additions and 2 deletions
+10 -1
View File
@@ -279,7 +279,7 @@ func parseOptions() (options, error) {
return options{}, errors.New("requests must be between 0 and 10000") return options{}, errors.New("requests must be between 0 and 10000")
} }
switch opts.profile { switch opts.profile {
case "simulated-smoke", "simulated-all", "gemini-baseline", "gemini-multi-image", "gemini-large", "gemini-peak", "video-throughput", "video-recovery", case "simulated-smoke", "simulated-all", "gemini-baseline", "gemini-multi-image", "gemini-large", "gemini-peak", "video-throughput", "video-capacity", "video-recovery",
"mixed-soak", "mixed-overload": "mixed-soak", "mixed-overload":
if opts.emulatorURL == "" { if opts.emulatorURL == "" {
return options{}, errors.New("AI_GATEWAY_ACCEPTANCE_EMULATOR_URL is required for simulated profiles") return options{}, errors.New("AI_GATEWAY_ACCEPTANCE_EMULATOR_URL is required for simulated profiles")
@@ -365,6 +365,12 @@ func run(ctx context.Context, opts options) ([]phaseResult, error) {
requests = opts.requestCount requests = opts.requestCount
} }
result = runVideo(ctx, client, opts, name, opts.shardRequestCount(requests), false, opts.emulatorFixtureURLs(), false, opts.shardIndex, opts.shardCount) result = runVideo(ctx, client, opts, name, opts.shardRequestCount(requests), false, opts.emulatorFixtureURLs(), false, opts.shardIndex, opts.shardCount)
case "video-capacity":
requests := 1200
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": case "video-recovery":
result = runVideo(ctx, client, opts, name, opts.shardRequestCount(96), true, opts.emulatorFixtureURLs(), false, opts.shardIndex, opts.shardCount) result = runVideo(ctx, client, opts, name, opts.shardRequestCount(96), true, opts.emulatorFixtureURLs(), false, opts.shardIndex, opts.shardCount)
case "mixed-soak", "mixed-overload": case "mixed-soak", "mixed-overload":
@@ -659,6 +665,9 @@ func runVideo(
if longRun { if longRun {
prompt += " acceptance-long-recovery" prompt += " acceptance-long-recovery"
} }
if name == "video-capacity" {
prompt += " acceptance-capacity-ladder"
}
if !realUpstream && logicalIndex%4 == 0 { if !realUpstream && logicalIndex%4 == 0 {
prompt += " acceptance-force-conversion" prompt += " acceptance-force-conversion"
} }
@@ -674,9 +674,24 @@ func videoDelay(body map[string]any, longRun bool) time.Duration {
if longRun { if longRun {
return 2*time.Minute + time.Duration(seed%61)*time.Second return 2*time.Minute + time.Duration(seed%61)*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 return 5*time.Second + time.Duration(seed%11)*time.Second
} }
func videoPromptContains(body map[string]any, marker string) bool {
content, _ := body["content"].([]any)
for _, raw := range content {
item, _ := raw.(map[string]any)
if strings.TrimSpace(stringValue(item["type"])) == "text" &&
strings.Contains(strings.ToLower(stringValue(item["text"])), marker) {
return true
}
}
return false
}
func requestOrigin(r *http.Request) string { func requestOrigin(r *http.Request) string {
scheme := strings.TrimSpace(r.Header.Get("X-Forwarded-Proto")) scheme := strings.TrimSpace(r.Header.Get("X-Forwarded-Proto"))
if scheme == "" { if scheme == "" {
@@ -228,6 +228,20 @@ func TestScaledDelayStaysOnWholeSecondsWithinProfile(t *testing.T) {
} }
} }
func TestVideoCapacityDelay(t *testing.T) {
body := map[string]any{
"seed": json.Number("7"),
"content": []any{map[string]any{
"type": "text",
"text": "capacity acceptance-capacity-ladder",
}},
}
delay := videoDelay(body, false)
if delay < 30*time.Second || delay > 45*time.Second {
t.Fatalf("video capacity delay=%s, want 30s..45s", delay)
}
}
func TestVolcesProtocolAcceptsThreeSixAndNineReferenceImages(t *testing.T) { func TestVolcesProtocolAcceptsThreeSixAndNineReferenceImages(t *testing.T) {
server := New(Config{Wait: func(context.Context, time.Duration) error { return nil }}) server := New(Config{Wait: func(context.Context, time.Duration) error { return nil }})
httpServer := httptest.NewServer(server.Handler()) httpServer := httptest.NewServer(server.Handler())
+1 -1
View File
@@ -3819,7 +3819,7 @@ run_single_node_acceptance() {
apply_single_node_capacity "$slots" || break apply_single_node_capacity "$slots" || break
requests=$((slots * 3)) requests=$((slots * 3))
(( requests < 32 )) && requests=32 (( requests < 32 )) && requests=32
if ! run_single_node_profile image-video video-throughput "$slots" "$requests"; then if ! run_single_node_profile image-video video-capacity "$slots" "$requests"; then
break break
fi fi
single_node_stable_slots=$slots single_node_stable_slots=$slots