Skip to content
Open
Changes from 1 commit
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
50 changes: 27 additions & 23 deletions packages/db/pkg/testutils/db.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package testutils

import (
"context"
"os/exec"
"path/filepath"
"strings"
Expand Down Expand Up @@ -41,6 +40,11 @@ type Database struct {
TestQueries *queries.Queries
}

var (
oneDB *Database
dblock sync.Mutex
)

// SetupDatabase creates a fresh PostgreSQL container with migrations applied
func SetupDatabase(t *testing.T) *Database {
t.Helper()
Expand All @@ -49,6 +53,21 @@ func SetupDatabase(t *testing.T) *Database {
t.Skip("Skipping integration test in short mode")
}

// cheap lookup
if oneDB != nil {
return oneDB
}

dblock.Lock()
defer dblock.Unlock()

// locked lookup
if oneDB != nil {
return oneDB
}

// lookup failed, create new

// Start PostgreSQL container
container, err := postgres.Run(
t.Context(),
Expand All @@ -63,12 +82,6 @@ func SetupDatabase(t *testing.T) *Database {
),
)
require.NoError(t, err, "Failed to start postgres container")
t.Cleanup(func() {
ctx := t.Context()
ctx = context.WithoutCancel(ctx)
err := container.Terminate(ctx)
assert.NoError(t, err)
})

connStr, err := container.ConnectionString(t.Context(), "sslmode=disable")
require.NoError(t, err, "Failed to get connection string")
Comment on lines +93 to 94
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Restore teardown for singleton test Postgres container

The new singleton path starts a postgres.Run container but never registers any termination hook, so once connStr is read the container lifecycle is unmanaged for the rest of the process. This leaks Docker resources whenever testcontainers' reaper is unavailable/disabled (a common CI hardening setting), and repeated package test runs can accumulate orphaned DB containers and fail due to exhausted Docker capacity.

Useful? React with 👍 / 👎.

Expand All @@ -77,34 +90,25 @@ func SetupDatabase(t *testing.T) *Database {
runDatabaseMigrations(t, connStr)

// create test queries client
dbClient, connPool, err := pool.New(t.Context(), connStr, "tests")
dbClient, _, err := pool.New(t.Context(), connStr, "tests")
require.NoError(t, err)
t.Cleanup(func() {
connPool.Close()
})
testQueries := queries.New(dbClient)

// Create app db client
sqlcClient, err := db.NewClient(t.Context(), connStr)
require.NoError(t, err, "Failed to create sqlc client")
t.Cleanup(func() {
err := sqlcClient.Close()
assert.NoError(t, err)
})

// Create the auth db client
authDb, err := authdb.NewClient(t.Context(), connStr, connStr)
require.NoError(t, err, "Failed to create auth db client")
t.Cleanup(func() {
err := authDb.Close()
assert.NoError(t, err)
})

return &Database{
oneDB = &Database{
SqlcClient: sqlcClient,
AuthDb: authDb,
TestQueries: testQueries,
}

return oneDB
}

// gooseMu serializes goose operations across parallel tests.
Expand All @@ -125,18 +129,18 @@ func runDatabaseMigrations(t *testing.T, connStr string) {
gooseMu.Lock()
defer gooseMu.Unlock()

db, err := goose.OpenDBWithDriver("pgx", connStr)
gooseDB, err := goose.OpenDBWithDriver("pgx", connStr)
require.NoError(t, err)
t.Cleanup(func() {
err := db.Close()
err := gooseDB.Close()
assert.NoError(t, err)
})

// run the db migration
err = goose.RunWithOptionsContext(
t.Context(),
"up",
db,
gooseDB,
filepath.Join(repoRoot, "packages", "db", "migrations"),
nil,
)
Expand Down
Loading