proxy-pool/internal/adapters/postgresadmin/testpostgres_test.go

99 lines
2.7 KiB
Go

//go:build integration
package postgresadmin
import (
"context"
"fmt"
"os"
"sync"
"sync/atomic"
"testing"
"time"
"github.com/jackc/pgx/v5"
"github.com/jackc/pgx/v5/pgxpool"
"proxy-pool/internal/domain/adminstate"
)
var postgresTestSchemaSequence atomic.Uint64
type postgresTestFixture struct {
Store adminstate.Store
Pool *pgxpool.Pool
Schema string
Cleanup func()
}
func newPostgresTestFixture(t *testing.T) postgresTestFixture {
t.Helper()
postgresURL := os.Getenv("PROXY_POOL_TEST_POSTGRES_URL")
if postgresURL == "" {
t.Skip("PROXY_POOL_TEST_POSTGRES_URL is not set")
}
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
adminConfig, err := pgxpool.ParseConfig(postgresURL)
if err != nil {
t.Fatalf("parse PROXY_POOL_TEST_POSTGRES_URL: %v", err)
}
adminPool, err := pgxpool.NewWithConfig(ctx, adminConfig)
if err != nil {
t.Fatalf("connect test PostgreSQL: %v", err)
}
if err := adminPool.Ping(ctx); err != nil {
adminPool.Close()
t.Fatalf("ping test PostgreSQL: %v", err)
}
schema := fmt.Sprintf("it_%d_%d_%d", os.Getpid(), time.Now().UnixNano(), postgresTestSchemaSequence.Add(1))
quotedSchema := pgx.Identifier{schema}.Sanitize()
if _, err := adminPool.Exec(ctx, "CREATE SCHEMA "+quotedSchema); err != nil {
adminPool.Close()
t.Fatalf("create isolated PostgreSQL schema: %v", err)
}
testConfig, err := pgxpool.ParseConfig(postgresURL)
if err != nil {
adminPool.Close()
t.Fatalf("parse isolated PostgreSQL config: %v", err)
}
testConfig.ConnConfig.RuntimeParams["search_path"] = schema
testPool, err := pgxpool.NewWithConfig(ctx, testConfig)
if err != nil {
_, _ = adminPool.Exec(context.Background(), "DROP SCHEMA "+quotedSchema+" CASCADE")
adminPool.Close()
t.Fatalf("connect isolated PostgreSQL schema: %v", err)
}
if err := ApplyMigrations(ctx, testPool); err != nil {
testPool.Close()
_, _ = adminPool.Exec(context.Background(), "DROP SCHEMA "+quotedSchema+" CASCADE")
adminPool.Close()
t.Fatalf("apply PostgreSQL migrations: %v", err)
}
store, err := New(testPool)
if err != nil {
testPool.Close()
_, _ = adminPool.Exec(context.Background(), "DROP SCHEMA "+quotedSchema+" CASCADE")
adminPool.Close()
t.Fatalf("construct PostgreSQL adapter: %v", err)
}
var cleanupOnce sync.Once
cleanup := func() {
cleanupOnce.Do(func() {
testPool.Close()
cleanupCtx, cleanupCancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cleanupCancel()
if _, err := adminPool.Exec(cleanupCtx, "DROP SCHEMA "+quotedSchema+" CASCADE"); err != nil {
t.Errorf("drop isolated PostgreSQL schema: %v", err)
}
adminPool.Close()
})
}
t.Cleanup(cleanup)
return postgresTestFixture{Store: store, Pool: testPool, Schema: schema, Cleanup: cleanup}
}