testcontainers-java
testcontainers-java copied to clipboard
Couchbase container does work as expected when using it with JUnit 5
I tried to use @TestContainers and @Container to bootstrap a Couchbase in a docker for testing purpose.
@SpringBootTest
@Testcontainers
@ActiveProfiles("test")
class PostRepositoryWithDynamicPropertiesTest {
private static final String COUCHBASE_IMAGE_NAME = "couchbase";
private static final String DEFAULT_IMAGE_NAME = "couchbase/server";
private static final DockerImageName DEFAULT_IMAGE = DockerImageName.parse(COUCHBASE_IMAGE_NAME)
.asCompatibleSubstituteFor(DEFAULT_IMAGE_NAME);
@Container
final static CouchbaseContainer couchbaseContainer = new CouchbaseContainer(DEFAULT_IMAGE)
.withCredentials("Administrator", "password")
.withBucket(new BucketDefinition("demo").withPrimaryIndex(true))
.withStartupTimeout(Duration.ofSeconds(60));
@DynamicPropertySource
static void bindCouchbaseProperties(DynamicPropertyRegistry registry) {
registry.add("spring.couchbase.connection-string", couchbaseContainer::getConnectionString);
registry.add("spring.couchbase.username", couchbaseContainer::getUsername);
registry.add("spring.couchbase.password", couchbaseContainer::getPassword);
registry.add("spring.data.couchbase.bucket-name", () -> "demo");
}
}
When running the application it always refused to connect.
com.couchbase.client.core.deps.io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: no further information: localhost/127.0.0.1:50392
I also used other database with testcontainers, others are not problematic.
And I use an Spring Boot initializer class to bootstrap it manually, it works.
@SpringBootTest
@ContextConfiguration(initializers = PostRepositoryTest.TestContainerInitializer.class)
@ActiveProfiles("test")
class PostRepositoryTest {
static class TestContainerInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
private static final String COUCHBASE_IMAGE_NAME = "couchbase";
private static final String DEFAULT_IMAGE_NAME = "couchbase/server";
private static final DockerImageName DEFAULT_IMAGE = DockerImageName.parse(COUCHBASE_IMAGE_NAME)
.asCompatibleSubstituteFor(DEFAULT_IMAGE_NAME);
@Override
public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
final CouchbaseContainer couchbaseContainer = new CouchbaseContainer(DEFAULT_IMAGE)
.withCredentials("Administrator", "password")
.withBucket(new BucketDefinition("demo").withPrimaryIndex(true))
.withStartupTimeout(Duration.ofSeconds(60));
couchbaseContainer.start();
configurableApplicationContext
.addApplicationListener((ApplicationListener<ContextClosedEvent>) event -> couchbaseContainer.stop());
TestPropertyValues.of(
"spring.couchbase.connection-string=" + couchbaseContainer.getConnectionString(),
"spring.couchbase.username=" + couchbaseContainer.getUsername(),
"spring.couchbase.password=" + couchbaseContainer.getPassword(),
"spring.data.couchbase.bucket-name=demo"
)
.applyTo(configurableApplicationContext.getEnvironment());
}
}
}
Update: I found on the Github actions, sometime the later failed. And always one of them failed. I am not sure the reason. See the github actions log: https://github.com/hantsy/spring-reactive-sample/runs/4199996412?check_suite_focus=true
If I ran the tests one by one, it worked well. I guess there are some clean work not performed in the running tests that affects the further tests.
On Github actions, I have to add scripts to clean the Docker data and run them one by one to make sure it working. see: https://github.com/hantsy/spring-reactive-sample/blob/master/.github/workflows/boot-data-couchbase.yml#L31
cd boot-data-couchbase
mvn -q clean test -Dtest=PostRepositoryWithDynamicPropertiesTest
docker rm $(docker ps -aq) -f
mvn -q clean test -Dtest=PostRepositoryTest
Originally posted by @hantsy in https://github.com/testcontainers/testcontainers-java/discussions/4676
Hi @hantsy, thanks for reporting.
Can you share the logs of the CouchbaseContainer in case of a failing connection?
cc @daschl
@hantsy thanks for raising the issue. Can you tell us more about the tests you are performing? If you say one-by-one they work, then at least the initialization of the container must be working fine. To be clear - the testcontainers lib is not performing any clean-up between the runs, so you have to clean up the state (i.e. clearing data) on your own. Or are you seeing a different issue? From the CI logs above somehow it seems that the SDK cannot connect to the port that is offered.
To be clear - the testcontainers lib is not performing any clean-up between the runs,
It is so weird I have no idea about this.
@daschl I am not sure the exact reason of this. To produce it,
- checkout my examples: https://github.com/hantsy/spring-reactive-sample/blob/master/boot-data-couchbase
- and run
mvn clean testin the project root.
It will run all the tests and will fail in the second test.
Facing some problems with couchbase testcontainers and Junit5 too.
Still encountered issue in the latest testcontainers 1.17.6 and Spring Boot 30.
See: https://github.com/hantsy/spring-reactive-sample/actions/runs/3589943257/jobs/6042847518#step:4:2133
I've been taking a look at this and something it can be noticed among the test execution is some ports provided by testcontainers are being used in both tests. Some of them are 51700, 51696, 51722 which can be found in the logs attached. So, looks like the client is using ports provided during the test execution in both test classes.
@hantsy, In order to do not have troubles with the containers as mentioned before. I had to add @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS) to both test classes. After that the only issue I have is when retrieving information. I'm not a Couchbase expert so not sure what could I miss.
In the log attached. I have enabled the couchbase client logs and if we see the connectionString and the port 64724 used in the first tests is also used in the second one.
Do you mind opening a ticket in spring-data-couchbase? I think that would be the best place to tackle this issue.