testcontainers-java icon indicating copy to clipboard operation
testcontainers-java copied to clipboard

Couchbase container does work as expected when using it with JUnit 5

Open hantsy opened this issue 3 years ago • 5 comments

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

hantsy avatar Nov 14 '21 05:11 hantsy

Hi @hantsy, thanks for reporting. Can you share the logs of the CouchbaseContainer in case of a failing connection?

cc @daschl

kiview avatar Nov 15 '21 08:11 kiview

@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.

daschl avatar Nov 15 '21 15:11 daschl

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,

  1. checkout my examples: https://github.com/hantsy/spring-reactive-sample/blob/master/boot-data-couchbase
  2. and run mvn clean test in the project root.

It will run all the tests and will fail in the second test.

hantsy avatar Nov 16 '21 03:11 hantsy

Facing some problems with couchbase testcontainers and Junit5 too.

lucasmarfe avatar Apr 20 '22 14:04 lucasmarfe

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

hantsy avatar Dec 02 '22 14:12 hantsy

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.

log1.txt log2.txt

eddumelendez avatar Jan 12 '23 22:01 eddumelendez

@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.

couchbase-log.txt

eddumelendez avatar Mar 04 '23 03:03 eddumelendez