package repository import ( "context" "os" "testing" "evobgp/internal/db" "evobgp/internal/store" "github.com/google/uuid" ) func TestEnsurePrefixSnapshotFillsEmptyExistingIntegration(t *testing.T) { dsn := os.Getenv("EVOBGP_TEST_DATABASE_URL") if dsn == "" { t.Skip("EVOBGP_TEST_DATABASE_URL not set") } ctx := context.Background() pool, err := db.OpenPostgresPool(ctx, dsn) if err != nil { t.Fatal(err) } defer pool.Close() pg, err := NewPostgres(ctx, pool, false) if err != nil { t.Fatal(err) } hash := normalizeSnapshotHash("sha256:empty-fill-" + uuid.NewString()) snapID := uuid.NewString() if _, err := pool.Exec(ctx, `INSERT INTO prefix_snapshot (id, content_hash) VALUES ($1::uuid, $2)`, snapID, hash); err != nil { t.Fatal(err) } t.Cleanup(func() { _, _ = pool.Exec(ctx, `DELETE FROM prefix_snapshot WHERE id = $1::uuid`, snapID) }) tx, err := pool.Begin(ctx) if err != nil { t.Fatal(err) } defer func() { _ = tx.Rollback(ctx) }() got, err := pg.ensurePrefixSnapshot(ctx, tx, "sha256:"+hash, []store.PrefixRow{ {Prefix: "203.0.113.1/32", Source: "test"}, }) if err != nil { t.Fatal(err) } if got != snapID { t.Fatalf("snap id: got %q want %q", got, snapID) } var rowCount int if err := tx.QueryRow(ctx, `SELECT COUNT(*)::int FROM prefix_snapshot_row WHERE snapshot_id = $1::uuid`, snapID).Scan(&rowCount); err != nil { t.Fatal(err) } if rowCount != 1 { t.Fatalf("row count: got %d", rowCount) } if err := tx.Commit(ctx); err != nil { t.Fatal(err) } } func TestEnsurePrefixSnapshotIdempotentIntegration(t *testing.T) { dsn := os.Getenv("EVOBGP_TEST_DATABASE_URL") if dsn == "" { t.Skip("EVOBGP_TEST_DATABASE_URL not set") } ctx := context.Background() pool, err := db.OpenPostgresPool(ctx, dsn) if err != nil { t.Fatal(err) } defer pool.Close() pg, err := NewPostgres(ctx, pool, false) if err != nil { t.Fatal(err) } contentHash := "sha256:idempotent-" + uuid.NewString() prefixes := []store.PrefixRow{{Prefix: "198.51.100.0/24", Source: "test"}} tx1, err := pool.Begin(ctx) if err != nil { t.Fatal(err) } id1, err := pg.ensurePrefixSnapshot(ctx, tx1, contentHash, prefixes) if err != nil { t.Fatal(err) } if err := tx1.Commit(ctx); err != nil { t.Fatal(err) } t.Cleanup(func() { _, _ = pool.Exec(ctx, `DELETE FROM prefix_snapshot WHERE id = $1::uuid`, id1) }) tx2, err := pool.Begin(ctx) if err != nil { t.Fatal(err) } defer func() { _ = tx2.Rollback(ctx) }() id2, err := pg.ensurePrefixSnapshot(ctx, tx2, contentHash, prefixes) if err != nil { t.Fatal(err) } if id1 != id2 { t.Fatalf("ids differ: %q vs %q", id1, id2) } var rowCount int if err := tx2.QueryRow(ctx, `SELECT COUNT(*)::int FROM prefix_snapshot_row WHERE snapshot_id = $1::uuid`, id1).Scan(&rowCount); err != nil { t.Fatal(err) } if rowCount != 1 { t.Fatalf("expected 1 row, got %d", rowCount) } }