Search code examples
spring-bootspring-data-jpatestcontainers

Driver:org.testcontainers.jdbc.ContainerDatabaseDriver@27f6854b returned null for URL:jdbc:mariadb://localhost:32785/test


I'm using Testcontainers to test my REST services, by default testcontainers jdbc mmodules (I'm using Mariadb) create a single schema but I need two; so I've created a customized image

FROM mariadb:10
ADD ./docker-entrypoint-initdb.d /docker-entrypoint-initdb.d

in ./docker-entrypoint-initdb.d a sql script initializes schemas and user grants

create database if not exists my_app_events;
create database if not exists my_app_db;
create user if not exists 'test'@'%' identified by 'test';
grant all on my_app_db.* to 'test'@'%';
grant all on my_app_events.* to 'test'@'%';

the test class looks like:

@SpringBootTest
@RunWith(SpringRunner.class)
@ContextConfiguration(initializers = MyTest.DatabaseTestInitializer.class)
public class MyTest {

    @Test
    public void testSomething(){
       // ...
    }

    public static class DatabaseTestInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {

        private MariaDBContainer mariaDBContainer;

        @Override
        public void initialize(final ConfigurableApplicationContext configurableApplicationContext) {
            mariaDBContainer = new MariaDBContainer(
                    DockerImageName.parse("registry.gitlab.com/myproject/empty-database")
                            .asCompatibleSubstituteFor("mariadb")
            );
            mariaDBContainer.start();

            // This is solution for 1.x.x Spring Boot framework
            // Article for migration from 1.x.x to 2.x.x Spring Boot https://stackoverflow.com/questions/54718995/appropriate-usage-of-testpropertyvalues-in-spring-boot-tests
            EnvironmentTestUtils.addEnvironment(configurableApplicationContext.getEnvironment(),
                    "spring.datasource.url=" + mariaDBContainer.getJdbcUrl(),
                    "spring.datasource.username=" + mariaDBContainer.getUsername(),
                    "spring.datasource.password=" + mariaDBContainer.getPassword()
            );
        }
    }
}

docker ps shows the running container and it's logs seems ok but the tests do not execute due to:

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::       (v1.5.22.RELEASE)

