//go:build integration package integrationtest import ( "context" "fmt" "strings" "time" "github.com/alicebob/miniredis/v2" "github.com/testcontainers/testcontainers-go" "github.com/testcontainers/testcontainers-go/modules/minio" "github.com/testcontainers/testcontainers-go/modules/postgres" "github.com/testcontainers/testcontainers-go/wait" ) type infra struct { pgContainer testcontainers.Container minioContainer testcontainers.Container miniredis *miniredis.Miniredis dbURL string s3Endpoint string s3AccessKey string s3SecretKey string redisAddr string } func sharedInfra(ctx context.Context, env Env) (*infra, error) { return startInfra(ctx, env) } func startInfra(ctx context.Context, env Env) (*infra, error) { out := &infra{ dbURL: env.DBURL, s3Endpoint: env.S3Endpoint, s3AccessKey: env.S3AccessKey, s3SecretKey: env.S3SecretKey, redisAddr: env.RedisAddr, } if out.dbURL == "" { pg, err := postgres.Run(ctx, "postgres:16-alpine", postgres.WithDatabase("ultidb_test"), postgres.WithUsername("ulti"), postgres.WithPassword("test"), testcontainers.WithWaitStrategy( wait.ForLog("database system is ready to accept connections"). WithOccurrence(2). WithStartupTimeout(60*time.Second), ), ) if err != nil { return nil, fmt.Errorf("postgres container: %w", err) } out.pgContainer = pg connStr, err := pg.ConnectionString(ctx, "sslmode=disable") if err != nil { return nil, fmt.Errorf("postgres connection string: %w", err) } out.dbURL = connStr } if out.redisAddr == "" { mr, err := miniredis.Run() if err != nil { return nil, fmt.Errorf("miniredis: %w", err) } out.miniredis = mr out.redisAddr = mr.Addr() } if out.s3Endpoint == "" { m, err := minio.Run(ctx, "minio/minio:latest", minio.WithUsername(env.S3AccessKey), minio.WithPassword(env.S3SecretKey), ) if err != nil { return nil, fmt.Errorf("minio container: %w", err) } out.minioContainer = m host, err := m.ConnectionString(ctx) if err != nil { return nil, fmt.Errorf("minio endpoint: %w", err) } out.s3Endpoint = host } if out.s3AccessKey == "" { out.s3AccessKey = "ultiadmin" } if out.s3SecretKey == "" { out.s3SecretKey = "changeme123" } return out, nil } func (i *infra) Close(ctx context.Context) { if i == nil { return } if i.miniredis != nil { i.miniredis.Close() } if i.pgContainer != nil { _ = i.pgContainer.Terminate(ctx) } if i.minioContainer != nil { _ = i.minioContainer.Terminate(ctx) } } func normalizeEndpoint(endpoint string) string { return strings.TrimPrefix(strings.TrimPrefix(endpoint, "http://"), "https://") }