feat(acceptance): 建立同构验收与弹性容量体系
实现本地三节点 K3s 同构环境、脱敏生产快照、Gemini 图片和多参考图视频协议模拟、统一验收报告及故障注入。\n\n新增 Worker 容量控制器、资源与连接预算、任务恢复保护,并将生产验收拆分为 validation 执行和人工 CAS 放量。\n\n验证包括 Go 全量测试、PostgreSQL HTTP 集成测试、go vet、OpenAPI、ShellCheck、前端检查、迁移及发布脚本测试。
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,180 @@
|
||||
package acceptancesnapshot
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestSnapshotValidationRejectsSecretsAndDetectsTampering(t *testing.T) {
|
||||
snapshot := validSnapshot(t)
|
||||
if err := Validate(snapshot); err != nil {
|
||||
t.Fatalf("validate fixture: %v", err)
|
||||
}
|
||||
|
||||
tampered := snapshot
|
||||
tampered.Candidates = append([]Candidate(nil), snapshot.Candidates...)
|
||||
tampered.Candidates[0].Platform.Name = "tampered"
|
||||
if err := Validate(tampered); err == nil {
|
||||
t.Fatal("tampered snapshot passed validation")
|
||||
}
|
||||
|
||||
unsafe := snapshot
|
||||
unsafe.Candidates = append([]Candidate(nil), snapshot.Candidates...)
|
||||
unsafe.Candidates[0].Platform.Config = map[string]any{"apiToken": "must-not-leak"}
|
||||
refreshHashes(t, &unsafe)
|
||||
if err := Validate(unsafe); err == nil {
|
||||
t.Fatal("secret-like snapshot field passed validation")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSanitizeMapRemovesCredentialAndProxyFields(t *testing.T) {
|
||||
input := map[string]any{
|
||||
"specType": "gemini",
|
||||
"credentialEnv": "PRODUCTION_TOKEN",
|
||||
"networkProxy": map[string]any{
|
||||
"proxyUrl": "http://user:password@example.invalid",
|
||||
},
|
||||
"requestAssetImageURLFormat": "base64",
|
||||
}
|
||||
got := sanitizeMap(input)
|
||||
if got["specType"] != "gemini" || got["requestAssetImageURLFormat"] != "base64" {
|
||||
t.Fatalf("safe protocol fields were removed: %#v", got)
|
||||
}
|
||||
if _, ok := got["credentialEnv"]; ok {
|
||||
t.Fatal("credentialEnv was not removed")
|
||||
}
|
||||
nested, _ := got["networkProxy"].(map[string]any)
|
||||
if _, ok := nested["proxyUrl"]; ok {
|
||||
t.Fatal("nested proxy URL was not removed")
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecodeRejectsUnknownSnapshotFields(t *testing.T) {
|
||||
snapshot := validSnapshot(t)
|
||||
payload, err := json.Marshal(snapshot)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var object map[string]any
|
||||
if err := json.Unmarshal(payload, &object); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
object["unexpected"] = true
|
||||
payload, _ = json.Marshal(object)
|
||||
if _, err := Decode(payload); err == nil {
|
||||
t.Fatal("snapshot with unknown field decoded successfully")
|
||||
}
|
||||
}
|
||||
|
||||
func validSnapshot(t *testing.T) Snapshot {
|
||||
t.Helper()
|
||||
candidates := []Candidate{
|
||||
{
|
||||
Workload: "gemini_image_edit",
|
||||
Provider: Provider{
|
||||
ProviderKey: "gemini", ProviderCode: "google-gemini",
|
||||
DisplayName: "Gemini", ProviderType: "gemini",
|
||||
CapabilitySchema: map[string]any{}, DefaultRateLimitPolicy: map[string]any{},
|
||||
},
|
||||
BaseModel: BaseModel{
|
||||
CanonicalModelKey: "gemini:image", InvocationName: "gemini-image",
|
||||
ProviderModelName: "gemini-image", ModelType: []string{"image_edit"},
|
||||
DisplayName: "Gemini Image", Capabilities: map[string]any{},
|
||||
BaseBillingConfig: map[string]any{}, DefaultRateLimitPolicy: map[string]any{},
|
||||
RuntimePolicyOverride: map[string]any{}, PricingVersion: 1,
|
||||
},
|
||||
Platform: Platform{
|
||||
Provider: "gemini", PlatformKey: "gemini-production", Name: "Gemini Production",
|
||||
BaseURLPath: "/", AuthType: "api_key", Config: map[string]any{"specType": "gemini"},
|
||||
DefaultPricingMode: "inherit_discount", DefaultDiscountFactor: "1",
|
||||
RetryPolicy: map[string]any{}, RateLimitPolicy: map[string]any{}, Priority: 10,
|
||||
},
|
||||
PlatformModel: PlatformModel{
|
||||
ModelName: "gemini-image", ProviderModelName: "gemini-image",
|
||||
ModelType: []string{"image_edit"}, DisplayName: "Gemini Image",
|
||||
CapabilityOverride: map[string]any{}, Capabilities: map[string]any{},
|
||||
PricingMode: "inherit_discount", BillingConfigOverride: map[string]any{},
|
||||
BillingConfig: map[string]any{}, PermissionConfig: map[string]any{},
|
||||
RetryPolicy: map[string]any{}, RateLimitPolicy: map[string]any{},
|
||||
RuntimePolicyOverride: map[string]any{},
|
||||
},
|
||||
RuntimePolicy: RuntimePolicy{
|
||||
RateLimitPolicy: map[string]any{}, RetryPolicy: map[string]any{},
|
||||
AutoDisablePolicy: map[string]any{}, DegradePolicy: map[string]any{},
|
||||
},
|
||||
PricingRules: []PricingRule{},
|
||||
Metadata: CandidateSource{
|
||||
PlatformID: "00000000-0000-0000-0000-000000000001",
|
||||
PlatformModelID: "00000000-0000-0000-0000-000000000002",
|
||||
BaseModelID: "00000000-0000-0000-0000-000000000003",
|
||||
},
|
||||
},
|
||||
{
|
||||
Workload: "multi_reference_video",
|
||||
Provider: Provider{
|
||||
ProviderKey: "volces", ProviderCode: "volces",
|
||||
DisplayName: "Volces", ProviderType: "volces",
|
||||
CapabilitySchema: map[string]any{}, DefaultRateLimitPolicy: map[string]any{},
|
||||
},
|
||||
BaseModel: BaseModel{
|
||||
CanonicalModelKey: "volces:seedance", InvocationName: "seedance-2-fast",
|
||||
ProviderModelName: "seedance-2-fast", ModelType: []string{"omni_video"},
|
||||
DisplayName: "Seedance", Capabilities: map[string]any{"omni_video": map[string]any{"max_images": 9}},
|
||||
BaseBillingConfig: map[string]any{}, DefaultRateLimitPolicy: map[string]any{},
|
||||
RuntimePolicyOverride: map[string]any{}, PricingVersion: 1,
|
||||
},
|
||||
Platform: Platform{
|
||||
Provider: "volces", PlatformKey: "volces-production", Name: "Volces Production",
|
||||
BaseURLPath: "/", AuthType: "bearer", Config: map[string]any{"specType": "volces"},
|
||||
DefaultPricingMode: "inherit_discount", DefaultDiscountFactor: "1",
|
||||
RetryPolicy: map[string]any{}, RateLimitPolicy: map[string]any{}, Priority: 10,
|
||||
},
|
||||
PlatformModel: PlatformModel{
|
||||
ModelName: "seedance-2-fast", ProviderModelName: "seedance-2-fast",
|
||||
ModelType: []string{"omni_video"}, DisplayName: "Seedance",
|
||||
CapabilityOverride: map[string]any{"omni_video": map[string]any{"max_images": 9}},
|
||||
Capabilities: map[string]any{}, PricingMode: "inherit_discount",
|
||||
BillingConfigOverride: map[string]any{}, BillingConfig: map[string]any{},
|
||||
PermissionConfig: map[string]any{}, RetryPolicy: map[string]any{},
|
||||
RateLimitPolicy: map[string]any{}, RuntimePolicyOverride: map[string]any{},
|
||||
},
|
||||
RuntimePolicy: RuntimePolicy{
|
||||
RateLimitPolicy: map[string]any{}, RetryPolicy: map[string]any{},
|
||||
AutoDisablePolicy: map[string]any{}, DegradePolicy: map[string]any{},
|
||||
},
|
||||
PricingRules: []PricingRule{},
|
||||
Metadata: CandidateSource{
|
||||
PlatformID: "00000000-0000-0000-0000-000000000004",
|
||||
PlatformModelID: "00000000-0000-0000-0000-000000000005",
|
||||
BaseModelID: "00000000-0000-0000-0000-000000000006",
|
||||
},
|
||||
},
|
||||
}
|
||||
snapshot := Snapshot{
|
||||
SchemaVersion: SchemaVersion,
|
||||
Source: Source{
|
||||
ReleaseSHA: "0123456789abcdef0123456789abcdef01234567",
|
||||
CreatedAt: time.Date(2026, 7, 31, 0, 0, 0, 0, time.UTC),
|
||||
},
|
||||
Candidates: candidates,
|
||||
SecretSafe: true,
|
||||
}
|
||||
refreshHashes(t, &snapshot)
|
||||
return snapshot
|
||||
}
|
||||
|
||||
func refreshHashes(t *testing.T, snapshot *Snapshot) {
|
||||
t.Helper()
|
||||
configHash, err := candidateConfigHash(snapshot.Candidates)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
snapshot.Source.ConfigHash = configHash
|
||||
snapshot.SnapshotSHA256 = ""
|
||||
hash, err := snapshotHash(*snapshot)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
snapshot.SnapshotSHA256 = hash
|
||||
}
|
||||
Reference in New Issue
Block a user