fix(billing): 封住发布前计费竞态
ci / verify (pull_request) Failing after 8s
ci / verify (pull_request) Failing after 8s
阻止上游提交状态不明的任务被租约接管后重复执行,并为人工复核保留可操作的结算记录。 将生产提交绑定到当前估价签名,统一复用预处理快照,并补强规则形状、定点溢出与历史规则兼容校验。 已通过 PostgreSQL 16 集成测试、Go 全量测试与静态检查、前端测试与构建、OpenAPI、依赖审计、镜像、迁移、流水线和 SemVer 门禁。
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
package runner
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"math"
|
||||
"testing"
|
||||
|
||||
"github.com/easyai/easyai-ai-gateway/apps/api/internal/store"
|
||||
@@ -16,11 +18,29 @@ func TestFixedAmountPreservesNineDecimalPlaces(t *testing.T) {
|
||||
}
|
||||
|
||||
price := mustFixedAmount(t, "0.000000001")
|
||||
if got, want := price.MulInt(3).String(), "0.000000003"; got != want {
|
||||
product, err := multiplyFixedAmountByInt(price, 3)
|
||||
if err != nil {
|
||||
t.Fatalf("multiply fixed amount: %v", err)
|
||||
}
|
||||
if got, want := product.String(), "0.000000003"; got != want {
|
||||
t.Fatalf("nano amount multiplication=%q, want %q", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFixedAmountOperationsRejectOverflow(t *testing.T) {
|
||||
maximum := fixedAmount(math.MaxInt64)
|
||||
if _, err := multiplyFixedAmountByInt(maximum, 2); !errors.Is(err, errFixedAmountOverflow) {
|
||||
t.Fatalf("multiply overflow error=%v", err)
|
||||
}
|
||||
if _, err := addFixedAmounts(maximum, 1); !errors.Is(err, errFixedAmountOverflow) {
|
||||
t.Fatalf("add overflow error=%v", err)
|
||||
}
|
||||
pricing := resolvedPricing{RuleSetID: "overflow-rule"}
|
||||
if _, err := pricing.calculate("image", maximum, []int{2}); !isPricingUnavailable(err) {
|
||||
t.Fatalf("pricing overflow should be unavailable: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEstimatedOutputTokensUsesAliasesAndCapabilityFallback(t *testing.T) {
|
||||
candidate := store.RuntimeModelCandidate{
|
||||
ModelType: "text_generate",
|
||||
@@ -97,6 +117,27 @@ func TestPricingAvailabilityRequiresExplicitFree(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestPricingWeightsUseFixedPrecisionAndRejectInvalidValues(t *testing.T) {
|
||||
pricing := resolvedPricing{Config: map[string]any{
|
||||
"image": map[string]any{
|
||||
"dynamicWeight": map[string]any{
|
||||
"qualityFactors": map[string]any{"high": "1.123456789", "broken": 0},
|
||||
},
|
||||
},
|
||||
}}
|
||||
weight, err := pricing.weight("image", "qualityWeights", "high")
|
||||
if err != nil || weight.String() != "1.123456789" {
|
||||
t.Fatalf("exact weight=%s err=%v", weight.String(), err)
|
||||
}
|
||||
if _, err := pricing.weight("image", "qualityWeights", "broken"); !isPricingUnavailable(err) {
|
||||
t.Fatalf("invalid configured weight should make pricing unavailable: %v", err)
|
||||
}
|
||||
defaultWeight, err := pricing.weight("image", "qualityWeights", "unconfigured")
|
||||
if err != nil || defaultWeight.String() != "1.000000000" {
|
||||
t.Fatalf("default weight=%s err=%v", defaultWeight.String(), err)
|
||||
}
|
||||
}
|
||||
|
||||
func mustFixedAmount(t *testing.T, value string) fixedAmount {
|
||||
t.Helper()
|
||||
amount, err := parseFixedAmount(value)
|
||||
|
||||
Reference in New Issue
Block a user