fix(conftest): isolate pytest suite from production DB #25

Merged
kaykayyali merged 2 commits from fix/conftest-test-db-isolation into main 2026-06-26 15:41:51 +00:00
Owner

Problem

The pytest suite's autouse reset_state fixture connects to the production orchestrator DB (127.0.0.1:5432) and TRUNCATEs all five tables before every test. Verified on 2026-06-26: any worker running pytest against an orchestrator copy silently wipes live work_items.

Fix

  1. Default DSN points at the new db-test compose service (127.0.0.1:5433 host / db-test:5432 container). Separate volume, separate credentials, separate database — production DB at 127.0.0.1:5432 is never touched by default.
  2. _prod_safety_guard() refuses to TRUNCATE if the configured host is db or port is 5432. Refuses with pytest.skip() + RuntimeWarning pointing at the DAMASCUS_ALLOW_TEST_RESET opt-in env var.
  3. 8 unit tests in tests/test_conftest_safety.py covering default config, env overrides, prod-host skip, prod-port skip, opt-in path, default-runs path, constants, and module import invariants.

Verification

  • pytest tests/test_conftest_safety.py -v → 8 passed
  • pytest tests/contract/ tests/unit/ -q → 65 passed (no regressions)
  • Combined run → 73 passed, 0 failed

Deployment order (critical)

  1. Merge PR #23 (chore(compose): add db-test service) first
  2. Merge this PR
  3. Force-recreate the orchestrator container: docker compose up -d --force-recreate --no-deps orchestrator so it sees the new db-test service in its compose network
  4. From this point on, worker pytest runs hit db-test instead of prod

Rollback

If a worker needs to TRUNCATE prod for a one-off diagnostic, set DAMASCUS_ALLOW_TEST_RESET=1 in its env. The guard emits a RuntimeWarning so the wipe is at least visible in the test logs.

Companion to PR #22 (MCP fix, already merged) and PR #23 (db-test compose service).

## Problem The pytest suite's autouse `reset_state` fixture connects to the production orchestrator DB (127.0.0.1:5432) and TRUNCATEs all five tables before every test. Verified on 2026-06-26: any worker running pytest against an orchestrator copy silently wipes live `work_items`. ## Fix 1. **Default DSN points at the new `db-test` compose service** (127.0.0.1:5433 host / db-test:5432 container). Separate volume, separate credentials, separate database — production DB at 127.0.0.1:5432 is never touched by default. 2. **`_prod_safety_guard()`** refuses to TRUNCATE if the configured host is `db` or port is 5432. Refuses with `pytest.skip()` + `RuntimeWarning` pointing at the `DAMASCUS_ALLOW_TEST_RESET` opt-in env var. 3. **8 unit tests** in `tests/test_conftest_safety.py` covering default config, env overrides, prod-host skip, prod-port skip, opt-in path, default-runs path, constants, and module import invariants. ## Verification - `pytest tests/test_conftest_safety.py -v` → 8 passed - `pytest tests/contract/ tests/unit/ -q` → 65 passed (no regressions) - Combined run → 73 passed, 0 failed ## Deployment order (critical) 1. Merge **PR #23** (`chore(compose): add db-test service`) first 2. Merge **this PR** 3. Force-recreate the orchestrator container: `docker compose up -d --force-recreate --no-deps orchestrator` so it sees the new `db-test` service in its compose network 4. From this point on, worker pytest runs hit `db-test` instead of prod ## Rollback If a worker needs to TRUNCATE prod for a one-off diagnostic, set `DAMASCUS_ALLOW_TEST_RESET=1` in its env. The guard emits a `RuntimeWarning` so the wipe is at least visible in the test logs. Companion to PR #22 (MCP fix, already merged) and PR #23 (db-test compose service).
kaykayyali added 1 commit 2026-06-26 15:36:31 +00:00
fix(conftest): isolate pytest suite from production DB
All checks were successful
test / contract-and-unit (pull_request) Successful in 13s
d40028f021
Production DB at 127.0.0.1:5432 holds live orchestrator state.
The tests/conftest.py autouse reset_state fixture connects to it
and runs TRUNCATE before every test, silently wiping work_items,
human_issues, cost_ledger, events_outbox, and coordination_gates.

Verified 2026-06-26: the active AnswerPopover worker (PR #21)
ran pytest and wiped freshly-ingested damascus-roadmap work_items
twice in 40 minutes before the architecture row + stories were
re-ingested.

This patch:

1. Defaults DB_CONFIG to 127.0.0.1:5433 (the host-bound port for
   the new db-test compose service, see PR #23). Same database
   is reachable from inside the orchestrator container at
   db-test:5432 via the compose network.

2. Adds _PROD_HOSTS ({"db"}) and _PROD_PORTS ({5432}) constants.
   The new _prod_safety_guard() refuses to TRUNCATE if either
   matches the current config. Refuses with pytest.skip() and a
   RuntimeWarning pointing at the DAMASCUS_ALLOW_TEST_RESET env var
   for intentional opt-in.

3. Adds 8 unit tests in tests/test_conftest_safety.py covering:
   - Default DB_CONFIG points at the test DB
   - DAMASCUS_TEST_PG_* env vars override defaults
   - Hostname 'db' triggers skip without opt-in
   - Port 5432 triggers skip without opt-in
   - DAMASCUS_ALLOW_TEST_RESET=1 permits TRUNCATE (with warning)
   - Default config (127.0.0.1:5433) runs TRUNCATE without skip
   - _PROD_HOSTS/_PROD_PORTS constants have correct membership
   - Module imports cleanly with all existing fixtures intact

Companion to PR #23 (chore(compose): add db-test service).
After both PRs merge, rebuild the orchestrator container so it
sees db-test in its compose network; pytest runs from a worker
worktree will then connect to db-test (port 5433 host / 5432
container) and prod work_items survives.

Verification:
- pytest tests/test_conftest_safety.py -v  → 8 passed
- pytest tests/contract/ tests/unit/ -q   → 65 passed (no regressions)
- pytest tests/test_conftest_safety.py tests/contract/ tests/unit/ -q
  → 73 passed, 0 failed
kaykayyali merged commit e0b4160a55 into main 2026-06-26 15:41:51 +00:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: kaykayyali/damascus-orchestrator#25