Files
2026-08-15 22:31:12 +08:00

92 lines
3.0 KiB
Go

package pricing_test
import (
"testing"
"billing/internal/pricing"
)
func testPolicy() pricing.Policy {
return pricing.Policy{
Model: "gpt-5.6-sol",
Base: pricing.Rates{
InputMicrosPer1M: 2_500_000,
CacheReadMicrosPer1M: 250_000,
CacheWriteMicrosPer1M: 3_125_000,
OutputMicrosPer1M: 15_000_000,
},
LongContext: &pricing.LongContext{
ThresholdInputTokens: 272_000,
Comparison: "gt",
Rates: pricing.Rates{
InputMicrosPer1M: 5_000_000,
CacheReadMicrosPer1M: 500_000,
CacheWriteMicrosPer1M: 6_250_000,
OutputMicrosPer1M: 22_500_000,
},
},
FastPricingEnabled: true,
FastMultiplier: pricing.Ratio{Numerator: 5, Denominator: 2},
}
}
func TestCalculateUsesEachTokenBucketOnce(t *testing.T) {
result, err := pricing.Calculate(testPolicy(), pricing.Usage{
InputTokens: 1_000_000, CacheReadTokens: 400_000, CacheWriteTokens: 100_000, OutputTokens: 500_000,
})
if err != nil {
t.Fatal(err)
}
// The request is above the threshold, so all buckets use long-context rates.
if result.CostMicros != 14_575_000 || result.PriceTier != "long_context" || result.FastApplied {
t.Fatalf("unexpected result: %+v", result)
}
}
func TestCalculateCanDisableFastPricingWithoutChangingRequestMode(t *testing.T) {
policy := testPolicy()
policy.FastPricingEnabled = false
result, err := pricing.Calculate(policy, pricing.Usage{InputTokens: 100_000, OutputTokens: 10_000, ServiceTier: "priority"})
if err != nil {
t.Fatal(err)
}
if result.CostMicros != 400_000 || !result.FastRequested || result.FastApplied || result.MultiplierNumerator != 1 || result.MultiplierDenominator != 1 {
t.Fatalf("unexpected disabled Fast pricing result: %+v", result)
}
}
func TestCalculateRecognizesPassedFastSpeed(t *testing.T) {
result, err := pricing.Calculate(testPolicy(), pricing.Usage{InputTokens: 100_000, Speed: "fast"})
if err != nil {
t.Fatal(err)
}
if !result.FastRequested || !result.FastApplied || result.CostMicros != 625_000 {
t.Fatalf("unexpected speed=fast result: %+v", result)
}
}
func TestCalculateUsesStrictThresholdAndAppliesFastOnce(t *testing.T) {
policy := testPolicy()
base, err := pricing.Calculate(policy, pricing.Usage{InputTokens: 272_000, OutputTokens: 10_000, ServiceTier: "priority"})
if err != nil {
t.Fatal(err)
}
if base.PriceTier != "base" || base.CostMicros != 2_075_000 || !base.FastApplied || base.MultiplierNumerator != 5 || base.MultiplierDenominator != 2 {
t.Fatalf("unexpected threshold result: %+v", base)
}
long, err := pricing.Calculate(policy, pricing.Usage{InputTokens: 272_001, OutputTokens: 10_000, ServiceTier: "priority"})
if err != nil {
t.Fatal(err)
}
if long.PriceTier != "long_context" || long.CostMicros != 3_962_513 {
t.Fatalf("unexpected long-context result: %+v", long)
}
}
func TestCalculateRejectsOverlappingCacheCounts(t *testing.T) {
_, err := pricing.Calculate(testPolicy(), pricing.Usage{InputTokens: 10, CacheReadTokens: 8, CacheWriteTokens: 3})
if err == nil {
t.Fatal("overlapping cache counts unexpectedly accepted")
}
}