Migrating schemas in docker testcontainers environment using Flyway and Spring boot
Asked Answered
T

1

6

I'm trying to set up testing environment with testcontainers and flyway in spring boot application. All this supposed to run via DinD scheme.

Current test example as follows:

import com.testapp.testapp.entity.TestEntity
import com.testapp.testapp.service.TestService
import org.junit.Test
import org.junit.runner.RunWith
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.context.annotation.Import
import org.springframework.test.context.ContextConfiguration
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner
import org.testcontainers.containers.PostgreSQLContainer
import org.testcontainers.spock.Testcontainers
import spock.lang.Shared
import spock.lang.Specification

@Testcontainers
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@SpringBootTest
@Import([FlywayAutoConfiguration.class])
class ApplicationTests extends Specification {

    @Shared
    PostgreSQLContainer postgreSQLContainer = new PostgreSQLContainer()
            .withDatabaseName("testdb")
            .withUsername("postgres")
            .withPassword("12345")

    @Autowired
    public TestService testappService;

    @Test
    def "entity_created"(){
        given: "init test entity"
        UUID uuid = UUID.randomUUID();
        when: "create test entity"
        def testEntity = TestEntity.builder()
            .id(uuid.toString())
            .description("Test")
            .decimals(9)
            .build()
        testappService.createEntity(testEntity) // <- exception here, no schemas got created in testdb
        then: "compare results"
    }
}

Final version of application.properties file as follows:

embedded.postgresql.enabled=true
embedded.postgresql.database=testdb
spring.datasource.driver-class-name=org.testcontainers.jdbc.ContainerDatabaseDriver
spring.datasource.url=jdbc:tc:postgresql://${embedded.postgresql.host}:${embedded.postgresql.port}/${embedded.postgresql.database}
#spring.datasource.url=jdbc:tc:postgresql:///${embedded.postgresql.database}
spring.datasource.username=${embedded.postgresql.user}
spring.datasource.password=${embedded.postgresql.password}

spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults=false
spring.jpa.open-in-view=false

spring.flyway.enabled=true
spring.flyway.locations=classpath:resources/db.migration

All possible paths spring.flyway.locations tried with no luck (via doc)

docker-compose.yml:

version: '2.4'
services:

  testapp:
    build: .
    ports:
    - "8080:8080"
    environment:
      POSTGRES_ADDRESS: jdbc:postgresql:///testdb
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: 12345
    networks:
    - host_machine
    restart: always

networks:
    host_machine:
        external: true

The output for this test:

2019-10-11 18:06:52.862  INFO 11341 --- [    Test worker] 🐳 [postgres:9.6.12]                     : Creating container for image: postgres:9.6.12
2019-10-11 18:06:52.862  WARN 11341 --- [    Test worker] o.t.utility.RegistryAuthLocator          : Failure when attempting to lookup auth config (dockerImageName: postgres:9.6.12, configFile: /home/user/.docker/config.json. Falling back to docker-java default behaviour. Exception message: /home/user/.docker/config.json (No such file or directory)
2019-10-11 18:06:52.900  INFO 11341 --- [    Test worker] 🐳 [postgres:9.6.12]                     : Starting container with ID: 54abc4af65619d0b5f913ccf4ff956e1439a26b7a494db2688691f9a25fde545
2019-10-11 18:06:53.266  INFO 11341 --- [    Test worker] 🐳 [postgres:9.6.12]                     : Container postgres:9.6.12 is starting: 54abc4af65619d0b5f913ccf4ff956e1439a26b7a494db2688691f9a25fde545
2019-10-11 18:06:56.818  INFO 11341 --- [    Test worker] 🐳 [postgres:9.6.12]                     : Container postgres:9.6.12 started
2019-10-11 18:06:56.869  INFO 11341 --- [    Test worker] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
2019-10-11 18:06:56.923  INFO 11341 --- [    Test worker] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [
    name: default
    ...]
2019-10-11 18:06:56.961  INFO 11341 --- [    Test worker] org.hibernate.Version                    : HHH000412: Hibernate Core {5.3.7.Final}
2019-10-11 18:06:56.963  INFO 11341 --- [    Test worker] org.hibernate.cfg.Environment            : HHH000206: hibernate.properties not found
2019-10-11 18:06:57.060  INFO 11341 --- [    Test worker] o.hibernate.annotations.common.Version   : HCANN000001: Hibernate Commons Annotations {5.0.4.Final}
2019-10-11 18:06:57.156  INFO 11341 --- [    Test worker] org.hibernate.dialect.Dialect            : HHH000400: Using dialect: org.hibernate.dialect.PostgreSQL95Dialect
2019-10-11 18:06:57.172  INFO 11341 --- [    Test worker] o.h.e.j.e.i.LobCreatorBuilderImpl        : HHH000422: Disabling contextual LOB creation as connection was null
2019-10-11 18:06:57.176  INFO 11341 --- [    Test worker] org.hibernate.type.BasicTypeRegistry     : HHH000270: Type registration [java.util.UUID] overrides previous : org.hibernate.type.UUIDBinaryType@a097872
2019-10-11 18:06:57.578  INFO 11341 --- [    Test worker] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2019-10-11 18:06:58.076  INFO 11341 --- [    Test worker] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'asyncExecutor'
2019-10-11 18:06:58.691  INFO 11341 --- [    Test worker] o.s.s.c.ThreadPoolTaskScheduler          : Initializing ExecutorService 'taskScheduler'
2019-10-11 18:06:58.859  INFO 11341 --- [    Test worker] c.testapp.testapp.ApplicationTests       : Started ApplicationTests in 8.976 seconds (JVM running for 17.211)
2019-10-11 18:06:59.037  WARN 11341 --- [    Test worker] o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Error: 0, SQLState: 42P01
2019-10-11 18:06:59.037 ERROR 11341 --- [    Test worker] o.h.engine.jdbc.spi.SqlExceptionHelper   : ERROR: relation "testschema" does not exist
  Position: 376
2019-10-11 18:06:59.045  INFO 11341 --- [    Test worker] o.h.e.internal.DefaultLoadEventListener  : HHH000327: Error performing load command : org.hibernate.exception.SQLGrammarException: could not extract ResultSet

However, same migrations working fine when starting application without tests, so the issue in some interchange between testing components.

I've tried numerous workarounds that popping up in google, but nothing really worked in my case.

Am I supposed to apply some kind of migration strategy myself or maybe there's some unevident configuration issue that could be quickly fixed?

Trichomoniasis answered 11/10, 2019 at 15:11 Comment(0)
V
2

After deep investigating, need to add the following line to properties:

spring.jpa.hibernate.ddl-auto=none

Integration Test removes all data from migration by default. Add the lone above to avoid it.

Ventriloquy answered 3/10, 2020 at 7:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.