Testcontainers start two containers instead of one in Spring boot project
Asked Answered
B

2

6

I'm using Testcontainers 1.15.3 with Spring Boot 2.4 and Junit5. When I run my test, testcontainers starts the first container and execute flyway scripts and then stop the first container. Immediatly a second container is started (without launching flyway scripts). My test fail because the second container does not contain data.

Abstract class:

@ExtendWith({RestDocumentationExtension.class, SpringExtension.class})
@TestPropertySource(locations = "classpath:application-test.properties")
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
public abstract class AbstractIntegrationTest {
//...
}

Test class:

class ClassTest extends AbstractIntegrationTest{
    
    @Test
    void getById () throws Exception {
    //...
    }

}

Property file for test (jdbc url contains jdbc:tc to launch testcontainer):

spring.flyway.locations = classpath:database/structure,classpath:database/data
spring.datasource.url=jdbc:tc:postgresql:13.3:///databasename?TC_INITSCRIPT=file:src/test/resources/database/dataset/add_user.sql

Logs after launching test :

...
...
2021-06-21 12:56:52 [main] INFO  🐳 [postgres:13.3] - Creating container for image: postgres:13.3
2021-06-21 12:56:52 [main] INFO  🐳 [postgres:13.3] - Starting container with ID: 6a41054e8ec0f9045f8db9e945134234458a0e60b6157618f6f139cdf77d0cc4
2021-06-21 12:56:52 [main] INFO  🐳 [postgres:13.3] - Container postgres:13.3 is starting: 6a41054e8ec0f9045f8db9e945134234458a0e60b6157618f6f139cdf77d0cc4
...
...
2021-06-21 12:56:53 [main] INFO  o.f.core.internal.command.DbMigrate - Migrating schema "public" to version "1.1.001 - init structure"
...
...
2021-06-21 12:56:55 [main] INFO  com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Starting...
2021-06-21 12:56:55 [main] INFO  🐳 [postgres:13.3] - Creating container for image: postgres:13.3
2021-06-21 12:56:55 [main] INFO  🐳 [postgres:13.3] - Starting container with ID: f02fccb0706f047918d849f897ce52bf41870a53821663b21212760c779db05f
2021-06-21 12:56:55 [main] INFO  🐳 [postgres:13.3] - Container postgres:13.3 is starting: f02fccb0706f047918d849f897ce52bf41870a53821663b21212760c779db05f

As we see in the logs above, two containers are created.

Could you help me to solve this problem ?

Thank you.

Bimestrial answered 21/6, 2021 at 13:35 Comment(5)
Maybe I’m missing something but I can’t spot the place in your code where testcontainers lib is used in the first place. Can you clarify? – Hackery
testcontainers is automatically used because in the property file above the jdbc url starts with jdbc:tc (tc for testcontainers) – Bimestrial
I suspect a spring initialization problem which causes this loading to be done twice, or maybe a problem with tescontainers – Bimestrial
I have the same issue with Spring Boot 2.5.3 and liquibase, TestContainer 1.16, Junit 5 with multiple datasources – Psycholinguistics
@François-DavidLessard see response below, I hope that helps – Bimestrial
B
3

I found a solution for my case: remove flyway user and password properties to use only spring ones. The duplication of these properties caused the double launch of the datasourse.

Before

spring:
  flyway:
    locations: [ classpath:flyway-scripts ]
    user: xxx
    password: xxx
  datasource:
    url: jdbc:postgresql://localhost:5432/postgres
    username: xxx
    password: xxx

After

spring:
  flyway:
    locations: [ classpath:flyway-scripts ]
  datasource:
    url: jdbc:postgresql://localhost:5432/postgres
    username: xxx
    password: xxx
Bimestrial answered 19/8, 2021 at 8:19 Comment(0)
C
4

The way I fixed it is by adding ?TC_DAEMON=true to the datasource url. (in my case I used postgis, so just replace it with jdbc:tc:postgresql:13.3

spring:
  datasource:
    driver-class-name: org.testcontainers.jdbc.ContainerDatabaseDriver
    url: jdbc:tc:postgis:9.6-2.5:///dbname?TC_DAEMON=true
    username: xxx
    password: xxx
  flyway:
    enabled: true
    locations: 'classpath:db/migration'
    url: ${spring.datasource.url}
    user: ${spring.datasource.username}
    password: ${spring.datasource.password}
    validate-on-migrate: true
Chainplate answered 27/9, 2021 at 10:31 Comment(1)
Adding TC_DAEMON=true to the database url fixed the issue for me. I was already using jdbc:tc:postgresql:13. Thank you. – Achromatism
B
3

I found a solution for my case: remove flyway user and password properties to use only spring ones. The duplication of these properties caused the double launch of the datasourse.

Before

spring:
  flyway:
    locations: [ classpath:flyway-scripts ]
    user: xxx
    password: xxx
  datasource:
    url: jdbc:postgresql://localhost:5432/postgres
    username: xxx
    password: xxx

After

spring:
  flyway:
    locations: [ classpath:flyway-scripts ]
  datasource:
    url: jdbc:postgresql://localhost:5432/postgres
    username: xxx
    password: xxx
Bimestrial answered 19/8, 2021 at 8:19 Comment(0)

© 2022 - 2024 β€” McMap. All rights reserved.