Roger Frauca Cordoba
Roger Frauca Cordoba

Reputation: 101

Issue with Testcontainers @ServiceConnection in AbstractIntegrationTest When Running Multiple Test Classes

I'm experiencing an issue with my integration tests using Testcontainers and the new @ServiceConnection annotation. I have an abstract class AbstractIntegrationTest which is extended by multiple test classes. The relevant code is as follows:

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
@Testcontainers
@ActiveProfiles("test")
public abstract class AbstractIntegrationTest {

    @Autowired protected MockMvc client;
    @Autowired ObjectMapper mapper;

    @Container
    @ServiceConnection
    static PostgreSQLContainer<?> postgresDB = new PostgreSQLContainer<>("postgres:16.3");
}

When I run each test class individually, they pass without any issues. However, when I run all test classes together, only the first test class executes successfully while the subsequent ones fail with the following error logs:

2024-05-21T22:53:27.678+02:00  INFO 369738 --- [    Test worker] tc.postgres:16.3                         : Creating container for image: postgres:16.3
2024-05-21T22:53:27.703+02:00  INFO 369738 --- [    Test worker] tc.postgres:16.3                         : Container postgres:16.3 is starting: 2214d73f09c3600beeadbd6a9031473e2dae9526c987991371a9f4fd22af5c59
2024-05-21T22:53:28.932+02:00  INFO 369738 --- [    Test worker] tc.postgres:16.3                         : Container postgres:16.3 started in PT1.253347718S
2024-05-21T22:53:28.932+02:00  INFO 369738 --- [    Test worker] tc.postgres:16.3                         : Container is started (JDBC URL: jdbc:postgresql://localhost:32779/test?loggerLevel=OFF)
2024-05-21T22:53:29.044+02:00  WARN 369738 --- [    Test worker] com.zaxxer.hikari.pool.PoolBase          : HikariPool-1 - Failed to validate connection org.postgresql.jdbc.PgConnection@5c2ae7d7 (This connection has been closed.). Possibly consider using a shorter maxLifetime value.
2024-05-21T22:53:29.045+02:00  WARN 369738 --- [    Test worker] com.zaxxer.hikari.pool.PoolBase          : HikariPool-1 - Failed to validate connection org.postgresql.jdbc.PgConnection@7e122a87 (This connection has been closed.). Possibly consider using a shorter maxLifetime value.
.
.
.
.
2024-05-21T22:53:59.046+02:00 ERROR 369738 --- [    Test worker] o.h.engine.jdbc.spi.SqlExceptionHelper   : Connection to localhost:32778 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.

The port in the error message is one less than the port where the container is started. It seems that the @ServiceConnection is not refreshing with the new Docker initialization. I suspect the issue is related to the service connection not being updated properly or the Docker container reinitializing. Ideally, I would like to prevent the Docker container from reinitializing or ensure that the service connection refreshes correctly, but I haven't found a way to achieve either.

I have tried using the withReuse(true) method with no success:

@Container
@ServiceConnection
static PostgreSQLContainer<?> postgresDB = new PostgreSQLContainer<>("postgres:16.3").withReuse(true);

If I avoid using the @ServiceConnection annotation, there are workarounds that may help, but I prefer to utilize this new functionality. How can I resolve this issue while keeping @ServiceConnection in place?

Any insights or solutions would be greatly appreciated!

Upvotes: 0

Views: 1087

Answers (1)

Roger Frauca Cordoba
Roger Frauca Cordoba

Reputation: 101

I managed to solve the issue by moving the Testcontainers configuration into a separate configuration class and removing the static container. This prevents the container from being reinstantiated for each test class. Here’s what I did:

First, I created a configuration class:

@TestConfiguration
public class TestContainersConfiguration {

    @Bean
    @ServiceConnection
    public PostgreSQLContainer<?> postgresDB() {
        return new PostgreSQLContainer<>("postgres:16.3");
    }
}

Then, I updated the AbstractIntegrationTest class to import this configuration:

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
@Testcontainers
@ActiveProfiles("test")
@Import(TestContainersConfiguration.class)
public abstract class AbstractIntegrationTest {

    @Autowired protected MockMvc client;
    @Autowired ObjectMapper mapper;

    // Removed the static container
}

I found the answer here: Testcontainers start first test so long.

Upvotes: 0

Related Questions