This is an automated email from the ASF dual-hosted git repository.
potiuk pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/main by this push:
new 8ee29ce9e4f providers/mongo: ping mongod before yielding from
mongodb_container fixture (#67066)
8ee29ce9e4f is described below
commit 8ee29ce9e4f3c1dc32304fd2841abced191a1c48
Author: Jarek Potiuk <[email protected]>
AuthorDate: Sun May 17 21:50:52 2026 +0200
providers/mongo: ping mongod before yielding from mongodb_container fixture
(#67066)
Under uv --resolution lowest-direct, testcontainers==4.12.0 is pinned and
MongoDbContainer.start() waits only for the "waiting for connections" log
line. mongod can emit that log line a few milliseconds before the TCP
listener is actually accepting connections on the published port. We
observed a low-frequency ARM CI flake where the entire TestMongoHook
suite errored at setup_method with:
pymongo.errors.ServerSelectionTimeoutError: 172.17.0.1:32769:
[Errno 111] Connection refused
while the same SHA passed on the other parallel runs.
No testcontainers version on PyPI closes the log-to-listener gap for
modern mongo images (4.13.2 only made the log regex case-insensitive for
mongo 3.6); the only reliable fix is to actively probe mongod from the
fixture. Add a short pymongo ping loop after get_connection_url() and
before yielding so all dependent fixtures see a mongod that actually
accepts connections.
---
providers/mongo/tests/conftest.py | 29 ++++++++++++++++++++++++++++-
1 file changed, 28 insertions(+), 1 deletion(-)
diff --git a/providers/mongo/tests/conftest.py
b/providers/mongo/tests/conftest.py
index 22a63f417b3..ecc94bc2e80 100644
--- a/providers/mongo/tests/conftest.py
+++ b/providers/mongo/tests/conftest.py
@@ -20,6 +20,7 @@ import contextlib
import time
import pytest
+from pymongo import MongoClient
from testcontainers.mongodb import MongoDbContainer
pytest_plugins = "tests_common.pytest_plugin"
@@ -29,6 +30,30 @@ pytest_plugins = "tests_common.pytest_plugin"
MONGO_IMAGE = "mongo:8.0"
+def _wait_for_mongo_ready(url: str, timeout: int = 60) -> None:
+ """Poll mongod via ``ping`` until it answers or the timeout expires.
+
+ ``MongoDbContainer.start()`` only waits for the ``waiting for connections``
+ log line, which mongod can emit a few milliseconds before the TCP listener
+ is actually accepting on the published port. Under
+ ``--resolution lowest-direct`` (testcontainers 4.12.0, pymongo 4.13.2) we
+ occasionally observed every ``TestMongoHook`` test failing with
+ ``Connection refused`` on the very first ``MongoHook.get_conn()`` call.
+ Actively pinging mongod after the log gate closes the gap.
+ """
+ deadline = time.monotonic() + timeout
+ last_exc: Exception | None = None
+ while time.monotonic() < deadline:
+ try:
+ with MongoClient(url, serverSelectionTimeoutMS=2000) as client:
+ client.admin.command("ping")
+ return
+ except Exception as exc:
+ last_exc = exc
+ time.sleep(1)
+ raise TimeoutError(f"mongod at {url} did not answer ping within
{timeout}s") from last_exc
+
+
@pytest.fixture(scope="session")
def mongodb_container():
# Retry container start to absorb transient Docker Hub failures (e.g.
@@ -48,7 +73,9 @@ def mongodb_container():
continue
raise
try:
- yield container.get_connection_url()
+ url = container.get_connection_url()
+ _wait_for_mongo_ready(url)
+ yield url
finally:
container.stop()
return