feat(pricing): add cucloud and bytedance payg importers
- Add import_cucloud_pricing.go for 联通云 payg 公开价抓取 - Add import_bytedance_pricing.go for 火山引擎/ByteDance Ark 定价导入 - Include test files and sample testdata for both importers - Update plan catalog inventory docs and seeds - Add cucloud pricing importer implementation plan - Align pipeline scripts and smoke gate tests
This commit is contained in:
95
scripts/import_cucloud_pricing_test.go
Normal file
95
scripts/import_cucloud_pricing_test.go
Normal file
@@ -0,0 +1,95 @@
|
||||
//go:build llm_script
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestParseCUCloudPricingBuildsBlendedRecords(t *testing.T) {
|
||||
raw, err := os.ReadFile(filepath.Join("testdata", "cucloud_pricing_sample.html"))
|
||||
if err != nil {
|
||||
t.Fatalf("读取 fixture 失败: %v", err)
|
||||
}
|
||||
|
||||
records, summary, err := parseCUCloudPricingCatalog(string(raw), defaultCUCloudPricingURL)
|
||||
if err != nil {
|
||||
t.Fatalf("parseCUCloudPricingCatalog 返回错误: %v", err)
|
||||
}
|
||||
if len(records) != 4 {
|
||||
t.Fatalf("期望 4 条联通云价格记录,实际 %d", len(records))
|
||||
}
|
||||
if summary.Models != 3 || summary.Records != 4 || summary.Regions != 2 {
|
||||
t.Fatalf("summary 计数错误: %+v", summary)
|
||||
}
|
||||
if !summary.PaygModeConfirmed || summary.PaygPriceTablePublic {
|
||||
t.Fatalf("payg 摘要错误: %+v", summary)
|
||||
}
|
||||
|
||||
recordMap := make(map[string]officialPricingRecord, len(records))
|
||||
for _, record := range records {
|
||||
recordMap[record.ModelName+"|"+record.Region] = record
|
||||
}
|
||||
|
||||
pro := recordMap["DeepSeek-V4-Pro|贵阳基地二区"]
|
||||
if pro.InputPrice != 9.3 || pro.OutputPrice != 9.3 || pro.ProviderName != "DeepSeek" {
|
||||
t.Fatalf("DeepSeek-V4-Pro 记录错误: %+v", pro)
|
||||
}
|
||||
flash := recordMap["DeepSeek-V4-Flash|贵阳基地二区"]
|
||||
if flash.InputPrice != 0.7 || flash.OutputPrice != 0.7 || flash.ProviderName != "DeepSeek" {
|
||||
t.Fatalf("DeepSeek-V4-Flash 记录错误: %+v", flash)
|
||||
}
|
||||
miniWuhan := recordMap["MiniMax-M2.5|武汉四区"]
|
||||
if miniWuhan.InputPrice != 1.1 || miniWuhan.OutputPrice != 1.1 || miniWuhan.ProviderName != "MiniMax" {
|
||||
t.Fatalf("MiniMax-M2.5 武汉记录错误: %+v", miniWuhan)
|
||||
}
|
||||
miniGuiyang := recordMap["MiniMax-M2.5|贵阳基地二区"]
|
||||
if miniGuiyang.InputPrice != 1.1 || miniGuiyang.OutputPrice != 1.1 {
|
||||
t.Fatalf("MiniMax-M2.5 贵阳记录错误: %+v", miniGuiyang)
|
||||
}
|
||||
if _, ok := recordMap["MiniMax-M2.5|上海二十二区"]; ok {
|
||||
t.Fatalf("不支持的区域不应生成记录")
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseCUCloudPricingRequiresBlendedPriceTable(t *testing.T) {
|
||||
raw, err := os.ReadFile(filepath.Join("testdata", "cucloud_pricing_sample.html"))
|
||||
if err != nil {
|
||||
t.Fatalf("读取 fixture 失败: %v", err)
|
||||
}
|
||||
broken := strings.Replace(string(raw), "综合单价9.30元/百万tokens", "综合单价元/百万tokens", 1)
|
||||
if _, _, err := parseCUCloudPricingCatalog(broken, defaultCUCloudPricingURL); err == nil {
|
||||
t.Fatalf("缺少 blended 价格时应返回错误")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRunCUCloudPricingImportDryRunPrintsSummary(t *testing.T) {
|
||||
var out bytes.Buffer
|
||||
err := runCUCloudPricingImport(cucloudPricingImportConfig{
|
||||
URL: defaultCUCloudPricingURL,
|
||||
Fixture: filepath.Join("testdata", "cucloud_pricing_sample.html"),
|
||||
DryRun: true,
|
||||
}, nil, &out)
|
||||
if err != nil {
|
||||
t.Fatalf("runCUCloudPricingImport 返回错误: %v", err)
|
||||
}
|
||||
output := out.String()
|
||||
for _, want := range []string{
|
||||
"source=cucloud-pricing-import",
|
||||
"models=3",
|
||||
"records=4",
|
||||
"regions=2",
|
||||
"operator=Unicom AISP",
|
||||
"payg_mode_confirmed=true",
|
||||
"payg_price_table_public=false",
|
||||
"dry_run=true",
|
||||
} {
|
||||
if !strings.Contains(output, want) {
|
||||
t.Fatalf("输出缺少 %q,实际: %q", want, output)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user