package test import ( "context" "fmt" "strconv" "testing" "time" db "queryorchestration/internal/database" "queryorchestration/internal/serviceconfig" "github.com/docker/go-connections/nat" "github.com/stretchr/testify/require" "github.com/testcontainers/testcontainers-go" "github.com/testcontainers/testcontainers-go/wait" ) type CreateDatabaseConfig struct { RunMigrations bool } const ( dbAlias = "postgres" dbPort = 5432 ) func CreateDB(t testing.TB, ctx context.Context, cfg serviceconfig.ConfigProvider, network string, dcfg *CreateDatabaseConfig) testcontainers.Container { port, err := nat.NewPort("tcp", strconv.Itoa(dbPort)) require.NoError(t, err) name := NormaliseAlias(fmt.Sprintf("queryorchestration_%s", t.Name())) pass := "pass" user := "postgres" req := testcontainers.ContainerRequest{ Image: "postgres:17.2-alpine3.21", Name: "postgres_test_queryorchestration", Env: map[string]string{ "POSTGRES_USER": user, "POSTGRES_PASSWORD": pass, }, Cmd: []string{"postgres", "-c", "max_connections=1000"}, ExposedPorts: []string{port.Port()}, WaitingFor: wait.ForAll( wait.ForExposedPort(), wait.ForListeningPort(port), wait.ForLog("database system is ready to accept connections"), wait.ForSQL(port, "postgres", func(host string, port nat.Port) string { return fmt.Sprintf("postgres://%s:%s@%s:%d/postgres?sslmode=disable", user, pass, host, port.Int()) }). WithStartupTimeout(25*time.Second). WithPollInterval(10*time.Second), ), Networks: []string{network}, NetworkAliases: map[string][]string{ network: {dbAlias}, }, } container, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{ ContainerRequest: req, Started: true, Reuse: true, }) require.NoError(t, err) host, err := container.Host(ctx) require.NoError(t, err) mappedPort, err := container.MappedPort(ctx, port) require.NoError(t, err) cfg.SetDBUser(user) cfg.SetDBSecret(pass) cfg.SetDBName(name) cfg.SetDBNoSSL(true) cfg.SetDBHost(host) cfg.SetDBPort(mappedPort.Int()) if dcfg.RunMigrations { err := db.RunMigrations(ctx, cfg) require.NoError(t, err) err = cfg.SetDBPool(ctx) require.NoError(t, err) } return container }