sub2api/backend/internal/service/antigravity_quota_reason_test.go
win 9da079a5ee
Some checks failed
Security Scan / backend-security (push) Failing after 3s
Security Scan / frontend-security (push) Failing after 5s
CI / test (push) Failing after 3s
CI / frontend (push) Failing after 3s
CI / golangci-lint (push) Failing after 3s
CI / windsurf-platform (macos-latest) (push) Has been cancelled
CI / windsurf-platform (windows-latest) (push) Has been cancelled
x
2026-04-27 19:01:41 +08:00

98 lines
3.1 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//go:build unit
package service
import (
"encoding/json"
"testing"
"github.com/stretchr/testify/require"
)
// 验证 parseAntigravitySmartRetryInfo 能识别 4 类 ErrorInfo.reason
// - RATE_LIMIT_EXCEEDED (RESOURCE_EXHAUSTED)
// - QUOTA_EXHAUSTED (RESOURCE_EXHAUSTED)
// - INSUFFICIENT_G1_CREDITS_BALANCE (RESOURCE_EXHAUSTED)
// - MODEL_CAPACITY_EXHAUSTED (UNAVAILABLE)
func TestParseAntigravitySmartRetryInfo_4类_reason(t *testing.T) {
cases := []struct {
name string
status string
reason string
expectModelCapacity bool
expectQuotaExhausted bool
expectInsufficientCredit bool
}{
{
name: "RESOURCE_EXHAUSTED + RATE_LIMIT_EXCEEDED",
status: "RESOURCE_EXHAUSTED",
reason: "RATE_LIMIT_EXCEEDED",
},
{
name: "UNAVAILABLE + MODEL_CAPACITY_EXHAUSTED",
status: "UNAVAILABLE",
reason: "MODEL_CAPACITY_EXHAUSTED",
expectModelCapacity: true,
},
{
name: "RESOURCE_EXHAUSTED + QUOTA_EXHAUSTED",
status: "RESOURCE_EXHAUSTED",
reason: "QUOTA_EXHAUSTED",
expectQuotaExhausted: true,
},
{
name: "RESOURCE_EXHAUSTED + INSUFFICIENT_G1_CREDITS_BALANCE",
status: "RESOURCE_EXHAUSTED",
reason: "INSUFFICIENT_G1_CREDITS_BALANCE",
expectInsufficientCredit: true,
},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
body := buildAntigravityErrorBody(tc.status, tc.reason, "claude-sonnet-4-5", "0.5s")
info := parseAntigravitySmartRetryInfo(body)
require.NotNil(t, info, "应识别 reason=%s", tc.reason)
require.Equal(t, "claude-sonnet-4-5", info.ModelName)
require.Equal(t, tc.expectModelCapacity, info.IsModelCapacityExhausted)
require.Equal(t, tc.expectQuotaExhausted, info.IsQuotaExhausted)
require.Equal(t, tc.expectInsufficientCredit, info.IsInsufficientCredits)
})
}
}
func TestParseAntigravitySmartRetryInfo_未知_reason_返回_nil(t *testing.T) {
body := buildAntigravityErrorBody("RESOURCE_EXHAUSTED", "SOME_UNKNOWN_REASON", "claude-x", "1s")
require.Nil(t, parseAntigravitySmartRetryInfo(body))
}
func TestParseAntigravitySmartRetryInfo_无_modelName_返回_nil(t *testing.T) {
// 有 reason 但 metadata.model 缺失,不应返回有效信息(避免无目标的限流)
body := buildAntigravityErrorBody("RESOURCE_EXHAUSTED", "QUOTA_EXHAUSTED", "", "1s")
require.Nil(t, parseAntigravitySmartRetryInfo(body))
}
// buildAntigravityErrorBody 构造一个 Google RPC 风格的 429/503 错误响应。
func buildAntigravityErrorBody(status, reason, model, retryDelay string) []byte {
errInfo := map[string]any{
"@type": "type.googleapis.com/google.rpc.ErrorInfo",
"reason": reason,
}
if model != "" {
errInfo["metadata"] = map[string]any{"model": model}
}
retryInfo := map[string]any{
"@type": "type.googleapis.com/google.rpc.RetryInfo",
"retryDelay": retryDelay,
}
body := map[string]any{
"error": map[string]any{
"status": status,
"details": []any{errInfo, retryInfo},
},
}
out, _ := json.Marshal(body)
return out
}