105 lines
2.9 KiB
Go
105 lines
2.9 KiB
Go
|
|
//go:build llm_script
|
|||
|
|
|
|||
|
|
package main
|
|||
|
|
|
|||
|
|
import (
|
|||
|
|
"bytes"
|
|||
|
|
"errors"
|
|||
|
|
"strings"
|
|||
|
|
"testing"
|
|||
|
|
"time"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
func TestRunPricingSmokeChecksCollectsSummariesAndFailures(t *testing.T) {
|
|||
|
|
checks := []pricingSmokeCheck{
|
|||
|
|
{
|
|||
|
|
Name: "Vertex",
|
|||
|
|
URL: "https://vertex.example/pricing",
|
|||
|
|
Run: func() (string, error) {
|
|||
|
|
return "source=vertex-pricing-import models=4 operator=Google Cloud Vertex AI dry_run=true", nil
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
Name: "Cloudflare",
|
|||
|
|
URL: "https://cloudflare.example/pricing",
|
|||
|
|
Run: func() (string, error) {
|
|||
|
|
return "", errors.New("fetch failed")
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
results := runPricingSmokeChecks(checks, func() time.Time {
|
|||
|
|
return time.UnixMilli(1710000000000)
|
|||
|
|
})
|
|||
|
|
if len(results) != 2 {
|
|||
|
|
t.Fatalf("期望 2 条结果,实际 %d", len(results))
|
|||
|
|
}
|
|||
|
|
if !results[0].Success {
|
|||
|
|
t.Fatalf("期望 Vertex 成功,结果: %+v", results[0])
|
|||
|
|
}
|
|||
|
|
if results[0].ModelCount != 4 {
|
|||
|
|
t.Fatalf("期望 Vertex 模型数为 4,实际 %d", results[0].ModelCount)
|
|||
|
|
}
|
|||
|
|
if results[0].Operator != "Google Cloud Vertex AI" {
|
|||
|
|
t.Fatalf("期望 Vertex operator 解析成功,实际 %q", results[0].Operator)
|
|||
|
|
}
|
|||
|
|
if results[1].Success {
|
|||
|
|
t.Fatalf("期望 Cloudflare 失败,结果: %+v", results[1])
|
|||
|
|
}
|
|||
|
|
if !strings.Contains(results[1].Error, "fetch failed") {
|
|||
|
|
t.Fatalf("期望 Cloudflare 错误被透传,实际 %q", results[1].Error)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func TestRenderPricingSmokeTextReportPrintsSummary(t *testing.T) {
|
|||
|
|
results := []pricingSmokeResult{
|
|||
|
|
{
|
|||
|
|
Name: "Vertex",
|
|||
|
|
URL: "https://vertex.example/pricing",
|
|||
|
|
Source: "vertex-pricing-import",
|
|||
|
|
Operator: "Google Cloud Vertex AI",
|
|||
|
|
ModelCount: 4,
|
|||
|
|
Success: true,
|
|||
|
|
DurationMS: 123,
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
Name: "Perplexity",
|
|||
|
|
URL: "https://perplexity.example/models",
|
|||
|
|
Success: false,
|
|||
|
|
DurationMS: 456,
|
|||
|
|
Error: "unexpected perplexity pricing content",
|
|||
|
|
},
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var out bytes.Buffer
|
|||
|
|
renderPricingSmokeTextReport(&out, results, time.Date(2026, 5, 15, 16, 4, 0, 0, time.FixedZone("CST", 8*3600)))
|
|||
|
|
text := out.String()
|
|||
|
|
for _, want := range []string{
|
|||
|
|
"=== Live Pricing Smoke Report (2026-05-15 16:04) ===",
|
|||
|
|
"PASS Vertex source=vertex-pricing-import models=4 operator=Google Cloud Vertex AI duration_ms=123",
|
|||
|
|
"FAIL Perplexity duration_ms=456 error=unexpected perplexity pricing content",
|
|||
|
|
"Summary: 1 passed, 1 failed",
|
|||
|
|
} {
|
|||
|
|
if !strings.Contains(text, want) {
|
|||
|
|
t.Fatalf("输出缺少 %q,实际: %q", want, text)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func TestParsePricingSmokeSummaryLine(t *testing.T) {
|
|||
|
|
line := "source=cloudflare-pricing-import models=4 operator=Cloudflare Workers AI dry_run=true"
|
|||
|
|
summary, ok := parsePricingSmokeSummaryLine(line)
|
|||
|
|
if !ok {
|
|||
|
|
t.Fatalf("期望成功解析 summary line")
|
|||
|
|
}
|
|||
|
|
if summary.Source != "cloudflare-pricing-import" {
|
|||
|
|
t.Fatalf("source 错误: %q", summary.Source)
|
|||
|
|
}
|
|||
|
|
if summary.ModelCount != 4 {
|
|||
|
|
t.Fatalf("models 错误: %d", summary.ModelCount)
|
|||
|
|
}
|
|||
|
|
if summary.Operator != "Cloudflare Workers AI" {
|
|||
|
|
t.Fatalf("operator 错误: %q", summary.Operator)
|
|||
|
|
}
|
|||
|
|
}
|