]> git.ipfire.org Git - thirdparty/psycopg.git/commitdiff
Warm up database before running tests
authorDaniele Varrazzo <daniele.varrazzo@gmail.com>
Mon, 15 Nov 2021 01:15:47 +0000 (02:15 +0100)
committerDaniele Varrazzo <daniele.varrazzo@gmail.com>
Mon, 15 Nov 2021 01:33:43 +0000 (02:33 +0100)
Sometimes, in the test CI, the first connection may take a long time,
and if the first test is about connection timeout, it might fail.

https://github.com/psycopg/psycopg/runs/4206004327?check_suite_focus=true

tests/fix_db.py

index 97287c42d61c619ea3fa9b8caff96ca0460195fa..3e4c60ab8f630df801ec4880d14d800893eb2453 100644 (file)
@@ -1,5 +1,7 @@
 import os
 import pytest
+import logging
+from typing import List
 
 from .utils import check_server_version
 
@@ -37,6 +39,15 @@ def dsn(request):
     dsn = request.config.getoption("--test-dsn")
     if dsn is None:
         pytest.skip("skipping test as no --test-dsn")
+
+    try:
+        warm_up_database(dsn)
+    except Exception:
+        # This is a session fixture, so, in case of error, the exception would
+        # be cached and nothing would run.
+        # Let the caller fail instead.
+        logging.exception("error warming up database")
+
     return dsn
 
 
@@ -155,3 +166,24 @@ def hstore(svcconn):
             svcconn.execute("create extension if not exists hstore")
     except Error as e:
         pytest.skip(str(e))
+
+
+def warm_up_database(
+    dsn: str, __first_connection: List[bool] = [True]
+) -> None:
+    """Connect to the database before returning a connection.
+
+    In the CI sometimes, the first test fails with a timeout, probably because
+    the server hasn't started yet. Absorb the delay before the test.
+    """
+    # Do it only once, even in case of failure, otherwise, in case of bad
+    # configuration, with every test timing out, the entire test run would take
+    # forever.
+    if not __first_connection:
+        return
+    del __first_connection[:]
+
+    import psycopg
+
+    with psycopg.connect(dsn, connect_timeout=10) as conn:
+        conn.execute("select 1")