testcontainers, hikari and Failed to validate connection org.postgresql.jdbc.PgConnection
Asked Answered
A

4

20

I have a spring boot app. I'm testing it with testcontainers to ensure that the DB (postgres) and the Repository implementation do what they are supposed to do.

I initialise the container with the following and works pretty well.

    @Container
    @SuppressWarnings("rawtypes")
    private static final PostgreSQLContainer POSTGRE_SQL = new PostgreSQLContainer("postgres:9.6")
        .withDatabaseName("xxx")
        .withUsername("xxx")
        .withPassword("xxx");

    static class Initialiser implements ApplicationContextInitializer<ConfigurableApplicationContext> {
        @Override
        public void initialize(ConfigurableApplicationContext applicationContext) {
            TestPropertyValues.of(
                "spring.datasource.url=" + POSTGRE_SQL.getJdbcUrl(),
                "spring.datasource.username=" + POSTGRE_SQL.getUsername(),
                "spring.jpa.hibernate.ddl-auto=create-drop"
            ).applyTo(applicationContext.getEnvironment());
        }
    }

The problem is that while the tests are successful, at the end of the class, when the container gets shutdown I get the following error messages from hikari

[31mWARN [0;39m [36mcom.zaxxer.hikari.pool.PoolBase.isConnectionAlive[0;39m - HikariPool-1 - Failed to validate connection org.postgresql.jdbc.PgConnection@4d728138 (This connection has been closed.). Possibly consider using a shorter maxLifetime value.
[31mWARN [0;39m [36mcom.zaxxer.hikari.pool.PoolBase.isConnectionAlive[0;39m - HikariPool-1 - Failed to validate connection org.postgresql.jdbc.PgConnection@43070a2e (This connection has been closed.). Possibly consider using a shorter maxLifetime value.
[31mWARN [0;39m [36mcom.zaxxer.hikari.pool.PoolBase.isConnectionAlive[0;39m - HikariPool-1 - Failed to validate connection org.postgresql.jdbc.PgConnection@1aa53837 (This connection has been closed.). Possibly consider using a shorter maxLifetime value.
[31mWARN [0;39m [36mcom.zaxxer.hikari.pool.PoolBase.isConnectionAlive[0;39m - HikariPool-1 - Failed to validate connection org.postgresql.jdbc.PgConnection@3d7cffa2 (This connection has been closed.). Possibly consider using a shorter maxLifetime value.
[31mWARN [0;39m [36mcom.zaxxer.hikari.pool.PoolBase.isConnectionAlive[0;39m - HikariPool-1 - Failed to validate connection org.postgresql.jdbc.PgConnection@634e7d8e (This connection has been closed.). Possibly consider using a shorter maxLifetime value.
[31mWARN [0;39m [36mcom.zaxxer.hikari.pool.PoolBase.isConnectionAlive[0;39m - HikariPool-1 - Failed to validate connection org.postgresql.jdbc.PgConnection@18634db3 (This connection has been closed.). Possibly consider using a shorter maxLifetime value.
[31mWARN [0;39m [36mcom.zaxxer.hikari.pool.PoolBase.isConnectionAlive[0;39m - HikariPool-1 - Failed to validate connection org.postgresql.jdbc.PgConnection@2bb4ba08 (This connection has been closed.). Possibly consider using a shorter maxLifetime value.
[31mWARN [0;39m [36mcom.zaxxer.hikari.pool.PoolBase.isConnectionAlive[0;39m - HikariPool-1 - Failed to validate connection org.postgresql.jdbc.PgConnection@71efd133 (This connection has been closed.). Possibly consider using a shorter maxLifetime value.
[31mWARN [0;39m [36mcom.zaxxer.hikari.pool.PoolBase.isConnectionAlive[0;39m - HikariPool-1 - Failed to validate connection org.postgresql.jdbc.PgConnection@61dd608d (This connection has been closed.). Possibly consider using a shorter maxLifetime value.
[31mWARN [0;39m [36mcom.zaxxer.hikari.pool.PoolBase.isConnectionAlive[0;39m - HikariPool-1 - Failed to validate connection org.postgresql.jdbc.PgConnection@6351b7d0 (This connection has been closed.). Possibly consider using a shorter maxLifetime value.

They are not making my test failing and i suspect it happens because the container, and therefore the db, is no longer there and hikari still tries to keep the connection pool alive. so the test to complete takes several seconds while hikari officially complain of failing connection.

I tried playing with, settings hikari properties in the Initialiser like "spring.datasource.hikari.maxLifetime=1" and "spring.datasource.hikari.idleTimeout=1" without any luck.

Any suggestions?

Thank you

Actin answered 17/12, 2019 at 10:18 Comment(2)
did you find an answer eventually?Agora
No I didn't? ☹️Actin
A
20

I had the exact same problem: test passed if I run it individually, but failed when I run it together with other tests.

I found that SpringBootTest is reusing Spring context between tests so there is a common Hikari Pool between tests. But in the background testcontainers killed (after the previous test) a container and created a new one (before the next test). SpringBootTest is not aware of that change resulting in a new Postgres container so Hikari Pool is the same as in the previous test (pointing to already used and currently unavailable port)

In my case adding @DirtiesContext annotation to test helped.

Airscrew answered 29/1, 2021 at 10:5 Comment(1)
thanks a lot, Marcin, this comment saved my day! :D dziękuję bardzo :)Nosebleed
R
1

I had the same issue.

I was reluctant to use @DirtiesContext as I wanted my tests to remain fast.

A solution that worked for me was to start the container only once :

public abstract class IntegrationTest {

    private static final PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>(
        "postgres:16.1-alpine"
    );

    static {
        postgres.start();
    }

    @DynamicPropertySource
    private static void configureProperties(DynamicPropertyRegistry registry) {
        registry.add("spring.datasource.url", postgres::getJdbcUrl);
        registry.add("spring.datasource.username", postgres::getUsername);
        registry.add("spring.datasource.password", postgres::getPassword);
    }
Reward answered 23/3 at 21:22 Comment(1)
The downside: tests are no longer isolated since the database is not implicitly cleaned between tests. However, I find it not difficult to use various test data to prevent tests from interfering or to use @Sql annotation with a script that truncates tables before inserting new test dataReward
C
0

I had the same issue in the question and found that setting the hikari connection timeout of the integration tests helps avoid the delay.

spring:
  datasource:
    hikari:
      connection-timeout: 250
Consideration answered 6/10, 2021 at 11:54 Comment(0)
M
0

I had exactly the same issue and noticed that I also have spring.jpa.hibernate.ddl-auto=create-drop.

It seems that hibernate is trying to drop the tables, but the postgres container is no longer there, hence the connection is no longer there.

I changed it to create since Ryuk-container will delete the Postgres-Container, we don't need to drop our database. And it helped without using @DirtiesContext.

Metz answered 14/2 at 7:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.