Skip to content

Perform failure analysis when Testcontainers cannot find a valid Docker environment #45281

@ahrytsiuk

Description

@ahrytsiuk

Context

Spring Boot comes with many handy failure analyzers which makes troubleshooting easier, so we can quickly understand why application failed to start and suggests how to fix the problem. For such things we love Spring Boot - because it's developer friendly.

Problem

When using spring-boot-testcontainers it's expected to have a valid Docker environment, but sometimes I just forget to run Docker. I don't have it enabled on startup of my system. Which leads to absolutely expected failure:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Failed to initialize dependency 'liquibase' of LoadTimeWeaverAware bean 'entityManagerFactory': Error creating bean with name 'liquibase' defined in class path resource [org/springframework/boot/autoconfigure/liquibase/LiquibaseAutoConfiguration$LiquibaseConfiguration.class]: Unsatisfied dependency expressed through method 'liquibase' parameter 4: Error creating bean with name 'liquibaseContainerConnectionDetailsForMysqlContainer': Error creating bean with name 'mysqlContainer' defined in com.github.ahrytsiuk.kata.server.TestcontainersConfiguration: Could not find a valid Docker environment. Please see logs and check configuration
...
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'liquibase' defined in class path resource [org/springframework/boot/autoconfigure/liquibase/LiquibaseAutoConfiguration$LiquibaseConfiguration.class]: Unsatisfied dependency expressed through method 'liquibase' parameter 4: Error creating bean with name 'liquibaseContainerConnectionDetailsForMysqlContainer': Error creating bean with name 'mysqlContainer' defined in com.github.ahrytsiuk.kata.server.TestcontainersConfiguration: Could not find a valid Docker environment. Please see logs and check configuration
...
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'liquibaseContainerConnectionDetailsForMysqlContainer': Error creating bean with name 'mysqlContainer' defined in com.github.ahrytsiuk.kata.server.TestcontainersConfiguration: Could not find a valid Docker environment. Please see logs and check configuration
...
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mysqlContainer' defined in com.github.ahrytsiuk.kata.server.TestcontainersConfiguration: Could not find a valid Docker environment. Please see logs and check configuration
...
Caused by: java.lang.IllegalStateException: Could not find a valid Docker environment. Please see logs and check configuration

Even though error message is clear, but is a bit overwhelming. And I believe that introducing specialized FailureAnalyzer could improve situation, by pointing directly to the issue and suggesting appropriate action.

Thoughts

Since by Testcontainers throw pretty generic exception (IllegalStateException) it's not that easy to add FailureAnalyzer. But still possible by parsing exception cause message, and check if it contains "Could not find a valid Docker environment" or just "Docker". Which could work, but not ideal and fragile.

As alternative maybe it would be possible to add exception handling in the TestcontainersStartup to catch failures and rethrow specialized exception, smth like

	public static void start(Startable startable) {
		if (!isRunning(startable)) {
			try {
				startable.start();
			} catch (Exception e) {
				throw new TestcontainersStartupException(e); // <--- new exception
			}
		}
	}

It seems this is the central place of starting all containers. This approach should work for SEQUENTIAL startup strategies, but I'm not sure about PARALLEL.

And of course ideally Testcontainers will introduce more specialized exception, but this is also tricky because it could be considered as a breaking change.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions