99 lines
2.7 KiB
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}
|
|
}
|