chore: establish local platform baseline
This commit is contained in:
@@ -0,0 +1,137 @@
|
||||
package opsconfig
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"data-terminal-cloud/internal/audit"
|
||||
"data-terminal-cloud/internal/identity"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
)
|
||||
|
||||
func TestAgentBundleRequiresStandardQualityEvidence(t *testing.T) {
|
||||
databaseURL := os.Getenv("TEST_DATABASE_URL")
|
||||
if databaseURL == "" {
|
||||
t.Skip("TEST_DATABASE_URL is not set")
|
||||
}
|
||||
ctx := context.Background()
|
||||
pool, err := pgxpool.New(ctx, databaseURL)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer pool.Close()
|
||||
service, err := NewService(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"}
|
||||
approver := identity.Principal{Issuer: admin.Issuer, Subject: "00000000-0000-0000-0000-000000000102"}
|
||||
tenantID := "10000000-0000-0000-0000-000000000010"
|
||||
configKey := "integration.agent.bundle." + uuid.NewString()
|
||||
invalidConfigKey := "integration.agent.bundle.invalid." + uuid.NewString()
|
||||
componentPrefix := "integration.agent.component." + uuid.NewString() + "."
|
||||
keys := []string{"agent-bundle-create-" + uuid.NewString(), "agent-bundle-generic-" + uuid.NewString(), "agent-bundle-standard-" + uuid.NewString(), "agent-bundle-invalid-" + uuid.NewString(), "agent-bundle-mismatched-evidence-" + uuid.NewString()}
|
||||
defer func() {
|
||||
_, _ = pool.Exec(ctx, `DELETE FROM audit_event WHERE request_id LIKE 'agent-bundle-%'`)
|
||||
_, _ = pool.Exec(ctx, `DELETE FROM idempotency_record WHERE idempotency_key=ANY($1::text[])`, keys)
|
||||
_, _ = pool.Exec(ctx, `DELETE FROM runtime_config_rollout WHERE config_key=$1`, configKey)
|
||||
_, _ = pool.Exec(ctx, `DELETE FROM ops_config_evaluation WHERE config_version_id IN (SELECT id FROM runtime_config_version WHERE config_key=$1 OR config_key=$2)`, configKey, invalidConfigKey)
|
||||
_, _ = pool.Exec(ctx, `DELETE FROM runtime_config_version WHERE config_key=$1 OR config_key=$2 OR config_key LIKE $3`, configKey, invalidConfigKey, componentPrefix+"%")
|
||||
}()
|
||||
componentIDs := seedPublishedAgentComponents(t, ctx, pool, tenantID, admin.Issuer, admin.Subject, componentPrefix)
|
||||
invalidInput := CreateInput{
|
||||
TenantID: tenantID, ConfigKey: invalidConfigKey, DisplayName: "Agent组件类型错误验证", ConfigKind: "AGENT_BUNDLE",
|
||||
Payload: map[string]any{
|
||||
"persona_version_id": componentIDs["PERSONA"], "voice_version_id": componentIDs["PERSONA"],
|
||||
"model_version_id": componentIDs["MODEL"], "routing_version_id": componentIDs["ROUTING"],
|
||||
}, SecretRefs: map[string]string{}, ChangeSummary: "验证错误类型的组件版本不能提交",
|
||||
}
|
||||
invalidVersion, _, err := service.Create(ctx, admin, keys[3], "agent-bundle-invalid-create", invalidInput)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err = service.Submit(ctx, admin, tenantID, invalidVersion.ID, "agent-bundle-invalid-submit", invalidVersion.RowVersion); !errors.Is(err, ErrInvalid) {
|
||||
t.Fatalf("wrong component kind submit error = %v", err)
|
||||
}
|
||||
input := CreateInput{
|
||||
TenantID: tenantID, ConfigKey: configKey, DisplayName: "Agent质量门禁集成配置", ConfigKind: "AGENT_BUNDLE",
|
||||
Payload: map[string]any{
|
||||
"persona_version_id": componentIDs["PERSONA"], "voice_version_id": componentIDs["VOICE"],
|
||||
"model_version_id": componentIDs["MODEL"], "routing_version_id": componentIDs["ROUTING"],
|
||||
}, SecretRefs: map[string]string{}, ChangeSummary: "验证标准Agent质量证据门禁",
|
||||
}
|
||||
version, _, err := service.Create(ctx, admin, keys[0], "agent-bundle-create", input)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
version, err = service.Submit(ctx, admin, tenantID, version.ID, "agent-bundle-submit", version.RowVersion)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
rollout := RolloutInput{ScopeType: "TENANT", RolloutPercent: 100, MaxConcurrentCalls: 10}
|
||||
if _, _, err = service.CreateEvaluation(ctx, admin, tenantID, version.ID, keys[1], "agent-bundle-generic", EvidenceTypeGeneric, "generic-v1", "PASSED", "artifact://generic.json", map[string]any{"passed": true}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err = service.Publish(ctx, approver, tenantID, version.ID, "agent-bundle-publish-generic", PublishInput{Reason: "通用证据不得放行", Rollout: rollout}, version.RowVersion); !errors.Is(err, ErrPublishGate) {
|
||||
t.Fatalf("generic evidence publish error = %v", err)
|
||||
}
|
||||
metrics := map[string]any{
|
||||
"report_schema": "agent-eval-report-v1", "suite_sha256": "b5cd3b798a01a48ddf0081f2fcc2a917f93681a3ee2fa55bbf4190466de3bef8",
|
||||
"agent_version": "agent-v1", "model_config_ref": "runtime-config-version:" + componentIDs["MODEL"], "config_version_id": version.ID, "environment": "mock", "executed_at": "2026-08-24T10:00:00Z",
|
||||
"cases_total": 10, "cases_passed": 10, "failed_check_count": 0, "conversation_success_rate": 1.0,
|
||||
"first_response_p95_ms": 1200, "interruption_recovery_rate": 1.0, "average_response_chars": 36.5,
|
||||
"salutation_accuracy": 1.0, "memory_accuracy": 1.0, "fabricated_facts": 0,
|
||||
"story_source_completeness": 1.0, "sensitive_information_handling_rate": 1.0,
|
||||
}
|
||||
mismatchedMetrics := make(map[string]any, len(metrics))
|
||||
for key, value := range metrics {
|
||||
mismatchedMetrics[key] = value
|
||||
}
|
||||
mismatchedMetrics["model_config_ref"] = "runtime-config-version:" + componentIDs["VOICE"]
|
||||
if _, _, err = service.CreateEvaluation(ctx, admin, tenantID, version.ID, keys[4], "agent-bundle-mismatched-evidence", EvidenceTypeAgentQualityV1, "agent-quality-mismatched-v1", "PASSED", "artifact://agent-quality-mismatched.json", mismatchedMetrics); !errors.Is(err, ErrInvalid) {
|
||||
t.Fatalf("mismatched model evidence error = %v", err)
|
||||
}
|
||||
evaluation, _, err := service.CreateEvaluation(ctx, admin, tenantID, version.ID, keys[2], "agent-bundle-standard", EvidenceTypeAgentQualityV1, "agent-quality-v1", "PASSED", "artifact://agent-quality.json", metrics)
|
||||
if err != nil || evaluation.EvidenceType != EvidenceTypeAgentQualityV1 {
|
||||
t.Fatalf("standard evaluation = %+v, error = %v", evaluation, err)
|
||||
}
|
||||
version, err = service.Publish(ctx, approver, tenantID, version.ID, "agent-bundle-publish-standard", PublishInput{Reason: "标准质量证据通过", Rollout: rollout}, version.RowVersion)
|
||||
if err != nil || version.Status != "PUBLISHED" {
|
||||
t.Fatalf("published version = %+v, error = %v", version, err)
|
||||
}
|
||||
}
|
||||
|
||||
func seedPublishedAgentComponents(t *testing.T, ctx context.Context, pool *pgxpool.Pool, tenantPublicID, oidcIssuer, oidcSubject, keyPrefix string) map[string]string {
|
||||
t.Helper()
|
||||
components := map[string]struct {
|
||||
payload map[string]any
|
||||
refs map[string]string
|
||||
}{
|
||||
"PERSONA": {payload: map[string]any{"system_prompt": "集成验证人设", "tone": "warm"}, refs: map[string]string{}},
|
||||
"VOICE": {payload: map[string]any{"provider": "local", "voice_resource_ref": "voice://integration/approved"}, refs: map[string]string{"credential_ref": "kms://integration/voice"}},
|
||||
"MODEL": {payload: map[string]any{"provider": "local", "model_id": "model://integration/approved"}, refs: map[string]string{"credential_ref": "kms://integration/model"}},
|
||||
"ROUTING": {payload: map[string]any{"default_engine_mode": "s2s_hybrid", "routes": []any{map[string]any{"goal": "open_conversation", "engine_mode": "s2s_hybrid"}}}, refs: map[string]string{}},
|
||||
}
|
||||
ids := make(map[string]string, len(components))
|
||||
for kind, component := range components {
|
||||
publicID := uuid.NewString()
|
||||
tag, err := pool.Exec(ctx, `
|
||||
INSERT INTO runtime_config_version(public_id,tenant_id,config_key,display_name,config_kind,version_no,status,payload,secret_refs,change_summary,validation_result,created_by,submitted_by,submitted_at,approved_by,approved_at,published_by,published_at)
|
||||
SELECT $1::uuid,t.id,$2,$3,$4,1,'PUBLISHED',$5::jsonb,$6::jsonb,'Agent组合组件引用集成夹具','{"valid":true}'::jsonb,u.id,u.id,now(),u.id,now(),u.id,now()
|
||||
FROM tenant t JOIN user_account u ON u.tenant_id=t.id WHERE t.public_id=$7::uuid AND u.oidc_issuer=$8 AND u.oidc_subject=$9`,
|
||||
publicID, keyPrefix+strings.ToLower(kind), "Agent组件"+kind, kind, mustJSON(component.payload), mustJSON(component.refs), tenantPublicID, oidcIssuer, oidcSubject)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if tag.RowsAffected() != 1 {
|
||||
t.Fatalf("seed %s component affected %d rows", kind, tag.RowsAffected())
|
||||
}
|
||||
ids[kind] = publicID
|
||||
}
|
||||
return ids
|
||||
}
|
||||
Reference in New Issue
Block a user