167 lines
6.8 KiB
Go
167 lines
6.8 KiB
Go
package postgres
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
"time"
|
|
|
|
"knowledge-governance/internal/governance"
|
|
)
|
|
|
|
// Exercise the existing SQL against a real disposable PostgreSQL schema.
|
|
// Keep the unbound legacy namespace available to prove history survives
|
|
// while configured targets cannot adopt it.
|
|
func targetTestStore(s *Store, target string) *Store {
|
|
return s.WithLibraryTarget(target)
|
|
}
|
|
|
|
func TestLibraryTargetRejectsForeignEvidenceJobsAndGrants(t *testing.T) {
|
|
legacy, _ := openVersionStore(t)
|
|
a, b := legacy.WithLibraryTarget("target-a"), legacy.WithLibraryTarget("target-b")
|
|
ctx := context.Background()
|
|
now := time.Now().UTC()
|
|
recordPrebackup(t, ctx, a, "internal", "backup-job", "backup", now)
|
|
if err := a.RecordLibraryVersion(ctx, governance.LibraryVersion{ID: "source-seal", Scope: "internal", Kind: governance.LibraryVersionTestSealed, SnapshotID: "source", SourceJobID: "seal-job", CreatedAt: now}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
checks := []struct {
|
|
name string
|
|
run func() bool
|
|
}{
|
|
{"version list", func() bool {
|
|
rows, err := b.LibraryVersions(ctx, "internal", 100)
|
|
return err == nil && len(rows) == 1 && rows[0].Kind == governance.LibraryVersionTestSealed
|
|
}},
|
|
{"exact backup", func() bool {
|
|
_, found, err := b.LibraryVersionByRef(ctx, "internal", governance.LibraryVersionProductionPrebackup, "backup-job", "backup")
|
|
return err == nil && !found
|
|
}},
|
|
{"snapshot version", func() bool {
|
|
_, found, err := b.LibraryVersionOfSnapshot(ctx, "internal", governance.LibraryVersionProductionPrebackup, "backup")
|
|
return err == nil && !found
|
|
}},
|
|
{"provenance", func() bool {
|
|
rows, err := b.LibraryVersionsBySnapshot(ctx, "internal", "backup")
|
|
return err == nil && len(rows) == 0
|
|
}},
|
|
{"snapshot kinds", func() bool {
|
|
rows, err := b.LibrarySnapshotKinds(ctx, "internal", "backup")
|
|
return err == nil && len(rows) == 0
|
|
}},
|
|
{"reuse sources", func() bool {
|
|
rows, err := b.LibraryReuseSources(ctx, "internal", 100)
|
|
return err == nil && len(rows) == 0
|
|
}},
|
|
{"handoff candidates", func() bool {
|
|
rows, err := b.LibrarySnapshotCandidates(ctx, "internal", time.Time{}, "", 100)
|
|
return err == nil && len(rows) == 1 && rows[0].SnapshotID == "source"
|
|
}},
|
|
}
|
|
for _, check := range checks {
|
|
t.Run(check.name, func(t *testing.T) {
|
|
if !check.run() {
|
|
t.Fatal("foreign target evidence was accepted or source seal was hidden")
|
|
}
|
|
})
|
|
}
|
|
job, _, err := a.CreateLibraryJob(ctx, governance.LibraryJob{ID: "target-a-job", Scope: "internal", Kind: governance.LibraryJobSync, IdempotencyKey: "target-a-job", RequestDigest: "digest", TargetSnapshotID: "source"}, governance.SyncStages(), now)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, err := b.LibraryJob(ctx, job.ID); err == nil {
|
|
t.Error("new executor admitted old target job")
|
|
}
|
|
if _, _, err := b.PrepareLibraryJobResume(ctx, job.ID, now); err == nil {
|
|
t.Error("new target resumed old target job")
|
|
}
|
|
grant := governance.LibraryReleaseAuthorization{ID: "grant-a", Scope: "internal", SnapshotID: "source", ParamsDigest: "same-input", AuthorizedBy: "admin", ExpiresAt: now.Add(time.Hour), CreatedAt: now}
|
|
if err := a.CreateLibraryAuthorization(ctx, grant); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, found, err := b.ActiveLibraryAuthorization(ctx, "internal", "source", "same-input", now); err != nil || found {
|
|
t.Errorf("foreign grant accepted: found=%v err=%v", found, err)
|
|
}
|
|
if rows, err := b.LibraryAuthorizations(ctx, "internal", 100); err != nil || len(rows) != 0 {
|
|
t.Errorf("foreign grant listed: rows=%v err=%v", rows, err)
|
|
}
|
|
if err := b.RevokeLibraryAuthorization(ctx, grant.ID, now); err == nil {
|
|
t.Error("foreign grant revoked")
|
|
}
|
|
if _, found, err := a.ActiveLibraryAuthorization(ctx, "internal", "source", "same-input", now); err != nil || !found {
|
|
t.Errorf("original grant must remain valid: found=%v err=%v", found, err)
|
|
}
|
|
}
|
|
|
|
func TestLibraryTargetRejectsForeignOperationReplay(t *testing.T) {
|
|
legacy, _ := openVersionStore(t)
|
|
a, b := legacy.WithLibraryTarget("target-a"), legacy.WithLibraryTarget("target-b")
|
|
ctx := context.Background()
|
|
op := governance.LibraryOperation{ID: "operation", Scope: "internal", Kind: governance.LibraryJobSync, TargetSnapshotID: "snapshot", RequestDigest: "digest", OperationKey: "same-key", CreatedAt: time.Now(), Actor: "admin"}
|
|
if _, _, err := a.EnsureLibraryOperation(ctx, op); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, _, err := b.EnsureLibraryOperation(ctx, op); err == nil {
|
|
t.Error("new target replayed foreign operation")
|
|
}
|
|
if _, err := b.LibraryOperation(ctx, op.ID); err == nil {
|
|
t.Error("new target read foreign operation as its own")
|
|
}
|
|
}
|
|
|
|
func TestLibraryTargetRejectsEventIdentityCollision(t *testing.T) {
|
|
legacy, _ := openVersionStore(t)
|
|
a, b := legacy.WithLibraryTarget("target-a"), legacy.WithLibraryTarget("target-b")
|
|
ctx := context.Background()
|
|
event := governance.LibraryVersion{ID: "same-event", Scope: "internal", Kind: governance.LibraryVersionProductionEffective, SnapshotID: "snapshot", SourceJobID: "job", CreatedAt: time.Now()}
|
|
if err := a.RecordLibraryVersion(ctx, event); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := b.RecordLibraryVersion(ctx, event); err == nil {
|
|
t.Fatal("foreign event collision was silently accepted")
|
|
}
|
|
event.ID = "seal"
|
|
event.Kind = governance.LibraryVersionTestSealed
|
|
if err := a.RecordLibraryVersion(ctx, event); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := b.RecordLibraryVersion(ctx, event); err != nil {
|
|
t.Fatalf("source seal replay must remain independent: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestLibraryTargetSeparatesCurrentAndPreservesLegacy(t *testing.T) {
|
|
legacy, pool := openVersionStore(t)
|
|
a := targetTestStore(legacy, "target-a")
|
|
b := targetTestStore(legacy, "target-b")
|
|
ctx := context.Background()
|
|
now := time.Now().UTC()
|
|
record := func(s *Store, id string, at time.Time) {
|
|
t.Helper()
|
|
if err := s.RecordLibraryVersion(ctx, governance.LibraryVersion{
|
|
ID: id, Scope: "internal", Kind: governance.LibraryVersionProductionEffective,
|
|
SnapshotID: "snapshot-" + id, SourceJobID: "job-" + id, Evidence: map[string]any{"verified": true}, CreatedAt: at,
|
|
}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
record(legacy, "legacy", now)
|
|
if _, found, err := b.LibraryCurrentVersion(ctx, "internal"); err != nil || found {
|
|
t.Fatalf("new target inherited legacy current: found=%v err=%v", found, err)
|
|
}
|
|
record(a, "a", now.Add(time.Second))
|
|
record(b, "b", now.Add(2*time.Second))
|
|
for _, tc := range []struct {
|
|
s *Store
|
|
want string
|
|
}{{legacy, "legacy"}, {a, "a"}, {b, "b"}} {
|
|
got, found, err := tc.s.LibraryCurrentVersion(ctx, "internal")
|
|
if err != nil || !found || got.ID != tc.want || got.SupersededAt != nil {
|
|
t.Fatalf("target current must remain independent: want=%s got=%+v found=%v err=%v", tc.want, got, found, err)
|
|
}
|
|
}
|
|
var count int
|
|
if err := pool.QueryRow(ctx, "SELECT count(*) FROM library_versions").Scan(&count); err != nil || count != 3 {
|
|
t.Fatalf("history changed: count=%d err=%v", count, err)
|
|
}
|
|
}
|