import pytest
import logging
from contextlib import contextmanager
-from typing import List, Optional
+from typing import Optional
import psycopg
from psycopg import pq
-from psycopg.pq._debug import PGconnDebug
from psycopg import sql
+from psycopg._compat import cache
+from psycopg.pq._debug import PGconnDebug
from .utils import check_postgres_version
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")
-
+ warm_up_database(dsn)
return dsn
pytest.skip(str(e))
-def warm_up_database(dsn: str, __first_connection: List[bool] = [True]) -> None:
+@cache
+def warm_up_database(dsn: str) -> 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[:]
+ In case of error, abort the test run entirely, to avoid failing downstream
+ hundreds of times.
+ """
global pg_version, crdb_version
- with psycopg.connect(dsn, connect_timeout=10) as conn:
- conn.execute("select 1")
+ try:
+ with psycopg.connect(dsn, connect_timeout=10) as conn:
+ conn.execute("select 1")
- pg_version = conn.info.server_version
+ pg_version = conn.info.server_version
- crdb_version = None
- param = conn.info.parameter_status("crdb_version")
- if param:
- from psycopg.crdb import CrdbConnectionInfo
+ crdb_version = None
+ param = conn.info.parameter_status("crdb_version")
+ if param:
+ from psycopg.crdb import CrdbConnectionInfo
- crdb_version = CrdbConnectionInfo.parse_crdb_version(param)
+ crdb_version = CrdbConnectionInfo.parse_crdb_version(param)
+ except Exception as exc:
+ pytest.exit(f"failed to connect to the test database: {exc}")