Files
llm-intelligence/scripts/import_mobile_cloud_pricing_test.go
phamnazage-jpg 5c5578a19b
Some checks failed
CI / go-test (push) Has been cancelled
CI / frontend-build (push) Has been cancelled
CI / docker-build (push) Has been cancelled
feat(region_pricing): 扩展非 token 统一计费字段,支持语音按字符/秒计费
- 新增 region_pricing.pricing_mode / price_unit / flat_price 字段
- 新增 migration 016_region_pricing_non_token_units.sql
- officialPricingRecord 新增 PricingMode/PriceUnit/FlatPrice 字段
- detectModality 新增 audio 模态检测(voice/audio/speech)
- providerMetadata 新增 BAAI/ByteDance/China Mobile 元数据
- import_mobile_cloud_pricing.go: 解析语音计费表(CosyVoice/SenseVoice)
  - CosyVoice: 2元/万字符 → pricingMode=flat, priceUnit=10k_characters
  - SenseVoice: 0.0007元/秒 → pricingMode=flat, priceUnit=second
- mobileCloudProviderName 新增 cosyvoice/sensevoice → Alibaba 映射
- cmd/server: modelResponse 新增 pricingMode/priceUnit/flatPrice,API 字段说明同步更新
- 新增 TestModelsHandlerReturnsFlatPricingFields 测试
2026-05-22 14:51:38 +08:00

90 lines
3.9 KiB
Go
Raw 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 llm_script
package main
import (
"bytes"
"os"
"path/filepath"
"strings"
"testing"
)
func TestResolveMobileCloudPricingArticle(t *testing.T) {
raw := `{"code":200,"data":{"children":[{"articleTitle":"其他文档","articleId":1,"articleContentPublished":"x"},{"children":[{"articleTitle":"预置模型服务-token按量计费","articleId":91592,"articleContentPublished":"64ec46cbfd7c535db501aff43df5a788"}]}]}}`
articleID, contentPublished, err := resolveMobileCloudPricingArticle(raw)
if err != nil {
t.Fatalf("resolveMobileCloudPricingArticle 返回错误: %v", err)
}
if articleID != 91592 || contentPublished != "64ec46cbfd7c535db501aff43df5a788" {
t.Fatalf("解析价格文章失败: articleID=%d contentPublished=%q", articleID, contentPublished)
}
}
func TestParseMobileCloudPricingHTMLBuildsRecords(t *testing.T) {
raw, err := os.ReadFile(filepath.Join("testdata", "mobile_cloud_pricing_sample.html"))
if err != nil {
t.Fatalf("读取 fixture 失败: %v", err)
}
records, err := parseMobileCloudPricingHTML(string(raw), "https://ecloud.10086.cn/op-help-center/doc/article/91592")
if err != nil {
t.Fatalf("parseMobileCloudPricingHTML 返回错误: %v", err)
}
if len(records) != 8 {
t.Fatalf("期望 8 条移动云价格记录,实际 %d", len(records))
}
recordMap := make(map[string]officialPricingRecord, len(records))
for _, record := range records {
recordMap[record.ModelID] = record
}
if recordMap["mobile-cloud-huabei-huhehaote-minimax-m2-5"].Region != "华北-呼和浩特" {
t.Fatalf("华北 MiniMax region 错误: %+v", recordMap["mobile-cloud-huabei-huhehaote-minimax-m2-5"])
}
if recordMap["mobile-cloud-huabei-huhehaote-deepseek-v3-0324"].InputPrice != 2 || recordMap["mobile-cloud-huabei-huhehaote-deepseek-v3-0324"].OutputPrice != 8 {
t.Fatalf("DeepSeek-V3-0324 价格错误: %+v", recordMap["mobile-cloud-huabei-huhehaote-deepseek-v3-0324"])
}
if recordMap["mobile-cloud-huabei-huhehaote-qwq-32b"].ProviderName != "Qwen" || recordMap["mobile-cloud-huabei-huhehaote-qwq-32b"].OutputPrice != 6 {
t.Fatalf("QwQ-32B provider/价格错误: %+v", recordMap["mobile-cloud-huabei-huhehaote-qwq-32b"])
}
if recordMap["mobile-cloud-huabei-huhehaote-bge-m3"].ProviderName != "BAAI" || recordMap["mobile-cloud-huabei-huhehaote-bge-m3"].InputPrice != 0.5 || recordMap["mobile-cloud-huabei-huhehaote-bge-m3"].OutputPrice != 0.5 {
t.Fatalf("bge-m3 平价 token 记录错误: %+v", recordMap["mobile-cloud-huabei-huhehaote-bge-m3"])
}
cosyVoice, ok := recordMap["mobile-cloud-huabei-huhehaote-cosyvoice"]
if !ok {
t.Fatalf("缺少 CosyVoice 语音计费记录")
}
if cosyVoice.ProviderName != "Alibaba" || cosyVoice.Modality != "audio" || cosyVoice.PricingMode != "flat" || cosyVoice.FlatPrice != 2 || cosyVoice.PriceUnit != "10k_characters" {
t.Fatalf("CosyVoice 语音计费记录错误: %+v", cosyVoice)
}
senseVoice, ok := recordMap["mobile-cloud-huabei-huhehaote-sensevoice"]
if !ok {
t.Fatalf("缺少 SenseVoice 语音计费记录")
}
if senseVoice.ProviderName != "Alibaba" || senseVoice.Modality != "audio" || senseVoice.PricingMode != "flat" || senseVoice.FlatPrice != 0.0007 || senseVoice.PriceUnit != "second" {
t.Fatalf("SenseVoice 语音计费记录错误: %+v", senseVoice)
}
}
func TestRunMobileCloudPricingImportDryRunPrintsSummary(t *testing.T) {
var out bytes.Buffer
err := runMobileCloudPricingImport(mobileCloudPricingImportConfig{
OutlineTreeURL: defaultMobileCloudOutlineTreeURL,
Fixture: filepath.Join("testdata", "mobile_cloud_pricing_sample.html"),
DryRun: true,
}, nil, &out)
if err != nil {
t.Fatalf("runMobileCloudPricingImport 返回错误: %v", err)
}
output := out.String()
for _, want := range []string{
"source=mobile-cloud-pricing-import",
"models=8",
"operator=Mobile Cloud",
"dry_run=true",
} {
if !strings.Contains(output, want) {
t.Fatalf("输出缺少 %q实际: %q", want, output)
}
}
}