mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-09-24 16:05:44 +08:00
test(billing): tighten DeepSeek V4 fallback assertions; clarify branch comments
Address copilot-pull-request-reviewer feedback on #2157: - billing_service_test.go: extend TestGetFallbackPricing_FamilyMatching with optional expectedOutput / expectedCacheRead fields and assert full Input/Output/CacheRead pricing for all 4 DeepSeek cases (v4-pro, v4-flash, deepseek-chat→flash, deepseek-reasoner→flash), preventing silent regression to 0 output/cache cost. - billing_service.go: rewrite the DeepSeek block comment to explicitly describe its scope (V4 Pro/Flash + chat/reasoner aliases, no unknown-deepseek fallback) and tighten the OpenAI comment to make it unambiguous that it only describes the OpenAI/Codex branch immediately below it.
This commit is contained in:
@@ -362,19 +362,19 @@ func (s *BillingService) getFallbackPricing(model string) *ModelPricing {
|
||||
return s.fallbackPrices["gemini-3.1-pro"]
|
||||
}
|
||||
|
||||
// DeepSeek V4 系列
|
||||
// DeepSeek V4 系列:仅匹配已知 V4 Pro/Flash 与官方兼容别名
|
||||
// (deepseek-chat / deepseek-reasoner → V4 Flash),未知 deepseek-* 型号不回退,避免误计价。
|
||||
if strings.Contains(modelLower, "deepseek-v4-flash") {
|
||||
return s.fallbackPrices["deepseek-v4-flash"]
|
||||
}
|
||||
if strings.Contains(modelLower, "deepseek-v4-pro") {
|
||||
return s.fallbackPrices["deepseek-v4-pro"]
|
||||
}
|
||||
// deepseek-chat / deepseek-reasoner → V4 Flash(官方兼容别名)
|
||||
if strings.Contains(modelLower, "deepseek-chat") || strings.Contains(modelLower, "deepseek-reasoner") {
|
||||
return s.fallbackPrices["deepseek-v4-flash"]
|
||||
}
|
||||
|
||||
// OpenAI 仅匹配已知 GPT-5/Codex 族,避免未知 OpenAI 型号误计价。
|
||||
// OpenAI(GPT-5 / Codex 族):仅匹配已知型号,避免未知 OpenAI 型号误计价。
|
||||
if normalized := normalizeKnownOpenAICodexModel(modelLower); normalized != "" {
|
||||
switch normalized {
|
||||
case "gpt-5.5":
|
||||
|
||||
@@ -332,11 +332,14 @@ func TestCalculateCost_LongContextAppliesMultiplierToCacheCreation5mAnd1h(t *tes
|
||||
func TestGetFallbackPricing_FamilyMatching(t *testing.T) {
|
||||
svc := newTestBillingService()
|
||||
|
||||
// expectedOutput / expectedCacheRead 为 0 时跳过该字段断言(保持与原有用例兼容)。
|
||||
tests := []struct {
|
||||
name string
|
||||
model string
|
||||
expectedInput float64
|
||||
expectNilPricing bool
|
||||
name string
|
||||
model string
|
||||
expectedInput float64
|
||||
expectedOutput float64
|
||||
expectedCacheRead float64
|
||||
expectNilPricing bool
|
||||
}{
|
||||
{name: "empty model", model: " ", expectNilPricing: true},
|
||||
{name: "claude opus 4.6", model: "claude-opus-4.6-20260201", expectedInput: 5e-6},
|
||||
@@ -352,10 +355,34 @@ func TestGetFallbackPricing_FamilyMatching(t *testing.T) {
|
||||
{name: "openai legacy gpt5.1 codex falls back to gpt5.3 codex", model: "gpt-5.1-codex", expectedInput: 1.5e-6},
|
||||
{name: "openai legacy codex mini latest falls back to gpt5.3 codex", model: "codex-mini-latest", expectedInput: 1.5e-6},
|
||||
{name: "openai unknown no fallback", model: "gpt-unknown-model", expectNilPricing: true},
|
||||
{name: "deepseek v4 pro", model: "deepseek-v4-pro", expectedInput: 4.35e-7},
|
||||
{name: "deepseek v4 flash", model: "deepseek-v4-flash", expectedInput: 1.4e-7},
|
||||
{name: "deepseek chat alias → flash", model: "deepseek-chat", expectedInput: 1.4e-7},
|
||||
{name: "deepseek reasoner alias → flash", model: "deepseek-reasoner", expectedInput: 1.4e-7},
|
||||
{
|
||||
name: "deepseek v4 pro",
|
||||
model: "deepseek-v4-pro",
|
||||
expectedInput: 4.35e-7,
|
||||
expectedOutput: 8.7e-7,
|
||||
expectedCacheRead: 3.625e-9,
|
||||
},
|
||||
{
|
||||
name: "deepseek v4 flash",
|
||||
model: "deepseek-v4-flash",
|
||||
expectedInput: 1.4e-7,
|
||||
expectedOutput: 2.8e-7,
|
||||
expectedCacheRead: 2.8e-9,
|
||||
},
|
||||
{
|
||||
name: "deepseek chat alias → flash",
|
||||
model: "deepseek-chat",
|
||||
expectedInput: 1.4e-7,
|
||||
expectedOutput: 2.8e-7,
|
||||
expectedCacheRead: 2.8e-9,
|
||||
},
|
||||
{
|
||||
name: "deepseek reasoner alias → flash",
|
||||
model: "deepseek-reasoner",
|
||||
expectedInput: 1.4e-7,
|
||||
expectedOutput: 2.8e-7,
|
||||
expectedCacheRead: 2.8e-9,
|
||||
},
|
||||
{name: "non supported family", model: "qwen-max", expectNilPricing: true},
|
||||
}
|
||||
|
||||
@@ -368,6 +395,14 @@ func TestGetFallbackPricing_FamilyMatching(t *testing.T) {
|
||||
}
|
||||
require.NotNil(t, pricing)
|
||||
require.InDelta(t, tt.expectedInput, pricing.InputPricePerToken, 1e-12)
|
||||
if tt.expectedOutput != 0 {
|
||||
require.InDelta(t, tt.expectedOutput, pricing.OutputPricePerToken, 1e-12,
|
||||
"OutputPricePerToken mismatch for %s", tt.model)
|
||||
}
|
||||
if tt.expectedCacheRead != 0 {
|
||||
require.InDelta(t, tt.expectedCacheRead, pricing.CacheReadPricePerToken, 1e-14,
|
||||
"CacheReadPricePerToken mismatch for %s", tt.model)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user