Run Integration Tests with Podman and Testcontainers
In this blog I will try to run integration tests with Tescontainers Using Podman instead Docker.
In one of my previous blog post, I have covered how to install and use Podman in place of Docker in Windows OS.
In that post I have used cli commands to create images and run the containers with Podman.
Testcontainers also creates Docker containers to run integration tests but do not use cli, it uses docker API to create docker containers.
Let’s see whether Podman provides API which is compatible to Docker which can be used by Testcontainers.
I have already written a detailed blog post about database integration testing with Spring Boot and Testcontainers in following article.
So I am going to see whether I can run integration tests with Podman using Testcontainers library.
I am going to use the repo from GitHub for running database integration tests.
Note
First I installed Podman version 4.2.0 for testing.
Starting Podman
For running integration tests with Podman, I started Podman with following command.
podman machine start
Code language: Java (java)
Starting machine "podman-machine-default"
API forwarding listening on: npipe:////./pipe/docker_engine
Docker API clients default to this address. You do not need to set DOCKER_HOST.
Machine "podman-machine-default" started successfully
Code language: Java (java)
If you are running Docker Desktop when you are start the Podman, you will see message like below. You need to set the DOCKER_HOST property so that Podman handles to Docker API requests.
Starting machine "podman-machine-default"
This machine is currently configured in rootless mode. If your containers
require root permissions (e.g. ports < 1024), or if you run into compatibility
issues with non-podman clients, you can switch using the following command:
podman machine set --rootful
API forwarding listening on: npipe:////./pipe/podman-machine-default
Another process was listening on the default Docker API pipe address.
You can still connect Docker API clients by setting DOCKER HOST using the
following powershell command in your terminal session:
$Env:DOCKER_HOST = 'npipe:////./pipe/podman-machine-default'
Or in a classic CMD prompt:
set DOCKER_HOST = 'npipe:////./pipe/podman-machine-default'
Alternatively terminate the other process and restart podman machine.
Machine "podman-machine-default" started successfully
Code language: Java (java)
Run Integration Test
mvn clean verify
Code language: Java (java)
From the logs, I can say that Testcontainer is recognizing the Podman as docker environment.
22:28:39.722 [main] INFO org.testcontainers.dockerclient.DockerClientProviderStrategy - Loaded org.testcontainers.dockerclient.NpipeSocketClientProviderStrategy from ~/.testcontainers.properties, will try it first
22:28:40.278 [main] INFO org.testcontainers.dockerclient.DockerClientProviderStrategy - Found Docker environment with local Npipe socket (npipe:////./pipe/docker_engine)
22:28:40.280 [main] INFO org.testcontainers.DockerClientFactory - Docker host IP address is localhost
22:28:40.376 [main] INFO org.testcontainers.DockerClientFactory - Connected to docker:
Server Version: 4.2.0
API Version: 1.41
Operating System: fedora
Total Memory: 904 MB
22:28:40.376 [main] INFO org.testcontainers.DockerClientFactory - Checking the system...
22:28:40.377 [main] INFO org.testcontainers.DockerClientFactory - ✔︎ Docker server version should be at least 1.6.0
22:28:40.382 [main] INFO org.testcontainers.utility.ImageNameSubstitutor - Image name substitution will be performed by: DefaultImageNameSubstitutor (composite of 'ConfigurationFileImageNameSubstitutor' and 'PrefixingImageNameSubstitutor')
Code language: Java (java)
But my tests were failing with following message.
org.testcontainers.containers.ContainerLaunchException: Timed out waiting for log output matching '.*database system is ready to accept connections.*'
Code language: Java (java)
The log output was showing following message
07:16:15.735 [docker-java-stream--2056062630] DEBUG com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.wire - http-outgoing-0 << "{"cause":"using --follow with the journald --log-driver but without the journald --events-backend (file) is not supported","message":"failed to obtain logs for Container '38555297088f5eb766b2c81e22637bb0b4581456b02422ee1cd59deb30674fdc': using --follow with the journald --log-driver but without the journald --events-backend (file) is not supported","response":500}[\n]"
I thought , there could be problem with Database containers, So I tried to ran integration tests for RabbitMQ based application.
First I tried to run the integration tests with RabbitMQ module provided by Testcontainers and faced same problem.
Next I tried to run integration tests with Generic containers and they ran successfully.
So I just compared the difference between two approaches.
RabbitMQ module uses Log of container to know whether container started or not.
For Generic container , I have checked ports open status to decide whether container started or not.
That means Testcontainer is not able to read logs of container. So opened a issue on Testcontaoners repo. I got very quick reply from repo maintainers and they clarified that it is not an issue of Testcontainers but could issue of Podman.
So opened issue on Podman repo and was waiting for maintainers reply.
Meanwhile I happen to watch a youtube video on Podman which explained about problem with journald in wsl systems.
So loogged into Podman virtual machine via ssh with following command.
podman machine ssh
Code language: Java (java)
And changed following line in /usr/share/containers/containers.conf file
from
log_driver = "journald"
Code language: Java (java)
to
log_driver = "k8s-file"
Code language: Java (java)
and restarted the Podman virtual machine.
Note
You could also just comment the line log_driver = “journald” to resolve the issue.
When I ran integration tests again which were failing earlier, they passed with out issue.
Note
When I upgraded the Podman to version 4.2.1, I was not facing any issues running all types of integration tests. Somethings were changed between version 4.2 and version 4.2.1.
But If you face issue with Testcontainers reading logs of containers, now you know how to resolve the issue.