test(acceptance): 在单窗口验证厂商额度峰值
厂商额度验收此前复用了多图与超大图容量素材,3 Worker 的下载和预处理使 24 个任务跨越多个固定分钟窗口,无法精确证明 RPM 与 TPM 上限。\n\n额度场景固定使用三张正常尺寸引用图并为每个任务增加唯一 URL 变体,使请求满足视频协议且能在单窗口完成;6、9 图和超大图转换继续由独立视频容量 profile 覆盖。\n\n验证:\n- go test ./cmd/acceptance-load ./internal/acceptanceworkload -count=1\n- go vet ./cmd/acceptance-load ./internal/acceptanceworkload\n- gofmt -l cmd/acceptance-load/main.go cmd/acceptance-load/main_test.go
This commit is contained in:
@@ -640,6 +640,13 @@ func runVideo(
|
||||
combinationCount = 1
|
||||
}
|
||||
combinations := videoCombinations(imageURLs, combinationCount)
|
||||
if name == "video-provider-quota" {
|
||||
// The quota profile must complete in one fixed rate-limit window so
|
||||
// RPM and TPM can be proven at their exact configured ceilings. Use
|
||||
// three distinct normal-sized references per task; larger multi-image
|
||||
// and oversized conversion remain covered by video capacity profiles.
|
||||
combinations = videoProviderQuotaCombinations(imageURLs, combinationCount)
|
||||
}
|
||||
var taskIDs = make([]string, requestCount)
|
||||
latencies := make([]time.Duration, requestCount)
|
||||
startedTasks := make([]time.Time, requestCount)
|
||||
@@ -658,7 +665,7 @@ func runVideo(
|
||||
logicalIndex := requestOffset + index*requestStride
|
||||
requestStarted := time.Now()
|
||||
startedTasks[index] = requestStarted
|
||||
imageCount := acceptanceworkload.VideoImageCount(logicalIndex)
|
||||
imageCount := videoImageCountForProfile(name, logicalIndex)
|
||||
combo := append([]string(nil), combinations[logicalIndex%len(combinations)]...)
|
||||
if len(combo) > imageCount {
|
||||
combo = combo[:imageCount]
|
||||
@@ -784,6 +791,7 @@ func runVideo(
|
||||
wg.Wait()
|
||||
uniqueImageCombinations := requestedVideoCombinationCount(
|
||||
combinations,
|
||||
name,
|
||||
requestCount,
|
||||
requestOffset,
|
||||
requestStride,
|
||||
@@ -1180,8 +1188,46 @@ func videoCombinations(images []string, count int) [][]string {
|
||||
return out
|
||||
}
|
||||
|
||||
func videoProviderQuotaCombinations(images []string, count int) [][]string {
|
||||
if len(images) == 0 || count <= 0 {
|
||||
return nil
|
||||
}
|
||||
fixtureCount := min(len(images), 4)
|
||||
if fixtureCount < 3 {
|
||||
return nil
|
||||
}
|
||||
out := make([][]string, 0, count)
|
||||
for index := 0; index < count; index++ {
|
||||
combination := make([]string, 0, 3)
|
||||
for imageIndex := 0; imageIndex < 3; imageIndex++ {
|
||||
imageURL := images[(index+imageIndex)%fixtureCount]
|
||||
separator := "?"
|
||||
if strings.Contains(imageURL, "?") {
|
||||
separator = "&"
|
||||
}
|
||||
combination = append(combination, fmt.Sprintf(
|
||||
"%s%sacceptance_quota_variant=%d-%d",
|
||||
imageURL,
|
||||
separator,
|
||||
index,
|
||||
imageIndex,
|
||||
))
|
||||
}
|
||||
out = append(out, combination)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func videoImageCountForProfile(profile string, index int) int {
|
||||
if profile == "video-provider-quota" {
|
||||
return 3
|
||||
}
|
||||
return acceptanceworkload.VideoImageCount(index)
|
||||
}
|
||||
|
||||
func requestedVideoCombinationCount(
|
||||
combinations [][]string,
|
||||
profile string,
|
||||
requestCount int,
|
||||
requestOffset int,
|
||||
requestStride int,
|
||||
@@ -1195,7 +1241,7 @@ func requestedVideoCombinationCount(
|
||||
seen := map[string]struct{}{}
|
||||
for index := 0; index < requestCount; index++ {
|
||||
logicalIndex := requestOffset + index*requestStride
|
||||
imageCount := acceptanceworkload.VideoImageCount(logicalIndex)
|
||||
imageCount := videoImageCountForProfile(profile, logicalIndex)
|
||||
combo := combinations[logicalIndex%len(combinations)]
|
||||
if len(combo) > imageCount {
|
||||
combo = combo[:imageCount]
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
)
|
||||
@@ -172,11 +173,34 @@ func TestVideoCombinationsProvide128UniqueInputs(t *testing.T) {
|
||||
if len(seen) != 128 {
|
||||
t.Fatalf("unique combinations=%d", len(seen))
|
||||
}
|
||||
if got := requestedVideoCombinationCount(combinations, 144, 0, 1); got != 131 {
|
||||
if got := requestedVideoCombinationCount(combinations, "video-capacity", 144, 0, 1); got != 131 {
|
||||
t.Fatalf("requested combinations=%d, want 131", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVideoProviderQuotaCombinationsUseDistinctNormalSizedImages(t *testing.T) {
|
||||
images := []string{
|
||||
"https://fixtures.example/image-00.png",
|
||||
"https://fixtures.example/image-01.png",
|
||||
"https://fixtures.example/image-02.png",
|
||||
"https://fixtures.example/image-03.png",
|
||||
}
|
||||
combinations := videoProviderQuotaCombinations(images, 24)
|
||||
if got := requestedVideoCombinationCount(combinations, "video-provider-quota", 24, 0, 1); got != 24 {
|
||||
t.Fatalf("quota combinations=%d, want 24", got)
|
||||
}
|
||||
for _, combination := range combinations {
|
||||
if len(combination) != 3 {
|
||||
t.Fatalf("invalid quota combination: %v", combination)
|
||||
}
|
||||
for _, imageURL := range combination {
|
||||
if !strings.Contains(imageURL, "acceptance_quota_variant=") {
|
||||
t.Fatalf("quota image lacks unique variant: %s", imageURL)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGeminiLoadIsSplitAcrossTwoGatewayAPIs(t *testing.T) {
|
||||
output := paddedPNG(256 << 10)
|
||||
encoded := base64.StdEncoding.EncodeToString(output)
|
||||
|
||||
Reference in New Issue
Block a user