Syntax highlighter header

Thursday, 26 January 2023

Increasing container startup timeout of testcontainers Mysql container

Recently I moved my Docker from SSD drive to HDD drive as per my post https://blog.bigdatawithjasvant.com/2023/01/installing-docker-in-secondary-drive-on.html

After doing this change I faced a problem that my code build was failing because docker containers launched by testcontainers were slow to come up and testcontainers was only waiting for 120 seconds for it to come up, after that it was killing the container and starting an new one. The new container was also taking more than 120 second so it was also killed and after 3 attempts the build failed. I got the following error in my logs:

[ERROR] Could not start container
java.lang.IllegalStateException: Container is started, but cannot be accessed by (JDBC URL: jdbc:mysql://localhost:51209/test), please check container logs
    at org.testcontainers.containers.JdbcDatabaseContainer.waitUntilContainerStarted (JdbcDatabaseContainer.java:165)
    at org.testcontainers.containers.GenericContainer.tryStart (GenericContainer.java:466)
    at org.testcontainers.containers.GenericContainer.lambda$doStart$0 (GenericContainer.java:329)
    at org.rnorth.ducttape.unreliables.Unreliables.retryUntilSuccess (Unreliables.java:81)
    at org.testcontainers.containers.GenericContainer.doStart (GenericContainer.java:327)
    at org.testcontainers.containers.GenericContainer.start (GenericContainer.java:315)
    at org.testcontainers.jdbc.ContainerDatabaseDriver.connect (ContainerDatabaseDriver.java:118)
    at org.jooq.codegen.GenerationTool.run0 (GenerationTool.java:362)
    at org.jooq.codegen.GenerationTool.run (GenerationTool.java:236)
    at org.jooq.codegen.GenerationTool.generate (GenerationTool.java:231)
    at org.jooq.codegen.maven.Plugin.execute (Plugin.java:207)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:137)
    at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute (MojoExecutor.java:301)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:211)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:165)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:157)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:121)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
    at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:127)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:294)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192)
    at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105)
    at org.apache.maven.cli.MavenCli.execute (MavenCli.java:960)
    at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:293)
    at org.apache.maven.cli.MavenCli.main (MavenCli.java:196)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
    at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke (Method.java:566)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:282)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:225)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:406)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:347)
[ERROR] Log output from the failed container:

I was looking for a option to increase this timeout but did not find any provision for doing that in the source code of testcontainers. So I had to take a fork from https://github.com/testcontainers/testcontainers-java and change the code to add new provision to override the timeout. The enhanced code is available at following location:

https://github.com/jasvant6thstreet/testcontainers-java-jasvant

You can take a clone of above repository and build it using following command:

gradle build -x test

This command will compile the code on your local machine without running the testcases. It takes some time to build so be patient and wait for it to complete. Once build is complete you can push it to your local maven repository using following command:

gradle publishToMavenLocal

The above command will push enhanced testcontainers to your maven repository and after that you can use it in your maven projects. The version number is 1.17.6-j1 for this fix.

For setting new timeout following new properties are added:

tc.jdbc.startuptimeout=120
tc.jdbc.connectiontimeout=120

You can set it up at three places as per documentation provide in page

https://www.testcontainers.org/features/configuration/

I used the first option to set it via environment variables. I set up the following environment variables in the shall where I was running my build:

TESTCONTAINERS_TC_JDBC_CONNECTIONTIMEOUT=600
TESTCONTAINERS_TC_JDBC_STARTUPTIMEOUT=600

Using the above environment variables testcontainers Mysql connector was waiting for 600 seconds and the docker container was able to come up successfully in this time and build was successfully completed.

I have submitted a pull request to testcontainers for incorporating this change.

No comments:

Post a Comment