package test import ( "context" "database/sql" "log/slog" "testing" "time" "gitea.michaelthomson.dev/mthomson/habits/internal/migrate" "github.com/testcontainers/testcontainers-go" "github.com/testcontainers/testcontainers-go/modules/postgres" "github.com/testcontainers/testcontainers-go/wait" ) type TestDatabase struct { Db *sql.DB container testcontainers.Container } func NewTestDatabase(tb testing.TB) *TestDatabase { tb.Helper() ctx := context.Background() // create container postgresContainer, err := postgres.Run(ctx, "postgres:16-alpine", postgres.WithDatabase("todo"), postgres.WithUsername("todo"), postgres.WithPassword("password"), testcontainers.WithWaitStrategy( wait.ForLog("database system is ready to accept connections"). WithOccurrence(2). WithStartupTimeout(5*time.Second)), ) if err != nil { tb.Fatalf("Failed to create postgres container, %v", err) } connectionString, err := postgresContainer.ConnectionString(ctx) if err != nil { tb.Fatalf("Failed to get connection string: %v", err) } // create db pool db, err := sql.Open("pgx", connectionString) if err != nil { tb.Fatalf("Failed to open db pool: %v", err) } migrate.Migrate(slog.Default(), db) return &TestDatabase{ Db: db, container: postgresContainer, } } func (tdb *TestDatabase) TearDown() { _ = tdb.container.Terminate(context.Background()) }