package test import ( "bufio" "context" "fmt" "log/slog" "strconv" "testing" "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 Container struct { Container testcontainers.Container URI string } type containerConfig struct { Name string Cfg serviceconfig.ConfigProvider Network *testcontainers.DockerNetwork Env map[string]string WaitForMsg string ExposedPorts []nat.Port } func createContainer(t testing.TB, ctx context.Context, cfg *containerConfig) (testcontainers.Container, func()) { env := map[string]string{ "PGUSER": cfg.Cfg.GetDBUser(), "PGPASSWORD": cfg.Cfg.GetDBSecret(), "PGHOST": cfg.Cfg.GetDBHost(), "PGDATABASE": cfg.Cfg.GetDBName(), "PGPORT": strconv.Itoa(cfg.Cfg.GetDBPort()), "DB_NOSSL": strconv.FormatBool(cfg.Cfg.IsDBNoSSL()), "AWS_ACCESS_KEY_ID": cfg.Cfg.GetAWSKeyID(), "AWS_SECRET_ACCESS_KEY": cfg.Cfg.GetAWSSecretKey(), "AWS_REGION": cfg.Cfg.GetAWSRegion(), "AWS_DEFAULT_REGION": cfg.Cfg.GetAWSRegion(), "AWS_ENDPOINT_URL": cfg.Cfg.GetAWSEndpoint(), "AWS_ENDPOINT_URL_SQS": cfg.Cfg.GetAWSEndpoint(), "AWS_ENDPOINT_URL_S3": cfg.Cfg.GetAWSEndpoint(), "AWS_S3_USE_PATH_STYLE": strconv.FormatBool(true), } if cfg.Env != nil { for k, v := range cfg.Env { env[k] = v } } req := testcontainers.ContainerRequest{ Image: "queryorchestration:latest", Env: env, Networks: []string{cfg.Network.Name}, WaitingFor: wait.ForLog(cfg.WaitForMsg), Entrypoint: []string{fmt.Sprintf("./%s", cfg.Name)}, } if len(cfg.ExposedPorts) > 0 { ports := make([]string, len(cfg.ExposedPorts)) for index, port := range cfg.ExposedPorts { ports[index] = port.Port() } req.ExposedPorts = ports } container, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{ ContainerRequest: req, Started: true, }) if err != nil { logs, _ := container.Logs(ctx) defer logs.Close() scanner := bufio.NewScanner(logs) for scanner.Scan() { line := scanner.Text() slog.Error(line) } require.NoError(t, err) } return container, func() { err := container.Terminate(ctx) if err != nil { t.Error(err) } } }