I have a Spring Boot Test using LocalStackContainer to test my DynamoDB functionality. The init script that I am providing is running but it is erroring out.
Here is the code that creates the container:
private static final DockerImageName LOCALSTACK_IMG_NAME =
DockerImageName.parse("localstack/localstack:3.0.1");
@Container
static LocalStackContainer LOCAL_STACK =
new LocalStackContainer(LOCALSTACK_IMG_NAME)
.withEnv("DEBUG", "1")
.withCopyFileToContainer(MountableFile.forClasspathResource("init-aws.sh"), "/etc/localstack/init/ready.d/")
.withServices(DYNAMODB, S3);
The "init-aws.sh" is the same exact script I use when I run LocalStack from docker-compose which works so I know the syntax is correct.
Here is a sample line from "init-aws.sh":
awslocal dynamodb create-table \
--table-name MyTable \
--attribute-definitions \
<rest omitted>
I have stopped the test in the debugger in one of the tests in able to bring up the docker logs to see what the error is. The script runs but I get the following errors when it attempts to call any of the awslocal lines:
Could not connect to the endpoint URL: "http://<ip>:4566"
Anybody have any hints or suggestions as to what the problem could be and how to fix it?
UPDATE: I am using Spring Cloud AWS. I have added the appropriate property but I am still seeing the same connection error and it is still trying to connect top port 4566:
@DynamicPropertySource
static void overrideProperties(DynamicPropertyRegistry registry) {
registry.add("spring.cloud.aws.region.static", LOCAL_STACK.getRegion()::toString);
registry.add("spring.cloud.aws.credentials.access-key", LOCAL_STACK.getAccessKey()::toString);
registry.add("spring.cloud.aws.credentials.secret-key", LOCAL_STACK.getSecretKey()::toString);
registry.add("spring.cloud.aws.dynamodb.endpoint", LOCAL_STACK.getEndpoint()::toString);
registry.add("spring.cloud.aws.dynamodb.region", LOCAL_STACK.getRegion()::toString);
registry.add("spring.cloud.aws.endpoint", LOCAL_STACK.getEndpoint()::toString);
}
I even added registry.add("aws.dynamodb.endpoint", LOCAL_STACK.getEndpoint()::toString); but I get the same connection error.
I tried your setup, using similar init hooks, with a simple S3 and DynamoDB configuration. I can see the LocalStack container spin up, the resources are created, and I use
LOCAL_STACK.execInContainer("awslocal", "dynamodb", "list-tables")to check on the services. This is working fine.I don't have the full context of your tests, but this is what I think is happening: when your Spring Boot app is starting up for testing, it's looking for the LocalStack container at the wrong endpoint, the one that you configured for local development, and not the one that's being managed by Testcontainers (hence the
<IP>:4566- Testcontainers randomize ports as a best practice, and it would look likehttp://127.0.0.1:57674). I guess your app also has a DynamoDB client that needs configuration. If you're providing these configs based on profiles (dev/test/prod) in anapplication.ymlorapplication.propertiesfile, you'd have to override those endpoints for the testing context. You can provide them at startup through a method like:Additionally, if this is not your situation and your tests are failing due to the fact that your DynamoDB table is not ready, you should use a waiter that allows the method to move forward once the condition is satisfied:
If you're still stuck, please give us more details about your tests or more instructions on reproducing this.