fix(queue): 移除未配置的 GPT 图像并发上限
This commit is contained in:
@@ -118,3 +118,123 @@ WHERE id = '20000000-0000-0000-0000-000000000001'`).Scan(&normalizedPlatformPoli
|
||||
t.Fatalf("normalized platform policy=%s, want={}", normalizedPlatformPolicy)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoveUnconfiguredGPTImageConcurrencyLimitMigration(t *testing.T) {
|
||||
databaseURL := strings.TrimSpace(os.Getenv("AI_GATEWAY_TEST_DATABASE_URL"))
|
||||
if databaseURL == "" {
|
||||
t.Skip("set AI_GATEWAY_TEST_DATABASE_URL to run rate-limit migration PostgreSQL integration tests")
|
||||
}
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
|
||||
defer cancel()
|
||||
schema := fmt.Sprintf("remove_gpt_image_limit_%d", time.Now().UnixNano())
|
||||
adminPool, err := pgxpool.New(ctx, databaseURL)
|
||||
if err != nil {
|
||||
t.Fatalf("connect migration test database: %v", err)
|
||||
}
|
||||
defer adminPool.Close()
|
||||
if _, err := adminPool.Exec(ctx, `CREATE SCHEMA `+schema); err != nil {
|
||||
t.Fatalf("create migration test schema: %v", err)
|
||||
}
|
||||
defer adminPool.Exec(context.Background(), `DROP SCHEMA IF EXISTS `+schema+` CASCADE`)
|
||||
|
||||
schemaURL, err := url.Parse(databaseURL)
|
||||
if err != nil {
|
||||
t.Fatalf("parse test database url: %v", err)
|
||||
}
|
||||
query := schemaURL.Query()
|
||||
query.Set("search_path", schema)
|
||||
schemaURL.RawQuery = query.Encode()
|
||||
pool, err := pgxpool.New(ctx, schemaURL.String())
|
||||
if err != nil {
|
||||
t.Fatalf("connect migration test schema: %v", err)
|
||||
}
|
||||
defer pool.Close()
|
||||
if _, err := pool.Exec(ctx, `
|
||||
CREATE TABLE base_model_catalog (
|
||||
id uuid PRIMARY KEY,
|
||||
invocation_name text NOT NULL,
|
||||
default_rate_limit_policy jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
metadata jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
updated_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
INSERT INTO base_model_catalog (id, invocation_name, default_rate_limit_policy, metadata) VALUES
|
||||
(
|
||||
'00000000-0000-0000-0000-000000000001',
|
||||
'gpt-image-2',
|
||||
'{"rules":[{"metric":"concurrent","limit":5,"leaseTtlSeconds":300}]}',
|
||||
'{"rateLimitSource":"image-gateway-migration","rateLimitUpdatedAt":"2026-07-24"}'
|
||||
),
|
||||
(
|
||||
'00000000-0000-0000-0000-000000000002',
|
||||
'gpt-image-2',
|
||||
'{"rules":[{"metric":"concurrent","limit":6,"leaseTtlSeconds":300}]}',
|
||||
'{"rateLimitSource":"image-gateway-migration"}'
|
||||
),
|
||||
(
|
||||
'00000000-0000-0000-0000-000000000003',
|
||||
'gpt-image-2',
|
||||
'{"rules":[{"metric":"concurrent","limit":5,"leaseTtlSeconds":300}]}',
|
||||
'{"rateLimitSource":"operator"}'
|
||||
),
|
||||
(
|
||||
'00000000-0000-0000-0000-000000000004',
|
||||
'gemini-3-pro-image',
|
||||
'{"rules":[{"metric":"concurrent","limit":10,"leaseTtlSeconds":600}]}',
|
||||
'{"rateLimitSource":"image-gateway-migration"}'
|
||||
);`); err != nil {
|
||||
t.Fatalf("seed pre-migration rows: %v", err)
|
||||
}
|
||||
|
||||
_, currentFile, _, _ := runtime.Caller(0)
|
||||
migrationPath := filepath.Join(filepath.Dir(currentFile), "..", "..", "migrations", "0082_remove_unconfigured_gpt_image_concurrency_limit.sql")
|
||||
migration, err := os.ReadFile(migrationPath)
|
||||
if err != nil {
|
||||
t.Fatalf("read migration: %v", err)
|
||||
}
|
||||
if _, err := pool.Exec(ctx, string(migration)); err != nil {
|
||||
t.Fatalf("apply migration: %v", err)
|
||||
}
|
||||
|
||||
rows, err := pool.Query(ctx, `
|
||||
SELECT id::text, default_rate_limit_policy::text, metadata->>'rateLimitSource',
|
||||
metadata->>'rateLimitRemovalReason'
|
||||
FROM base_model_catalog
|
||||
ORDER BY id`)
|
||||
if err != nil {
|
||||
t.Fatalf("read migrated rows: %v", err)
|
||||
}
|
||||
defer rows.Close()
|
||||
type result struct {
|
||||
policy string
|
||||
source *string
|
||||
removalReason *string
|
||||
}
|
||||
got := make([]result, 0, 4)
|
||||
for rows.Next() {
|
||||
var id string
|
||||
var item result
|
||||
if err := rows.Scan(&id, &item.policy, &item.source, &item.removalReason); err != nil {
|
||||
t.Fatalf("scan migrated row: %v", err)
|
||||
}
|
||||
got = append(got, item)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
t.Fatalf("read migrated rows: %v", err)
|
||||
}
|
||||
if len(got) != 4 {
|
||||
t.Fatalf("migrated %d rows, want 4", len(got))
|
||||
}
|
||||
if got[0].policy != "{}" || got[0].source != nil ||
|
||||
got[0].removalReason == nil || *got[0].removalReason != "upstream-limit-unconfigured" {
|
||||
t.Fatalf("migration-owned GPT policy not removed: %+v", got[0])
|
||||
}
|
||||
if got[1].policy == "{}" || got[1].source == nil || *got[1].source != "image-gateway-migration" {
|
||||
t.Fatalf("custom GPT policy was changed: %+v", got[1])
|
||||
}
|
||||
if got[2].policy == "{}" || got[2].source == nil || *got[2].source != "operator" {
|
||||
t.Fatalf("operator GPT policy was changed: %+v", got[2])
|
||||
}
|
||||
if got[3].policy == "{}" || got[3].source == nil || *got[3].source != "image-gateway-migration" {
|
||||
t.Fatalf("Gemini policy was changed: %+v", got[3])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
-- gpt-image-2 platforms do not declare an upstream concurrency limit. The
|
||||
-- migration-only base default added in 0081 therefore turned an unspecified
|
||||
-- limit into an artificial per-platform-model cap of five.
|
||||
--
|
||||
-- Remove only the exact policy written by 0081. Explicit platform, runtime, or
|
||||
-- platform-model policies continue to take precedence and remain untouched.
|
||||
UPDATE base_model_catalog
|
||||
SET default_rate_limit_policy = '{}'::jsonb,
|
||||
metadata = (COALESCE(metadata, '{}'::jsonb) - 'rateLimitSource' - 'rateLimitUpdatedAt')
|
||||
|| jsonb_build_object(
|
||||
'rateLimitRemovedAt', '2026-07-24',
|
||||
'rateLimitRemovalReason', 'upstream-limit-unconfigured'
|
||||
),
|
||||
updated_at = now()
|
||||
WHERE invocation_name = 'gpt-image-2'
|
||||
AND metadata->>'rateLimitSource' = 'image-gateway-migration'
|
||||
AND default_rate_limit_policy =
|
||||
'{"rules":[{"metric":"concurrent","limit":5,"leaseTtlSeconds":300}]}'::jsonb;
|
||||
Reference in New Issue
Block a user