2023-02-25 12:55:22.805  INFO 41908 --- [           main] o.t.utility.ImageNameSubstitutor         : Image name substitution will be performed by: DefaultImageNameSubstitutor (composite of 'ConfigurationFileImageNameSubstitutor' and 'PrefixingImageNameSubstitutor')
2023-02-25 12:55:22.834  INFO 41908 --- [           main] o.t.d.DockerClientProviderStrategy       : Loaded org.testcontainers.dockerclient.UnixSocketClientProviderStrategy from ~/.testcontainers.properties, will try it first
2023-02-25 12:55:23.238  INFO 41908 --- [           main] o.t.d.DockerClientProviderStrategy       : Found Docker environment with local Unix socket (unix:///var/run/docker.sock)
2023-02-25 12:55:23.239  INFO 41908 --- [           main] org.testcontainers.DockerClientFactory   : Docker host IP address is localhost
2023-02-25 12:55:23.251  INFO 41908 --- [           main] org.testcontainers.DockerClientFactory   : Connected to docker: 
  Server Version: 23.0.1
  API Version: 1.42
  Operating System: Ubuntu 22.04.2 LTS
  Total Memory: 31729 MB
2023-02-25 12:55:23.310  INFO 41908 --- [           main] 🐳 [testcontainers/ryuk:0.3.4]           : Creating container for image: testcontainers/ryuk:0.3.4
2023-02-25 12:55:23.429  INFO 41908 --- [           main] 🐳 [testcontainers/ryuk:0.3.4]           : Container testcontainers/ryuk:0.3.4 is starting: e1fb00ceb884f930b4395f6a4ae52e3d782cd18b3e5095d64e879cc3c6a546ab
2023-02-25 12:55:23.770  INFO 41908 --- [           main] 🐳 [testcontainers/ryuk:0.3.4]           : Container testcontainers/ryuk:0.3.4 started in PT0.511S
2023-02-25 12:55:23.775  INFO 41908 --- [           main] o.t.utility.RyukResourceReaper           : Ryuk started - will monitor and terminate Testcontainers containers on JVM exit
2023-02-25 12:55:23.775  INFO 41908 --- [           main] org.testcontainers.DockerClientFactory   : Checking the system...
2023-02-25 12:55:23.775  INFO 41908 --- [           main] org.testcontainers.DockerClientFactory   : ✔︎ Docker server version should be at least 1.6.0
2023-02-25 12:55:23.788  INFO 41908 --- [           main] .g.com/garanteasy/empty-database:latest] : Creating container for image: registry.gitlab.com/garanteasy/empty-database:latest
2023-02-25 12:55:23.871  INFO 41908 --- [           main] .g.com/garanteasy/empty-database:latest] : Container registry.gitlab.com/garanteasy/empty-database:latest is starting: 064f7bcb915621d2cd7d891f2c2920462bd7197854aad5f6f46ff1e4b827d691
2023-02-25 12:55:24.122  INFO 41908 --- [           main] .g.com/garanteasy/empty-database:latest] : Waiting for database connection to become available at jdbc:mariadb://localhost:32806/test using query 'SELECT 1'
2023-02-25 12:55:28.922  INFO 41908 --- [           main] .g.com/garanteasy/empty-database:latest] : Container is started (JDBC URL: jdbc:mariadb://localhost:32806/test)
2023-02-25 12:55:28.923  INFO 41908 --- [           main] .g.com/garanteasy/empty-database:latest] : Container registry.gitlab.com/garanteasy/empty-database:latest started in PT5.146S
2023-02-25 12:55:28.926  INFO 41908 --- [           main] c.g.cms_api.BrandCmsResourceTest         : Starting BrandCmsResourceTest on lrkwz-XPS-15-7590 with PID 41908 (started by lrkwz in /home/lrkwz/garanteasy/api-development-environment/garanteasy-cms-api)
2023-02-25 12:55:28.926 DEBUG 41908 --- [           main] c.g.cms_api.BrandCmsResourceTest         : Running with Spring Boot v1.5.22.RELEASE, Spring v4.3.25.RELEASE
2023-02-25 12:55:28.926  INFO 41908 --- [           main] c.g.cms_api.BrandCmsResourceTest         : No active profile set, falling back to default profiles: default
2023-02-25 12:55:28.943  INFO 41908 --- [           main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@3fce8fd9: startup date [Sat Feb 25 12:55:28 CET 2023]; root of context hierarchy
2023-02-25 12:55:29.697  INFO 41908 --- [           main] f.a.AutowiredAnnotationBeanPostProcessor : JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
2023-02-25 12:55:30.212  INFO 41908 --- [           main] j.LocalContainerEntityManagerFactoryBean : Building JPA container EntityManagerFactory for persistence unit 'default'
2023-02-25 12:55:30.224  INFO 41908 --- [           main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [
    name: default
    ...]
2023-02-25 12:55:30.286  INFO 41908 --- [           main] org.hibernate.Version                    : HHH000412: Hibernate Core {5.0.12.Final}
2023-02-25 12:55:30.287  INFO 41908 --- [           main] org.hibernate.cfg.Environment            : HHH000206: hibernate.properties not found
2023-02-25 12:55:30.288  INFO 41908 --- [           main] org.hibernate.cfg.Environment            : HHH000021: Bytecode provider name : javassist
2023-02-25 12:55:30.320  INFO 41908 --- [           main] o.hibernate.annotations.common.Version   : HCANN000001: Hibernate Commons Annotations {5.0.1.Final}
2023-02-25 12:55:30.415 DEBUG 41908 --- [           main] o.a.tomcat.jdbc.pool.PooledConnection    : Instantiating driver using class: org.testcontainers.jdbc.ContainerDatabaseDriver [url=jdbc:mariadb://localhost:32806/test]
2023-02-25 12:55:30.416 DEBUG 41908 --- [           main] o.a.tomcat.jdbc.pool.ClassLoaderUtil     : Attempting to load class[org.testcontainers.jdbc.ContainerDatabaseDriver] from sun.misc.Launcher$AppClassLoader@18b4aac2
2023-02-25 12:55:30.417 DEBUG 41908 --- [           main] o.a.tomcat.jdbc.pool.ConnectionPool      : Unable to create a new JDBC connection.

java.sql.SQLException: Driver:org.testcontainers.jdbc.ContainerDatabaseDriver@65036e8d returned null for URL:jdbc:mariadb://localhost:32806/test
    at org.apache.tomcat.jdbc.pool.PooledConnection.connectUsingDriver(PooledConnection.java:338)
    at org.apache.tomcat.jdbc.pool.PooledConnection.connect(PooledConnection.java:212)
    at org.apache.tomcat.jdbc.pool.ConnectionPool.createConnection(ConnectionPool.java:736)

I've also tried to stop the execution on a breakpoint and manually connect mysql -u test -ptest -h localhost -P <RANDOMPORT> my_app_db (you can read the random port in many ways: i.e. using docker ps) has success.

What's wrong in the context initialization?


Solution

  • I guess you forget to configure the spring.datasource.driver-class-name. So try below to see if it can fix the problem :

             EnvironmentTestUtils.addEnvironment(configurableApplicationContext.getEnvironment(), 
        "spring.datasource.url=" + mariaDBContainer.getJdbcUrl(),
        "spring.datasource.username=" + mariaDBContainer.getUsername(),
        "spring.datasource.password=" + mariaDBContainer.getPassword(),
        "spring.datasource.driver-class-name=org.mariadb.jdbc.Driver");