91 lines
4.3 KiB
Go
91 lines
4.3 KiB
Go
package diagnostics
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"os"
|
|
"testing"
|
|
|
|
"data-terminal-cloud/internal/audit"
|
|
"data-terminal-cloud/internal/database"
|
|
"data-terminal-cloud/internal/idempotency"
|
|
"data-terminal-cloud/internal/identity"
|
|
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
func TestAcceptanceSnapshotIsAuditedIdempotentAndTenantScoped(t *testing.T) {
|
|
databaseURL := os.Getenv("TEST_DATABASE_URL")
|
|
if databaseURL == "" {
|
|
t.Skip("TEST_DATABASE_URL is not set")
|
|
}
|
|
ctx := context.Background()
|
|
pool, err := database.Open(ctx, databaseURL, "acceptance-snapshot-test")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer pool.Close()
|
|
service, err := NewService(pool, idempotency.NewExecutor(pool), audit.NewRepository())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
admin := identity.Principal{Issuer: "http://localhost:58180/realms/voice-local", Subject: "00000000-0000-0000-0000-000000000101"}
|
|
tenantPublicID := "10000000-0000-0000-0000-000000000010"
|
|
key := "acceptance-snapshot-" + uuid.NewString()
|
|
requestID := "acceptance-snapshot-test-" + uuid.NewString()
|
|
alertID := uuid.NewString()
|
|
missingConversationID := uuid.NewString()
|
|
defer func() {
|
|
_, _ = pool.Exec(context.Background(), `DELETE FROM audit_event WHERE request_id=$1`, requestID)
|
|
_, _ = pool.Exec(context.Background(), `DELETE FROM idempotency_record WHERE idempotency_key=$1`, key)
|
|
_, _ = pool.Exec(context.Background(), `DELETE FROM alert_incident WHERE public_id=$1::uuid`, alertID)
|
|
}()
|
|
if _, err = pool.Exec(ctx, `INSERT INTO alert_incident(public_id,tenant_id,rule_code,category,severity,status,fingerprint,title,summary,resource_type,resource_public_id,first_detected_at,last_detected_at) VALUES($1::uuid,'10000000-0000-0000-0000-000000000001'::uuid,'ACCEPTANCE_SNAPSHOT_TEST','TECHNICAL','HIGH','OPEN',$2,'验收快照合成阻断','验证缺失资源定位','conversation',$3::uuid,now(),now())`, alertID, "acceptance-snapshot-test:"+alertID, missingConversationID); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
input := AcceptanceSnapshotInput{
|
|
CandidateVersion: "0.50.0-rc.1",
|
|
BuildDigest: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
|
Environment: "LAB",
|
|
RunType: "REAL_DEVICE_PROVIDER",
|
|
Scope: "本地真实OIDC与平台技术预检",
|
|
RequiredDependencies: []string{
|
|
"oidc_jwks",
|
|
},
|
|
Reason: "生成可归档的阶段8技术验收证据",
|
|
}
|
|
first, created, err := service.ExportAcceptanceSnapshot(ctx, admin, tenantPublicID, key, requestID, input)
|
|
if err != nil || !created {
|
|
t.Fatalf("first=%+v created=%t err=%v", first, created, err)
|
|
}
|
|
if first.ID == "" || first.Database.MigrationVersion < 39 || first.Database.Dirty || first.RedactionPolicy != "ops-acceptance-minimal-v1" || len(first.ExternalDependencies) != 1 || len(first.Gates) != 8 {
|
|
t.Fatalf("unexpected snapshot=%+v", first)
|
|
}
|
|
if first.ExternalDependencies[0].Dependency != "oidc_jwks" || first.ExternalDependencies[0].ServiceName != "api" {
|
|
t.Fatalf("unexpected dependency=%+v", first.ExternalDependencies[0])
|
|
}
|
|
var foundBlockingAlert bool
|
|
for _, item := range first.Alerts.BlockingItems {
|
|
if item.ID == alertID {
|
|
foundBlockingAlert = item.RuleCode == "ACCEPTANCE_SNAPSHOT_TEST" && item.ResourceID == missingConversationID && item.ResourceState == "MISSING"
|
|
}
|
|
}
|
|
if !foundBlockingAlert || first.Alerts.Blocking == 0 || first.Gates[5].Code != "critical_alerts_clear" || first.Gates[5].Satisfied {
|
|
t.Fatalf("blocking alert evidence=%+v gates=%+v", first.Alerts, first.Gates)
|
|
}
|
|
if first.Gates[6].Code != "platform_health_current" || first.PlatformHealth.State == "" {
|
|
t.Fatalf("platform health=%+v gates=%+v", first.PlatformHealth, first.Gates)
|
|
}
|
|
if first.Gates[7].Code != "production_infrastructure_ready" || !first.Gates[7].Satisfied || first.ProductionInfrastructure.Applicable {
|
|
t.Fatalf("production infrastructure=%+v gates=%+v", first.ProductionInfrastructure, first.Gates)
|
|
}
|
|
replayed, createdAgain, err := service.ExportAcceptanceSnapshot(ctx, admin, tenantPublicID, key, requestID, input)
|
|
if err != nil || createdAgain || replayed.ID != first.ID || !replayed.GeneratedAt.Equal(first.GeneratedAt) {
|
|
t.Fatalf("replayed=%+v created=%t err=%v", replayed, createdAgain, err)
|
|
}
|
|
if _, _, err = service.ExportAcceptanceSnapshot(ctx, admin, "20000000-0000-0000-0000-000000000010", "cross-"+key, requestID, input); !errors.Is(err, ErrAccessDenied) {
|
|
t.Fatalf("cross tenant error=%v", err)
|
|
}
|
|
}
|