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 Port not working #569

Closed
Biscgit opened this issue May 10, 2024 · 5 comments
Closed

Bug: Postgres Port not working #569

Biscgit opened this issue May 10, 2024 · 5 comments

Comments

@Biscgit
Copy link

Biscgit commented May 10, 2024

Describe the bug

Creating a PostgresContainer gets stuck on creating when port= is defined and raises a Runtime error after 1-2 minutes except when setting to the default Postgres port 5432.
Not defining it leads to random port mapping (as intended), but reading it with PostgresContainer.port returns the default Postgres port instead of the randomly selected one. It gets correctly mapped in the connection url though.

To Reproduce

import asyncpg
import pytest
from testcontainers.postgres import PostgresContainer

pytest_plugins = ('pytest_asyncio',)


# Gets stuck in creating container process and eventually raises a RuntimeException
@pytest.mark.asyncio
async def test_postgres_start():
    port = 3182
    with PostgresContainer("postgres:16-alpine", port=port) as pg:
        pass


# Reading port via .port returns the default port and not the actual one
@pytest.mark.asyncio
async def test_postgres_port():
    # Gets stuck in creating process:
    with PostgresContainer("postgres:16-alpine") as pg:
        port = pg.get_connection_url().split(":")[-1].split('/')[0]
        assert int(port) == pg.port

You can check the port with nmap as-well to be certain that the variable fails.
Setting driver=None leads to the same results.

Runtime environment

Versions and specs (at time of creating latest stable versions):

  • Machine: EndeavourOS Linux 6.8.9-arch1-2 x86_64 GNU/Linux
  • Docker: v26.1.2
  • Python: v3.12.3
    • pip: v24.0
    • pytest: v8.2.0
    • pytest-asyncio: v0.23.6
    • asyncpg: v0.29.0
    • testcontainers: v4.4.0
@alexanderankin
Copy link
Collaborator

alexanderankin commented May 10, 2024 via email

@Biscgit
Copy link
Author

Biscgit commented May 12, 2024

Hello!
Would it be possible to maybe expand the documentation on what exactly port= does? Because neither in the Python documentation nor in Postgres-Tests was I able to find any hints.
Or implementing a simple function for getting the containers port directly.

@alexanderankin
Copy link
Collaborator

you can get the exposed port using this function: https://github.com/testcontainers/testcontainers-python/blob/main/core/testcontainers/core/container.py#L140

@wait_container_is_ready()
def get_exposed_port(self, port: int) -> str:
mapped_port = self.get_docker_client().port(self._container.id, port)
if inside_container():
gateway_ip = self.get_docker_client().gateway_ip(self._container.id)
host = self.get_docker_client().host()
if gateway_ip == host:
return port
return mapped_port

e.g. by:

mkdir tcp-postgres-port-demo
cd tcp-postgres-port-demo
python -m venv .venv
test -d .venv/bin && . .venv/bin/activate
test -d .venv/Scripts && . .venv/Scripts/activate
pip install testcontainers pytest
cat > example.py <<EOF
from testcontainers.postgres import PostgresContainer
def test():
    with PostgresContainer("postgres:16-alpine") as pg:
        print(pg.get_exposed_port(5432))
EOF
pytest -s example.py

@alexanderankin
Copy link
Collaborator

documentation can be improved a lot, you are right about that

@Biscgit
Copy link
Author

Biscgit commented May 12, 2024

okay, that works too, thanks 👍

@Biscgit Biscgit closed this as completed May 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants