|
|
|
|
@@ -1,23 +1,26 @@
|
|
|
|
|
"""
|
|
|
|
|
Tests for the conftest.py prod-safety guard.
|
|
|
|
|
Tests for the conftest.py prod-safety guard (tuple-based identity check).
|
|
|
|
|
|
|
|
|
|
The guard refuses to TRUNCATE a database whose (host, port, user, dbname)
|
|
|
|
|
tuple matches the production DB. Anything else (test DB, in-container test,
|
|
|
|
|
mismatched creds) is treated as not-prod and proceeds.
|
|
|
|
|
|
|
|
|
|
These tests verify that:
|
|
|
|
|
1. By default, reset_state() connects to the test DB (db-test:5433 / 127.0.0.1:5433).
|
|
|
|
|
2. When DAMASCUS_PG_HOST points to a production hostname (127.0.0.1, localhost, db),
|
|
|
|
|
reset_state() refuses to TRUNCATE unless DAMASCUS_ALLOW_TEST_RESET=1 is set.
|
|
|
|
|
3. The DB_CONFIG defaults are correct (db-test, port 5433, damascus_test).
|
|
|
|
|
4. Explicit env-var overrides still work (DAMASCUS_TEST_PG_*).
|
|
|
|
|
|
|
|
|
|
These tests do NOT themselves touch the production DB. They exercise the
|
|
|
|
|
guard logic by importing the module, checking DB_CONFIG, and calling
|
|
|
|
|
reset_state() against a known-bad host while monkeypatching DB_CONFIG.
|
|
|
|
|
1. Default DSN points at db-test (127.0.0.1:5433 / damascus_test / damascus_test).
|
|
|
|
|
2. Production tuples (host-loopback, in-container via `db`, container name)
|
|
|
|
|
are recognized and refused without opt-in.
|
|
|
|
|
3. Tuple must match EXACTLY — any field mismatch (wrong port, wrong user,
|
|
|
|
|
wrong dbname, wrong host) is treated as not-prod.
|
|
|
|
|
4. DAMASCUS_ALLOW_TEST_RESET=1 permits production wipe with a warning.
|
|
|
|
|
5. The in-container test DSN (`db-test:5432/damascus_test/damascus_test`)
|
|
|
|
|
is treated as not-prod — important because the orchestrator worker runs
|
|
|
|
|
pytest INSIDE the container and reaches the test DB via this tuple.
|
|
|
|
|
|
|
|
|
|
Run from the repo root:
|
|
|
|
|
pytest tests/test_conftest_safety.py -v
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
import importlib
|
|
|
|
|
import os
|
|
|
|
|
import sys
|
|
|
|
|
|
|
|
|
|
import pytest
|
|
|
|
|
@@ -25,7 +28,6 @@ import pytest
|
|
|
|
|
|
|
|
|
|
def _reload_conftest():
|
|
|
|
|
"""Reload the conftest module so env-var changes take effect."""
|
|
|
|
|
# Remove any cached conftest modules
|
|
|
|
|
for mod_name in list(sys.modules.keys()):
|
|
|
|
|
if "conftest" in mod_name:
|
|
|
|
|
del sys.modules[mod_name]
|
|
|
|
|
@@ -34,33 +36,41 @@ def _reload_conftest():
|
|
|
|
|
return conftest
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_db_config_defaults_to_test_db(monkeypatch):
|
|
|
|
|
"""DB_CONFIG defaults should point at db-test on host port 5433, NOT production."""
|
|
|
|
|
monkeypatch.delenv("DAMASCUS_TEST_PG_HOST", raising=False)
|
|
|
|
|
monkeypatch.delenv("DAMASCUS_TEST_PG_PORT", raising=False)
|
|
|
|
|
monkeypatch.delenv("DAMASCUS_TEST_PG_USER", raising=False)
|
|
|
|
|
monkeypatch.delenv("DAMASCUS_TEST_PG_PASSWORD", raising=False)
|
|
|
|
|
monkeypatch.delenv("DAMASCUS_TEST_PG_DB", raising=False)
|
|
|
|
|
monkeypatch.delenv("DAMASCUS_PG_HOST", raising=False)
|
|
|
|
|
monkeypatch.delenv("DAMASCUS_PG_PORT", raising=False)
|
|
|
|
|
monkeypatch.delenv("DAMASCUS_PG_USER", raising=False)
|
|
|
|
|
monkeypatch.delenv("DAMASCUS_PG_PASSWORD", raising=False)
|
|
|
|
|
monkeypatch.delenv("DAMASCUS_PG_DB", raising=False)
|
|
|
|
|
monkeypatch.delenv("DAMASCUS_ALLOW_TEST_RESET", raising=False)
|
|
|
|
|
def _clear_pg_env(monkeypatch):
|
|
|
|
|
"""Clear every DAMASCUS_PG_* and DAMASCUS_TEST_PG_* env var so the
|
|
|
|
|
module's DB_CONFIG reflects only the hard-coded defaults.
|
|
|
|
|
"""
|
|
|
|
|
for var in (
|
|
|
|
|
"DAMASCUS_TEST_PG_HOST", "DAMASCUS_TEST_PG_PORT",
|
|
|
|
|
"DAMASCUS_TEST_PG_USER", "DAMASCUS_TEST_PG_PASSWORD",
|
|
|
|
|
"DAMASCUS_TEST_PG_DB",
|
|
|
|
|
"DAMASCUS_PG_HOST", "DAMASCUS_PG_PORT",
|
|
|
|
|
"DAMASCUS_PG_USER", "DAMASCUS_PG_PASSWORD", "DAMASCUS_PG_DB",
|
|
|
|
|
"DAMASCUS_ALLOW_TEST_RESET",
|
|
|
|
|
):
|
|
|
|
|
monkeypatch.delenv(var, raising=False)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# ── Default config ───────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_db_config_defaults_to_test_db(monkeypatch):
|
|
|
|
|
"""DB_CONFIG defaults should point at the host-loopback test DB,
|
|
|
|
|
NOT production. Host 127.0.0.1 + port 5433 + damascus_test user +
|
|
|
|
|
damascus_test dbname is the host-bound port mapping for db-test.
|
|
|
|
|
"""
|
|
|
|
|
_clear_pg_env(monkeypatch)
|
|
|
|
|
conftest = _reload_conftest()
|
|
|
|
|
|
|
|
|
|
# From the host, default to 127.0.0.1 (the dev-loopback port to db-test)
|
|
|
|
|
assert conftest.DB_CONFIG["host"] == "127.0.0.1", \
|
|
|
|
|
f"DB_CONFIG.host should default to '127.0.0.1', got {conftest.DB_CONFIG['host']!r}"
|
|
|
|
|
assert conftest.DB_CONFIG["port"] == 5433, \
|
|
|
|
|
f"DB_CONFIG.port should default to 5433, got {conftest.DB_CONFIG['port']!r}"
|
|
|
|
|
assert conftest.DB_CONFIG["user"] == "damascus_test", \
|
|
|
|
|
f"DB_CONFIG.user should default to 'damascus_test', got {conftest.DB_CONFIG['user']!r}"
|
|
|
|
|
assert conftest.DB_CONFIG["password"] == "damascus_test", \
|
|
|
|
|
f"DB_CONFIG.password should default to 'damascus_test', got {conftest.DB_CONFIG['password']!r}"
|
|
|
|
|
assert conftest.DB_CONFIG["dbname"] == "damascus_test", \
|
|
|
|
|
f"DB_CONFIG.dbname should default to 'damascus_test', got {conftest.DB_CONFIG['dbname']!r}"
|
|
|
|
|
assert conftest.DB_CONFIG["host"] == "127.0.0.1"
|
|
|
|
|
assert conftest.DB_CONFIG["port"] == 5433
|
|
|
|
|
assert conftest.DB_CONFIG["user"] == "damascus_test"
|
|
|
|
|
assert conftest.DB_CONFIG["password"] == "damascus_test"
|
|
|
|
|
assert conftest.DB_CONFIG["dbname"] == "damascus_test"
|
|
|
|
|
|
|
|
|
|
# The default tuple MUST NOT match any production tuple.
|
|
|
|
|
dsn = ("127.0.0.1", 5433, "damascus_test", "damascus_test")
|
|
|
|
|
assert dsn not in conftest._PROD_DSNS
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_db_config_explicit_overrides(monkeypatch):
|
|
|
|
|
@@ -80,57 +90,85 @@ def test_db_config_explicit_overrides(monkeypatch):
|
|
|
|
|
assert conftest.DB_CONFIG["dbname"] == "staging_db"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_prod_safety_guard_skips_against_db_host(monkeypatch):
|
|
|
|
|
"""The docker service name 'db' is production. reset_state must skip."""
|
|
|
|
|
# ── Prod detection: the four canonical tuples ───────────────────────────
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_prod_safety_guard_skips_host_loopback_prod(monkeypatch):
|
|
|
|
|
"""127.0.0.1:5432/damascus/damascus = prod (host-loopback). Skip without opt-in."""
|
|
|
|
|
_clear_pg_env(monkeypatch)
|
|
|
|
|
monkeypatch.setenv("DAMASCUS_TEST_PG_HOST", "127.0.0.1")
|
|
|
|
|
monkeypatch.setenv("DAMASCUS_TEST_PG_PORT", "5432")
|
|
|
|
|
monkeypatch.setenv("DAMASCUS_TEST_PG_USER", "damascus")
|
|
|
|
|
monkeypatch.setenv("DAMASCUS_TEST_PG_PASSWORD", "damascus")
|
|
|
|
|
monkeypatch.setenv("DAMASCUS_TEST_PG_DB", "damascus")
|
|
|
|
|
|
|
|
|
|
conftest = _reload_conftest()
|
|
|
|
|
|
|
|
|
|
with pytest.raises(pytest.skip.Exception):
|
|
|
|
|
conftest.reset_state()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_prod_safety_guard_skips_in_container_via_db_host(monkeypatch):
|
|
|
|
|
"""db:5432/damascus/damascus = prod (in-container via compose). Skip."""
|
|
|
|
|
_clear_pg_env(monkeypatch)
|
|
|
|
|
monkeypatch.setenv("DAMASCUS_TEST_PG_HOST", "db")
|
|
|
|
|
monkeypatch.setenv("DAMASCUS_TEST_PG_PORT", "5432")
|
|
|
|
|
monkeypatch.setenv("DAMASCUS_TEST_PG_USER", "damascus")
|
|
|
|
|
monkeypatch.setenv("DAMASCUS_TEST_PG_PASSWORD", "damascus")
|
|
|
|
|
monkeypatch.setenv("DAMASCUS_TEST_PG_DB", "damascus")
|
|
|
|
|
monkeypatch.delenv("DAMASCUS_ALLOW_TEST_RESET", raising=False)
|
|
|
|
|
|
|
|
|
|
conftest = _reload_conftest()
|
|
|
|
|
|
|
|
|
|
assert conftest.DB_CONFIG["host"] == "db"
|
|
|
|
|
|
|
|
|
|
with pytest.raises(pytest.skip.Exception):
|
|
|
|
|
conftest.reset_state()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_prod_safety_guard_skips_against_port_5432(monkeypatch):
|
|
|
|
|
"""127.0.0.1:5432 IS production (the prod DB's host-bound port).
|
|
|
|
|
Even though 127.0.0.1 is also the host-loopback port for db-test:5433,
|
|
|
|
|
port 5432 is unambiguously production.
|
|
|
|
|
"""
|
|
|
|
|
monkeypatch.setenv("DAMASCUS_TEST_PG_HOST", "127.0.0.1")
|
|
|
|
|
def test_prod_safety_guard_skips_localhost(monkeypatch):
|
|
|
|
|
"""localhost:5432/damascus/damascus = prod. Skip."""
|
|
|
|
|
_clear_pg_env(monkeypatch)
|
|
|
|
|
monkeypatch.setenv("DAMASCUS_TEST_PG_HOST", "localhost")
|
|
|
|
|
monkeypatch.setenv("DAMASCUS_TEST_PG_PORT", "5432")
|
|
|
|
|
monkeypatch.setenv("DAMASCUS_TEST_PG_USER", "damascus")
|
|
|
|
|
monkeypatch.setenv("DAMASCUS_TEST_PG_PASSWORD", "damascus")
|
|
|
|
|
monkeypatch.setenv("DAMASCUS_TEST_PG_DB", "damascus")
|
|
|
|
|
monkeypatch.delenv("DAMASCUS_ALLOW_TEST_RESET", raising=False)
|
|
|
|
|
|
|
|
|
|
conftest = _reload_conftest()
|
|
|
|
|
|
|
|
|
|
assert conftest.DB_CONFIG["host"] == "127.0.0.1"
|
|
|
|
|
assert conftest.DB_CONFIG["port"] == 5432
|
|
|
|
|
|
|
|
|
|
with pytest.raises(pytest.skip.Exception):
|
|
|
|
|
conftest.reset_state()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_prod_safety_guard_opt_in(monkeypatch):
|
|
|
|
|
"""With DAMASCUS_ALLOW_TEST_RESET=1 the guard should NOT skip — let it run.
|
|
|
|
|
|
|
|
|
|
We monkeypatch reset_state's TRUNCATE path to a no-op so the test
|
|
|
|
|
doesn't actually hit the DB. The point is to verify the guard
|
|
|
|
|
permits the call when explicitly opted in.
|
|
|
|
|
"""
|
|
|
|
|
monkeypatch.setenv("DAMASCUS_TEST_PG_HOST", "127.0.0.1")
|
|
|
|
|
def test_prod_safety_guard_skips_container_name(monkeypatch):
|
|
|
|
|
"""damascus-orchestrator-db-1:5432/damascus/damascus = prod. Skip."""
|
|
|
|
|
_clear_pg_env(monkeypatch)
|
|
|
|
|
monkeypatch.setenv("DAMASCUS_TEST_PG_HOST", "damascus-orchestrator-db-1")
|
|
|
|
|
monkeypatch.setenv("DAMASCUS_TEST_PG_PORT", "5432")
|
|
|
|
|
monkeypatch.setenv("DAMASCUS_TEST_PG_USER", "damascus")
|
|
|
|
|
monkeypatch.setenv("DAMASCUS_TEST_PG_PASSWORD", "damascus")
|
|
|
|
|
monkeypatch.setenv("DAMASCUS_TEST_PG_DB", "damascus")
|
|
|
|
|
monkeypatch.setenv("DAMASCUS_ALLOW_TEST_RESET", "1")
|
|
|
|
|
|
|
|
|
|
conftest = _reload_conftest()
|
|
|
|
|
|
|
|
|
|
with pytest.raises(pytest.skip.Exception):
|
|
|
|
|
conftest.reset_state()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# ── Tuple mismatches: should NOT be treated as prod ─────────────────────
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_prod_safety_guard_treats_in_container_test_as_safe(monkeypatch):
|
|
|
|
|
"""db-test:5432/damascus_test/damascus_test = test DB (in-container).
|
|
|
|
|
|
|
|
|
|
This is the DSN an orchestrator worker uses when running pytest
|
|
|
|
|
inside the container. Same port as prod (5432), different host,
|
|
|
|
|
different user, different dbname. MUST NOT be treated as prod.
|
|
|
|
|
"""
|
|
|
|
|
_clear_pg_env(monkeypatch)
|
|
|
|
|
monkeypatch.setenv("DAMASCUS_TEST_PG_HOST", "db-test")
|
|
|
|
|
monkeypatch.setenv("DAMASCUS_TEST_PG_PORT", "5432")
|
|
|
|
|
monkeypatch.setenv("DAMASCUS_TEST_PG_USER", "damascus_test")
|
|
|
|
|
monkeypatch.setenv("DAMASCUS_TEST_PG_PASSWORD", "damascus_test")
|
|
|
|
|
monkeypatch.setenv("DAMASCUS_TEST_PG_DB", "damascus_test")
|
|
|
|
|
|
|
|
|
|
conftest = _reload_conftest()
|
|
|
|
|
|
|
|
|
|
@@ -149,36 +187,21 @@ def test_prod_safety_guard_opt_in(monkeypatch):
|
|
|
|
|
|
|
|
|
|
monkeypatch.setattr(conftest, "get_conn", lambda: FakeConn())
|
|
|
|
|
|
|
|
|
|
# Should NOT raise skip — guard permits the call
|
|
|
|
|
with pytest.warns(RuntimeWarning, match="PRODUCTION DB"):
|
|
|
|
|
conftest.reset_state()
|
|
|
|
|
# Should NOT raise — this is the test DB
|
|
|
|
|
conftest.reset_state()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_reset_state_runs_against_test_db(monkeypatch):
|
|
|
|
|
"""Default config (127.0.0.1:5433) should run the TRUNCATE without skip.
|
|
|
|
|
|
|
|
|
|
127.0.0.1 is the host-loopback port mapping for db-test:5432.
|
|
|
|
|
Port 5433 is the host-bound port for db-test (NOT prod port 5432).
|
|
|
|
|
"""
|
|
|
|
|
monkeypatch.delenv("DAMASCUS_TEST_PG_HOST", raising=False)
|
|
|
|
|
monkeypatch.delenv("DAMASCUS_TEST_PG_PORT", raising=False)
|
|
|
|
|
monkeypatch.delenv("DAMASCUS_TEST_PG_USER", raising=False)
|
|
|
|
|
monkeypatch.delenv("DAMASCUS_TEST_PG_PASSWORD", raising=False)
|
|
|
|
|
monkeypatch.delenv("DAMASCUS_TEST_PG_DB", raising=False)
|
|
|
|
|
monkeypatch.delenv("DAMASCUS_PG_HOST", raising=False)
|
|
|
|
|
monkeypatch.delenv("DAMASCUS_PG_PORT", raising=False)
|
|
|
|
|
monkeypatch.delenv("DAMASCUS_PG_USER", raising=False)
|
|
|
|
|
monkeypatch.delenv("DAMASCUS_PG_PASSWORD", raising=False)
|
|
|
|
|
monkeypatch.delenv("DAMASCUS_PG_DB", raising=False)
|
|
|
|
|
monkeypatch.delenv("DAMASCUS_ALLOW_TEST_RESET", raising=False)
|
|
|
|
|
def test_prod_safety_guard_treats_wrong_user_as_safe(monkeypatch):
|
|
|
|
|
"""127.0.0.1:5432/wrong_user/damascus = not prod (mismatched user)."""
|
|
|
|
|
_clear_pg_env(monkeypatch)
|
|
|
|
|
monkeypatch.setenv("DAMASCUS_TEST_PG_HOST", "127.0.0.1")
|
|
|
|
|
monkeypatch.setenv("DAMASCUS_TEST_PG_PORT", "5432")
|
|
|
|
|
monkeypatch.setenv("DAMASCUS_TEST_PG_USER", "wrong_user")
|
|
|
|
|
monkeypatch.setenv("DAMASCUS_TEST_PG_PASSWORD", "wrong_pw")
|
|
|
|
|
monkeypatch.setenv("DAMASCUS_TEST_PG_DB", "damascus")
|
|
|
|
|
|
|
|
|
|
conftest = _reload_conftest()
|
|
|
|
|
|
|
|
|
|
assert conftest.DB_CONFIG["host"] == "127.0.0.1"
|
|
|
|
|
assert conftest.DB_CONFIG["port"] == 5433
|
|
|
|
|
|
|
|
|
|
# The actual DB connection may fail if db-test isn't running, but
|
|
|
|
|
# the safety guard should NOT skip. We stub get_conn to assert that.
|
|
|
|
|
class FakeCursor:
|
|
|
|
|
def __enter__(self): return self
|
|
|
|
|
def __exit__(self, *a): pass
|
|
|
|
|
@@ -193,27 +216,104 @@ def test_reset_state_runs_against_test_db(monkeypatch):
|
|
|
|
|
|
|
|
|
|
monkeypatch.setattr(conftest, "get_conn", lambda: FakeConn())
|
|
|
|
|
|
|
|
|
|
# Should NOT raise skip — host is 127.0.0.1, port is 5433 (test DB)
|
|
|
|
|
# Wrong user = not prod. Should NOT skip.
|
|
|
|
|
conftest.reset_state()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_prod_host_set_constant():
|
|
|
|
|
"""The _PROD_HOSTS and _PROD_PORTS sets should include the obvious production values."""
|
|
|
|
|
from conftest import _PROD_HOSTS, _PROD_PORTS # type: ignore
|
|
|
|
|
def test_prod_safety_guard_treats_wrong_dbname_as_safe(monkeypatch):
|
|
|
|
|
"""127.0.0.1:5432/damascus/wrong_db = not prod (mismatched dbname)."""
|
|
|
|
|
_clear_pg_env(monkeypatch)
|
|
|
|
|
monkeypatch.setenv("DAMASCUS_TEST_PG_HOST", "127.0.0.1")
|
|
|
|
|
monkeypatch.setenv("DAMASCUS_TEST_PG_PORT", "5432")
|
|
|
|
|
monkeypatch.setenv("DAMASCUS_TEST_PG_USER", "damascus")
|
|
|
|
|
monkeypatch.setenv("DAMASCUS_TEST_PG_PASSWORD", "damascus")
|
|
|
|
|
monkeypatch.setenv("DAMASCUS_TEST_PG_DB", "wrong_db")
|
|
|
|
|
|
|
|
|
|
assert "db" in _PROD_HOSTS
|
|
|
|
|
assert 5432 in _PROD_PORTS
|
|
|
|
|
# Negative: 127.0.0.1 is NOT prod (it's the host-loopback port to db-test)
|
|
|
|
|
assert "127.0.0.1" not in _PROD_HOSTS
|
|
|
|
|
# Negative: 5433 is NOT prod (it's the host-bound port to db-test)
|
|
|
|
|
assert 5433 not in _PROD_PORTS
|
|
|
|
|
conftest = _reload_conftest()
|
|
|
|
|
|
|
|
|
|
class FakeCursor:
|
|
|
|
|
def __enter__(self): return self
|
|
|
|
|
def __exit__(self, *a): pass
|
|
|
|
|
def execute(self, *a, **k): pass
|
|
|
|
|
|
|
|
|
|
class FakeConn:
|
|
|
|
|
def __enter__(self): return self
|
|
|
|
|
def __exit__(self, *a): pass
|
|
|
|
|
def cursor(self): return FakeCursor()
|
|
|
|
|
def commit(self): pass
|
|
|
|
|
def close(self): pass
|
|
|
|
|
|
|
|
|
|
monkeypatch.setattr(conftest, "get_conn", lambda: FakeConn())
|
|
|
|
|
|
|
|
|
|
conftest.reset_state()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_existing_tests_unaffected():
|
|
|
|
|
"""Smoke test: the module imports cleanly with no env-var manipulation."""
|
|
|
|
|
# ── Opt-in path ──────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_prod_safety_guard_opt_in(monkeypatch):
|
|
|
|
|
"""With DAMASCUS_ALLOW_TEST_RESET=1 the guard permits prod wipe (with warning)."""
|
|
|
|
|
_clear_pg_env(monkeypatch)
|
|
|
|
|
monkeypatch.setenv("DAMASCUS_TEST_PG_HOST", "127.0.0.1")
|
|
|
|
|
monkeypatch.setenv("DAMASCUS_TEST_PG_PORT", "5432")
|
|
|
|
|
monkeypatch.setenv("DAMASCUS_TEST_PG_USER", "damascus")
|
|
|
|
|
monkeypatch.setenv("DAMASCUS_TEST_PG_PASSWORD", "damascus")
|
|
|
|
|
monkeypatch.setenv("DAMASCUS_TEST_PG_DB", "damascus")
|
|
|
|
|
monkeypatch.setenv("DAMASCUS_ALLOW_TEST_RESET", "1")
|
|
|
|
|
|
|
|
|
|
conftest = _reload_conftest()
|
|
|
|
|
|
|
|
|
|
class FakeCursor:
|
|
|
|
|
def __enter__(self): return self
|
|
|
|
|
def __exit__(self, *a): pass
|
|
|
|
|
def execute(self, *a, **k): pass
|
|
|
|
|
|
|
|
|
|
class FakeConn:
|
|
|
|
|
def __enter__(self): return self
|
|
|
|
|
def __exit__(self, *a): pass
|
|
|
|
|
def cursor(self): return FakeCursor()
|
|
|
|
|
def commit(self): pass
|
|
|
|
|
def close(self): pass
|
|
|
|
|
|
|
|
|
|
monkeypatch.setattr(conftest, "get_conn", lambda: FakeConn())
|
|
|
|
|
|
|
|
|
|
with pytest.warns(RuntimeWarning, match="PRODUCTION DB"):
|
|
|
|
|
conftest.reset_state()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# ── Constants & invariants ──────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_prod_dsn_constant_includes_all_four_prod_tuples():
|
|
|
|
|
"""_PROD_DSNS must include the four canonical production tuples."""
|
|
|
|
|
from conftest import _PROD_DSNS # type: ignore
|
|
|
|
|
|
|
|
|
|
expected = {
|
|
|
|
|
("127.0.0.1", 5432, "damascus", "damascus"),
|
|
|
|
|
("localhost", 5432, "damascus", "damascus"),
|
|
|
|
|
("db", 5432, "damascus", "damascus"),
|
|
|
|
|
("damascus-orchestrator-db-1", 5432, "damascus", "damascus"),
|
|
|
|
|
}
|
|
|
|
|
assert expected.issubset(_PROD_DSNS)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_prod_dsn_excludes_test_tuples():
|
|
|
|
|
"""_PROD_DSNS must NOT include any test DB tuple."""
|
|
|
|
|
from conftest import _PROD_DSNS # type: ignore
|
|
|
|
|
|
|
|
|
|
forbidden = {
|
|
|
|
|
("127.0.0.1", 5433, "damascus_test", "damascus_test"), # host->test
|
|
|
|
|
("db-test", 5432, "damascus_test", "damascus_test"), # in-container test
|
|
|
|
|
("localhost", 5433, "damascus_test", "damascus_test"),
|
|
|
|
|
}
|
|
|
|
|
for dsn in forbidden:
|
|
|
|
|
assert dsn not in _PROD_DSNS, f"Test DSN {dsn} wrongly in _PROD_DSNS"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_module_invariants():
|
|
|
|
|
"""Smoke test: module imports cleanly with all expected callables."""
|
|
|
|
|
import conftest # type: ignore
|
|
|
|
|
|
|
|
|
|
# Module-level invariants
|
|
|
|
|
assert callable(conftest.get_conn)
|
|
|
|
|
assert callable(conftest.reset_state)
|
|
|
|
|
assert callable(conftest.insert_work_item)
|
|
|
|
|
@@ -221,6 +321,5 @@ def test_existing_tests_unaffected():
|
|
|
|
|
assert callable(conftest.get_events)
|
|
|
|
|
assert callable(conftest.get_cost_rows)
|
|
|
|
|
assert hasattr(conftest, "clean_state")
|
|
|
|
|
# clean_state should be a fixture (pytest fixture function marker)
|
|
|
|
|
import _pytest.fixtures # noqa
|
|
|
|
|
assert isinstance(conftest.clean_state, _pytest.fixtures.FixtureFunctionDefinition)
|