Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: Postgres waiting strategy is ineffective. #5986

Closed
yogurtearl opened this issue Oct 11, 2022 · 2 comments
Closed

[Bug]: Postgres waiting strategy is ineffective. #5986

yogurtearl opened this issue Oct 11, 2022 · 2 comments
Labels

Comments

@yogurtearl
Copy link

Module

PostgreSQL

Testcontainers version

1.17.5

Using the latest Testcontainers version?

Yes

Host OS

macOS

Host Arch

ARM

Docker version

Client:
 Version:           20.10.17-rd
 API version:       1.41
 Go version:        go1.17.11
 Git commit:        c2e4e01
 Built:             Fri Jul 22 18:32:57 2022
 OS/Arch:           darwin/arm64
 Context:           default
 Experimental:      true

Server:
 Engine:
  Version:          20.10.18
  API version:      1.41 (minimum version 1.12)
  Go version:       go1.18.6
  Git commit:       e42327a6d3c55ceda3bd5475be7aae6036d02db3
  Built:            Sun Sep 11 07:10:00 2022
  OS/Arch:          linux/arm64
  Experimental:     false
 containerd:
  Version:          v1.6.8
  GitCommit:        9cd3357b7fd7218e4aec3eae239db1f68a5a6ec6
 runc:
  Version:          1.1.4
  GitCommit:        5fd4c4d144137e991c4acebb2146ab1483a97925
 docker-init:
  Version:          0.19.0
  GitCommit:

What happened?

When using PostgreSQLContainer it doesn't wait long enough and I get the error mentioned below.

Putting a small sleep at the beginner of my test method reliably fixes it.

Also, this reliably fixes the issue:

    @Container
    private val postgres = PostgreSQLContainer<Nothing>(
        DockerImageName.parse("postgres@sha256:b6dde1cdf6efe3c9f8d099b378dd79e802ef44eef164e8a662451749243f9cda")
    ).also {
        it.setWaitStrategy(HostPortWaitStrategy())
    }

Relevant log output

Fails reliably every time with: 


        Caused by:
        org.postgresql.util.PSQLException: Connection to localhost:49330 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.
            at app//org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:319)
            at app//org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:49)
            at app//org.postgresql.jdbc.PgConnection.<init>(PgConnection.java:247)
            at app//org.postgresql.Driver.makeConnection(Driver.java:434)
            at app//org.postgresql.Driver.connect(Driver.java:291)
            at app//com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138)
            at app//com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359)
            at app//com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201)
            at app//com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470)
            at app//com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561)
            ... 4 more

            Caused by:
            java.net.ConnectException: Connection refused
                at java.base/sun.nio.ch.Net.pollConnect(Native Method)
                at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672)
                at java.base/sun.nio.ch.NioSocketImpl.timedFinishConnect(NioSocketImpl.java:549)
                at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:597)
                at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327)
                at java.base/java.net.Socket.connect(Socket.java:633)
                at org.postgresql.core.PGStream.createSocket(PGStream.java:241)
                at org.postgresql.core.PGStream.<init>(PGStream.java:98)
                at org.postgresql.core.v3.ConnectionFactoryImpl.tryConnect(ConnectionFactoryImpl.java:109)
                at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:235)


### Additional Information

I am using RacherDesktop 1.6.0 on macOS 12.6 on Apple Silicon (M1 Max)

Using image `postgres@sha256:b6dde1cdf6efe3c9f8d099b378dd79e802ef44eef164e8a662451749243f9cda` 

Using Kotlin 1.7
@eddumelendez
Copy link
Member

Testcontainers requires a Docker-API compatible container runtime. During development, Testcontainers is actively tested against recent versions of Docker on Linux, as well as against Docker Desktop on Mac and Windows.
These Docker environments are automatically detected and used by Testcontainers without any additional configuration being necessary.

It is possible to configure Testcontainers to work for other Docker setups, such as a remote Docker host or Docker alternatives. However, these are not actively tested in the main development workflow, so not all Testcontainers features might be available and additional manual configuration might be necessary. If you have further questions about configuration details for your setup or whether it supports running Testcontainers-based tests, please contact the Testcontainers team and other users from the Testcontainers community on Slack:

Join our Slack team

We have tested the port availability in both docker/rancher desktop and got the numbers below:

Docker desktop

real	0m0.003s
user	0m0.000s
sys	0m0.002s

Rancher desktop

real	0m3.046s
user	0m0.005s
sys	0m0.022s

@eddumelendez eddumelendez closed this as not planned Won't fix, can't repro, duplicate, stale Oct 12, 2022
@yogurtearl
Copy link
Author

@eddumelendez

The problem is not that it doesn't work with Rancher Desktop... it "just works" with Rancher Desktop
but the waiting strategy for postgres is ineffective.

If you use Docker desktop and it takes longer for some reason (system load on CI) it will also fail...
When my CI is under high load port availability might also take 3 seconds and cause a failure.

ONLY waiting for this log message is not sufficient, even for Docker Desktop.

this.waitStrategy =
new LogMessageWaitStrategy()
.withRegEx(".*database system is ready to accept connections.*\\s")
.withTimes(2)
.withStartupTimeout(Duration.of(60, ChronoUnit.SECONDS));

The DB needs to be started, but we also should wait for port availability, on any impl of docker.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants