Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions cmd/apply/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/pgschema/pgschema/cmd/util"
"github.com/pgschema/pgschema/internal/fingerprint"
"github.com/pgschema/pgschema/internal/plan"
"github.com/pgschema/pgschema/internal/postgres"
"github.com/pgschema/pgschema/internal/version"
"github.com/pgschema/pgschema/ir"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -89,7 +90,7 @@ type ApplyConfig struct {
//
// If config.File is provided, embeddedPG is used to generate the plan.
// The caller is responsible for managing the embeddedPG lifecycle (creation and cleanup).
func ApplyMigration(config *ApplyConfig, embeddedPG *util.EmbeddedPostgres) error {
func ApplyMigration(config *ApplyConfig, embeddedPG *postgres.EmbeddedPostgres) error {
var migrationPlan *plan.Plan
var err error

Expand Down Expand Up @@ -253,7 +254,7 @@ func RunApply(cmd *cobra.Command, args []string) error {
ApplicationName: applyApplicationName,
}

var embeddedPG *util.EmbeddedPostgres
var embeddedPG *postgres.EmbeddedPostgres
var err error

// If using --plan flag, load plan from JSON file
Expand Down
188 changes: 139 additions & 49 deletions cmd/apply/apply_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,29 @@ package apply

import (
"context"
"database/sql"
"os"
"path/filepath"
"strings"
"testing"

embeddedpostgres "github.com/fergusstrange/embedded-postgres"
planCmd "github.com/pgschema/pgschema/cmd/plan"
"github.com/pgschema/pgschema/cmd/util"
"github.com/pgschema/pgschema/internal/plan"
"github.com/pgschema/pgschema/internal/postgres"
"github.com/pgschema/pgschema/testutil"
)

var (
// sharedEmbeddedPG is a shared embedded PostgreSQL instance used across all integration tests
// to significantly improve test performance by avoiding repeated startup/teardown
sharedEmbeddedPG *util.EmbeddedPostgres
sharedEmbeddedPG *postgres.EmbeddedPostgres
)

// TestMain sets up shared resources for all tests in this package
func TestMain(m *testing.M) {
// Create shared embedded postgres instance for all integration tests
// This dramatically improves test performance by reusing the same instance
sharedEmbeddedPG = util.SetupSharedEmbeddedPostgres(nil, embeddedpostgres.PostgresVersion("17.5.0"))
sharedEmbeddedPG = testutil.SetupPostgres(nil)
defer sharedEmbeddedPG.Stop()

// Run tests
Expand Down Expand Up @@ -62,11 +62,29 @@ func TestApplyCommand_TransactionRollback(t *testing.T) {
var err error

// Start PostgreSQL container
container := testutil.SetupPostgresContainerWithDB(ctx, t, "testdb", "testuser", "testpass")
defer container.Terminate(ctx, t)
embeddedPG := testutil.SetupPostgres(t)
defer embeddedPG.Stop()
conn, host, port, dbname, user, password := testutil.ConnectToPostgres(t, embeddedPG)
defer conn.Close()

// Create container struct to match old API for minimal changes
container := &struct {
Conn *sql.DB
Host string
Port int
DBName string
User string
Password string
}{
Conn: conn,
Host: host,
Port: port,
DBName: dbname,
User: user,
Password: password,
}

// Setup database with initial schema
conn := container.Conn

initialSQL := `
CREATE TABLE users (
Expand Down Expand Up @@ -138,9 +156,9 @@ func TestApplyCommand_TransactionRollback(t *testing.T) {
planConfig := &planCmd.PlanConfig{
Host: containerHost,
Port: portMapped,
DB: "testdb",
User: "testuser",
Password: "testpass",
DB: container.DBName,
User: container.User,
Password: container.Password,
Schema: "public",
File: desiredStateFile,
ApplicationName: "pgschema",
Expand Down Expand Up @@ -197,9 +215,9 @@ func TestApplyCommand_TransactionRollback(t *testing.T) {
applyConfig := &ApplyConfig{
Host: containerHost,
Port: portMapped,
DB: "testdb",
User: "testuser",
Password: "testpass",
DB: container.DBName,
User: container.User,
Password: container.Password,
Schema: "public",
Plan: migrationPlan, // Use pre-generated plan with injected failure
AutoApprove: true,
Expand Down Expand Up @@ -319,11 +337,29 @@ func TestApplyCommand_CreateIndexConcurrently(t *testing.T) {
var err error

// Start PostgreSQL container
container := testutil.SetupPostgresContainerWithDB(ctx, t, "testdb", "testuser", "testpass")
defer container.Terminate(ctx, t)
embeddedPG := testutil.SetupPostgres(t)
defer embeddedPG.Stop()
conn, host, port, dbname, user, password := testutil.ConnectToPostgres(t, embeddedPG)
defer conn.Close()

// Create container struct to match old API for minimal changes
container := &struct {
Conn *sql.DB
Host string
Port int
DBName string
User string
Password string
}{
Conn: conn,
Host: host,
Port: port,
DBName: dbname,
User: user,
Password: password,
}

// Setup database with initial schema
conn := container.Conn

initialSQL := `
CREATE TABLE users (
Expand Down Expand Up @@ -375,9 +411,9 @@ func TestApplyCommand_CreateIndexConcurrently(t *testing.T) {
planConfig := &planCmd.PlanConfig{
Host: containerHost,
Port: portMapped,
DB: "testdb",
User: "testuser",
Password: "testpass",
DB: container.DBName,
User: container.User,
Password: container.Password,
Schema: "public",
File: desiredStateFile,
ApplicationName: "pgschema",
Expand Down Expand Up @@ -414,9 +450,9 @@ func TestApplyCommand_CreateIndexConcurrently(t *testing.T) {
applyConfig := &ApplyConfig{
Host: containerHost,
Port: portMapped,
DB: "testdb",
User: "testuser",
Password: "testpass",
DB: container.DBName,
User: container.User,
Password: container.Password,
Schema: "public",
Plan: migrationPlan, // Use pre-generated plan
AutoApprove: true,
Expand Down Expand Up @@ -520,11 +556,29 @@ func TestApplyCommand_WithPlanFile(t *testing.T) {
var err error

// Start PostgreSQL container
container := testutil.SetupPostgresContainerWithDB(ctx, t, "testdb", "testuser", "testpass")
defer container.Terminate(ctx, t)
embeddedPG := testutil.SetupPostgres(t)
defer embeddedPG.Stop()
conn, host, port, dbname, user, password := testutil.ConnectToPostgres(t, embeddedPG)
defer conn.Close()

// Create container struct to match old API for minimal changes
container := &struct {
Conn *sql.DB
Host string
Port int
DBName string
User string
Password string
}{
Conn: conn,
Host: host,
Port: port,
DBName: dbname,
User: user,
Password: password,
}

// Setup database with initial schema
conn := container.Conn

initialSQL := `
CREATE TABLE users (
Expand Down Expand Up @@ -569,9 +623,9 @@ func TestApplyCommand_WithPlanFile(t *testing.T) {
planConfig := &planCmd.PlanConfig{
Host: containerHost,
Port: portMapped,
DB: "testdb",
User: "testuser",
Password: "testpass",
DB: container.DBName,
User: container.User,
Password: container.Password,
Schema: "public",
File: desiredStateFile,
ApplicationName: "pgschema",
Expand All @@ -586,9 +640,9 @@ func TestApplyCommand_WithPlanFile(t *testing.T) {
applyConfig := &ApplyConfig{
Host: containerHost,
Port: portMapped,
DB: "testdb",
User: "testuser",
Password: "testpass",
DB: container.DBName,
User: container.User,
Password: container.Password,
Schema: "public",
Plan: migrationPlan, // Use pre-generated plan
AutoApprove: true,
Expand Down Expand Up @@ -689,11 +743,29 @@ func TestApplyCommand_FingerprintMismatch(t *testing.T) {
var err error

// Start PostgreSQL container
container := testutil.SetupPostgresContainerWithDB(ctx, t, "testdb", "testuser", "testpass")
defer container.Terminate(ctx, t)
embeddedPG := testutil.SetupPostgres(t)
defer embeddedPG.Stop()
conn, host, port, dbname, user, password := testutil.ConnectToPostgres(t, embeddedPG)
defer conn.Close()

// Create container struct to match old API for minimal changes
container := &struct {
Conn *sql.DB
Host string
Port int
DBName string
User string
Password string
}{
Conn: conn,
Host: host,
Port: port,
DBName: dbname,
User: user,
Password: password,
}

// Setup database with initial schema
conn := container.Conn

initialSQL := `
CREATE TABLE users (
Expand Down Expand Up @@ -744,9 +816,9 @@ func TestApplyCommand_FingerprintMismatch(t *testing.T) {
planConfig := &planCmd.PlanConfig{
Host: containerHost,
Port: portMapped,
DB: "testdb",
User: "testuser",
Password: "testpass",
DB: container.DBName,
User: container.User,
Password: container.Password,
Schema: "public",
File: desiredStateFile,
ApplicationName: "pgschema",
Expand Down Expand Up @@ -798,9 +870,9 @@ func TestApplyCommand_FingerprintMismatch(t *testing.T) {
applyConfig := &ApplyConfig{
Host: containerHost,
Port: portMapped,
DB: "testdb",
User: "testuser",
Password: "testpass",
DB: container.DBName,
User: container.User,
Password: container.Password,
Schema: "public",
Plan: migrationPlan, // Use pre-generated plan with old fingerprint
AutoApprove: true,
Expand Down Expand Up @@ -880,11 +952,29 @@ func TestApplyCommand_WaitDirective(t *testing.T) {
var err error

// Start PostgreSQL container
container := testutil.SetupPostgresContainerWithDB(ctx, t, "testdb", "testuser", "testpass")
defer container.Terminate(ctx, t)
embeddedPG := testutil.SetupPostgres(t)
defer embeddedPG.Stop()
conn, host, port, dbname, user, password := testutil.ConnectToPostgres(t, embeddedPG)
defer conn.Close()

// Create container struct to match old API for minimal changes
container := &struct {
Conn *sql.DB
Host string
Port int
DBName string
User string
Password string
}{
Conn: conn,
Host: host,
Port: port,
DBName: dbname,
User: user,
Password: password,
}

// Setup database with initial schema and data
conn := container.Conn

initialSQL := `
CREATE TABLE users (
Expand Down Expand Up @@ -931,9 +1021,9 @@ func TestApplyCommand_WaitDirective(t *testing.T) {
planConfig := &planCmd.PlanConfig{
Host: container.Host,
Port: container.Port,
DB: "testdb",
User: "testuser",
Password: "testpass",
DB: container.DBName,
User: container.User,
Password: container.Password,
Schema: "public",
File: desiredStateFile,
ApplicationName: "pgschema",
Expand All @@ -948,9 +1038,9 @@ func TestApplyCommand_WaitDirective(t *testing.T) {
applyConfig := &ApplyConfig{
Host: container.Host,
Port: container.Port,
DB: "testdb",
User: "testuser",
Password: "testpass",
DB: container.DBName,
User: container.User,
Password: container.Password,
Schema: "public",
Plan: migrationPlan, // Use pre-generated plan
AutoApprove: true,
Expand Down
Loading