package test import ( "fmt" "io" "net/http" "strconv" "sync" "testing" "queryorchestration/internal/serviceconfig/objectstore" "queryorchestration/internal/serviceconfig/queue" "github.com/docker/go-connections/nat" "github.com/stretchr/testify/require" "github.com/testcontainers/testcontainers-go" "github.com/testcontainers/testcontainers-go/wait" ) type AWSContainerConfig struct { ExternalEndpoint string } type AWSConfigProvider interface { queue.ConfigProvider objectstore.ConfigProvider } const ( awsAlias = "localstack" awsPort = 4566 ) var awsLock sync.Mutex func CreateAWSContainer(t testing.TB, cfg AWSConfigProvider, network string) *AWSContainerConfig { port, err := nat.NewPort("tcp", strconv.Itoa(awsPort)) require.NoError(t, err) cfg.SetAWSKeyID("test") cfg.SetAWSSecretKey("test") cfg.SetAWSSessionToken("") cfg.SetAWSRegion("us-east-1") cfg.SetAWSEndpoint(fmt.Sprintf("http://%s:%d", awsAlias, awsPort)) req := testcontainers.ContainerRequest{ Image: "localstack/localstack:4.1.0", Name: "localstack_test_queryorchestration", Env: map[string]string{ "AWS_ACCESS_KEY_ID": cfg.GetAWSKeyID(), "AWS_SECRET_ACCESS_KEY": cfg.GetAWSSecretKey(), "AWS_SESSION_TOKEN": cfg.GetAWSSessionToken(), "AWS_REGION": cfg.GetAWSRegion(), "SERVICES": "s3,sqs", "SKIP_SSL_CERT_DOWNLOAD": "1", "LOCALSTACK_HOST": awsAlias, "SQS_ENDPOINT_STRATEGY": "path", "EAGER_SERVICE_LOADING": "1", "DEBUG": "1", "LS_LOG": "trace", "SQS_CLOUDWATCH_METRICS_REPORT_INTERVAL": "5", }, ExposedPorts: []string{port.Port()}, WaitingFor: wait.ForAll( wait.ForListeningPort(port), wait.ForLog("Ready."), wait.ForHTTP("/_localstack/health"). WithPort(port). WithResponseMatcher(func(body io.Reader) bool { return true }). WithStatusCodeMatcher(func(statusCode int) bool { return statusCode == http.StatusOK }), ), Networks: []string{network}, NetworkAliases: map[string][]string{ network: {awsAlias}, }, } awsLock.Lock() container, err := testcontainers.GenericContainer(t.Context(), testcontainers.GenericContainerRequest{ ContainerRequest: req, Started: true, Reuse: true, }) require.NoError(t, err) host, err := container.Host(t.Context()) require.NoError(t, err) mappedPort, err := container.MappedPort(t.Context(), port) require.NoError(t, err) awsLock.Unlock() awsAddress := fmt.Sprintf("http://%s:%s", host, mappedPort.Port()) return &AWSContainerConfig{ ExternalEndpoint: awsAddress, } }