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

Reply via email to