package test import ( "bufio" "context" "fmt" "log/slog" "strconv" "testing" "queryorchestration/internal/serviceconfig" "queryorchestration/internal/serviceconfig/objectstore" "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 ContainerConfigProvider interface { serviceconfig.ConfigProvider objectstore.ConfigProvider } type containerConfig struct { Name string Cfg ContainerConfigProvider DownstreamQueues []RunnerName Env map[string]string WaitForMsg string ExposedPorts []nat.Port MockHTTP string } const ( imageTag = "queryorchestration:latest" dockerfilePath = "build/Dockerfile" ) func createContainer(t testing.TB, ctx context.Context, network string, cfg *containerConfig) (testcontainers.Container, func()) { bucket := cfg.Cfg.GetBucket() if bucket == "" { bucket = "invalid-example" } env := map[string]string{ "BUCKET": bucket, "PGUSER": cfg.Cfg.GetDBUser(), "PGPASSWORD": cfg.Cfg.GetDBSecret(), "PGHOST": dbAlias, "PGDATABASE": cfg.Cfg.GetDBName(), "PGPORT": strconv.Itoa(dbPort), "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_ENDPOINT_URL_TEXTRACT": cfg.MockHTTP, "AWS_S3_USE_PATH_STYLE": strconv.FormatBool(true), "DISABLE_AUTH": "true", "LOG_LEVEL": "DEBUG", "COGNITO_USER_POOL_ID": "coguserpoolid", "COGNITO_CLIENT_SECRET": "cogsecret", "COGNITO_DOMAIN": "cogdomain", "COGNITO_CLIENT_ID": "clientid", } if cfg.Env != nil { for k, v := range cfg.Env { env[k] = v } } for _, e := range cfg.DownstreamQueues { env[string(GetRunnerEnvFromName(e))] = GetQueueURL(t, cfg.Cfg, e) } req := testcontainers.ContainerRequest{ Image: imageTag, Env: env, WaitingFor: wait.ForLog(cfg.WaitForMsg), Entrypoint: []string{fmt.Sprintf("./%s", cfg.Name)}, Networks: []string{network}, } 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 { PrintContainerLogs(t, container) require.NoError(t, err) } return container, func() { err := container.Terminate(ctx) if err != nil { t.Error(err) } } } func PrintContainerLogs(t testing.TB, container testcontainers.Container) { if container == nil { return } logs, err := container.Logs(t.Context()) require.NoError(t, err) defer func() { err := logs.Close() require.NoError(t, err) }() scanner := bufio.NewScanner(logs) for scanner.Scan() { line := scanner.Text() slog.Info(line) } }