fix(integration): use testcontainers.community.redis + asyncpg driver (pre-deploy break) - #2397
fix(integration): use testcontainers.community.redis + asyncpg driver (pre-deploy break)#2397farnalabs wants to merge 7 commits into
Conversation
…er for migration test - saq/conftest.py and bdd test_personas.py imported the deprecated testcontainers.redis (now emits a DeprecationWarning that pytest's strict filterwarnings turns into a collection error), breaking the integration suite. Switch to testcontainers.community.redis (same migration as #2327 did for postgres) and declare the redis extra. - test_migration_0166_uuid_promotion.py only swapped the scheme but left the psycopg2 driver in place (Testcontainers returns postgresql+psycopg2://), so create_async_engine tried to import the uninstalled psycopg2. Mirror the conftest.py replace that also swaps psycopg2 -> asyncpg. Fixes pre-deploy integration-test collection errors on main.
…n env The integration_client fixture builds Settings without modulo_system_database_url, so the process-global system engine fell back to the scoped app role and system_engine_is_fallback() became True. Pre-auth paths (webhook trigger delivery) then refuse with 503 (system_bootstrap_degraded), failing every integration test that exercises them. Point MODULO_SYSTEM_DATABASE_URL at the migrated testcontainer (its superuser has BYPASSRLS), matching the working system engine the suite expects, so webhook/cross-org paths return real results instead of 503.
…ration suite serially - test_guardrail_correction.py inserted a literal 'node_a' string into feedback_records.producing_node_id, which migration 0166 promoted to a UUID column, so every correction test failed with 'invalid input syntax for type uuid'. Bind the real rig node UUID instead. - Run the pre-deploy integration suite without -n 2. The suite has parallel races under xdist (duplicate (organisation_id, name) pipeline inserts in test_variant_group, concurrent ALTER TABLE in test_fenced_json_typing_regression, cross-test FK races in test_pipeline) that the current environment makes deterministic; the prior green run only avoided them by luck. Serial execution removes the whole class of concurrency collisions. The 90-minute job timeout comfortably covers the serial runtime.
Branch Fixer: pre-deploy integration-test break on mainRoot cause of the failing deploy (run on Fixes in this PR
VerificationThe Commit SHAs:
|
farnalabs
left a comment
There was a problem hiding this comment.
Review feedback (feedback only, not the formal decision): Verified all four fixes against the codebase — (1) testcontainers.community.redis import is correct and required: pyproject filterwarnings has error::DeprecationWarning, so the deprecated module import was a collection error; (2) the psycopg2→asyncpg driver swap in test_migration_0166 is real: get_connection_url() returns postgresql+psycopg2:// in testcontainers 4.x so the old bare postgresql:// replace was a no-op; (3) MODULO_SYSTEM_DATABASE_URL wiring is consumed by get_or_create_system_engine (api/dependencies.py) and unblocks the 503 system_bootstrap_degraded gate on pre-auth paths (webhooks/slack); (4) producing_node_id now satisfies the 0166 FK to nodes.id via the rig's materialised node row. Minor nits inline. CI green, mergeable, no test removals/skips.
farnalabs
left a comment
There was a problem hiding this comment.
Minor nits from the review (feedback only, not the formal decision):
| raw = pg.get_connection_url().replace("postgresql://", "postgresql+asyncpg://", 1) | ||
| # Testcontainers' PostgresContainer returns a ``postgresql+psycopg2://`` URL, | ||
| # so the bare ``postgresql://`` replace below misses it. Mirror conftest.py and | ||
| # also swap the ``psycopg2`` driver for ``asyncpg`` (psycopg2 is not installed). |
There was a problem hiding this comment.
The postgresql+psycopg2 -> asyncpg swap is now copy-pasted in three test locations (tests/integration/conftest.py:103, tests/bdd/steps/test_personas.py:1835, here). Consider extracting a small shared to_asyncpg_url() test helper so the next driver change is a one-line edit. Non-blocking.
| - name: Integration tests | ||
| working-directory: backend | ||
| run: uv run --no-build --no-sync pytest tests/integration/ -m integration -n 2 --timeout=300 --cov=src/modulo --cov-report=xml --cov-fail-under=0 -q | ||
| run: uv run --no-build --no-sync pytest tests/integration/ -m integration --timeout=300 --cov=src/modulo --cov-report=xml --cov-fail-under=0 -q |
There was a problem hiding this comment.
Dropping -n 2 makes the integration suite serial - fine for reliability, but the adjacent comment only explains the 300s per-test timeout, not why parallelism was removed. A one-line note (e.g. shared testcontainer state races between xdist workers) would help future readers. Note CI wall time roughly doubles. Non-blocking.
| # auth.dependencies._verify_identity hits tables that don't exist there and | ||
| # every API-backed integration test fails with a 503. | ||
| session_monkeypatch.setenv("DATABASE_URL", url) | ||
| # Also point the system (BYPASSRLS) engine at the same migrated testcontainer. |
There was a problem hiding this comment.
Informational: get_or_create_system_engine() caches a process-global singleton, so this session-scope setenv only helps if it lands before the first system-engine init. Today every API-backed integration test depends on migrated_db_url -> db_url, so ordering is safe - just worth keeping in mind if a future test touches the system engine without the DB fixtures.
modulo-reviewbot
left a comment
There was a problem hiding this comment.
Approved — automated multi-lens review verdict (APPROVE); all fixes verified real:
- backend/pyproject.toml: testcontainers extra widened to
[postgres,redis]in both dependency groups — required for thetestcontainers.community.redisimport enforced by theerror::DeprecationWarningfilter (pyproject.toml:441). - backend/tests/bdd/steps/test_personas.py:1827:
RedisContainerimport moved totestcontainers.community.redis, matching the postgres community migration. - backend/tests/integration/saq/conftest.py: deprecated
testcontainers.redisimport replaced withtestcontainers.community.redisand the warnings-suppression shim removed — no non-community testcontainers imports remain in the test suite. - backend/tests/integration/conftest.py:116:
MODULO_SYSTEM_DATABASE_URLsetenv is real — without itsystem_engine_is_fallback()is True and pre-auth paths (webhooks.py:212/519, slack.py:183) 503 withsystem_bootstrap_degraded; testcontainer superuser has BYPASSRLS. - backend/tests/integration/db/test_migration_0166_uuid_promotion.py:75: driver swap fix verified —
get_connection_url()returnspostgresql+psycopg2://, so the old barepostgresql://replace was a no-op; the new chain handles both URL forms. - backend/tests/integration/test_guardrail_correction.py:219:
producing_node_idnow uses the rig's materialisednodes.id, satisfying the 0155/0164/0165 FK + 0166 uuid promotion. - .github/workflows/deploy.yml:262: integration tests run serially (dropped
-n 2) — reliability tradeoff for shared-container flakiness; no skip/xfail added, coverage gate unchanged.
Three minor non-blocking nits were posted as inline feedback (document the removal of parallelism; consider a shared to_asyncpg_url() helper for the now-triplicated URL munging; informational note on process-global system-engine singleton ordering).
CI green, PR mergeable. is_high_risk = false (2-node topology: the review node's QA gate is the authorizing control).
…ole, not admin The break-glass deploy gate failed: 'modulo_system role does not have BYPASSRLS'. bootstrap_role._bootstrap derives the system role NAME from MODULO_SYSTEM_DATABASE_URL, so pointing it at the testcontainer admin URL (role 'test') provisioned the admin role and never created modulo_system, failing the gate's posture assertion. Point MODULO_SYSTEM_DATABASE_URL at the modulo_system role so bootstrap_roles creates it (LOGIN BYPASSRLS) with the matching password. This keeps the process-global system engine working against the migrated testcontainer AND satisfies the break-glass gate's modulo_system BYPASSRLS check.
Branch Fixer: break-glass deploy gate (
|
farnalabs
left a comment
There was a problem hiding this comment.
Review feedback (non-binding; formal decision posted by post-decision node). Reviewed head b9b5c85 (payload SHA 2d0ecd7 was stale; author pushed two further fix commits after the 14:38Z approval of c43a08b — re-reviewed per timestamp rule). Verdict recommendation: APPROVE.
All four commits are coherent CI-stability fixes, each traced to a concrete failure mode:
- conftest.py: MODULO_SYSTEM_DATABASE_URL now points at the modulo_system role instead of the admin URL. Verified against bootstrap_role.py:304-311 — sys_user/sys_pass are derived from that env var, so the admin URL would have provisioned a wrong-named role and left modulo_system uncreated (break-glass gate posture assertion fails). The env var is set by the session-scoped db_url fixture before bootstrap_roles() runs in the migration fixture, and patch.dict doesn't remove it, so modulo_system/syspass is actually provisioned. _with_credentials is reused, not duplicated.
- test_migration_0166_uuid_promotion.py: testcontainers returns postgresql+psycopg2:// so the bare postgresql:// replace was a no-op; adding .replace(psycopg2, asyncpg) is correct (psycopg2 not installed).
- test_guardrail_correction.py: producing_node_id now binds the rig's real node UUID, satisfying the 0166 FK to nodes.id (migration 0166 promotes the column to UUID FK; hardcoded 'node_a' would violate it).
- Redis import swap to testcontainers.community.redis in saq/conftest.py + bdd/steps/test_personas.py, with the redis extra added to pyproject in both dev groups — correct under the error::DeprecationWarning filter; removing the now-unneeded warnings shim in saq/conftest.py is proper cleanup. No remaining testcontainers.redis imports repo-wide.
- deploy.yml: dropping -n 2 makes the suite serial, matching ci.yml's serial invocation. No test deletions, no skip/xfail additions.
Minor (non-blocking): the bdd test_personas.py keeps its DeprecationWarning catch_warnings wrapper around the community import — harmless belt-and-suspenders, could be dropped in a follow-up. CI on b9b5c85: Integration tests (changed) + BDD + Lint + Schema freshness + migrations all green; Test (Backend) still running at review time.
modulo-reviewbot
left a comment
There was a problem hiding this comment.
Approved by the post-decision node executing the review node's APPROVE verdict (2-node topology: the review node's full multi-lens QA gate is the authorizing control). Review was conducted on current head b9b5c85 — the payload SHA 2d0ecd7 was stale (two non-merge fix commits followed the prior approved review).
Key findings verified by the review:
- .github/workflows/deploy.yml: removed
-n 2so the integration suite runs serially, matching ci.yml's serial invocation; timeout unchanged (300s/test). No skips or test removals. - backend/pyproject.toml: added the redis extra to
testcontainers[postgres,redis]>=4.14.2in both dependency groups — required for the community RedisContainer migration. - Redis imports moved to
testcontainers.community.redisin SAQ and BDD tests, with the now-unnecessary warnings shim removed; notestcontainers.redisimports remain repo-wide (required under theerror::DeprecationWarningfilterwarnings policy). Minor non-blocking note: the redundantcatch_warnings(DeprecationWarning)wrapper in bdd test_personas.py could be dropped in a follow-up. - backend/tests/integration/conftest.py: MODULO_SYSTEM_DATABASE_URL now targets the
modulo_systemrole instead of the admin URL — verified bootstrap_role.py:304-311 derives the system role name/password from this env var, it is set before bootstrap_roles() runs, and the break-glass BYPASSRLS posture assertion passes. Reuses the existing_with_credentialshelper. - backend/tests/integration/db/test_migration_0166_uuid_promotion.py: correct fix — testcontainers returns
postgresql+psycopg2://, so the barepostgresql://replace was a no-op; the added psycopg2→asyncpg swap mirrors conftest.py and is required since psycopg2 is not installed. - backend/tests/integration/test_guardrail_correction.py: producing_node_id now binds the rig's real node UUID, satisfying migration 0166's UUID FK from feedback_records.producing_node_id to nodes.id.
No test deletions, no skip/xfail additions; no API/frontend changes so contract round-trip is N/A. CI on head shows Integration tests (changed), BDD, Lint, Schema freshness, and migration checks green; mergeable state true.
…ontainers-deprecation-1788357736 # Conflicts: # backend/tests/bdd/steps/test_personas.py # backend/tests/integration/db/test_migration_0166_uuid_promotion.py # backend/tests/integration/saq/conftest.py
|
Resolved merge conflicts with
No product code was changed — only merge conflict markers in test/conftest files were reconciled in favour of this branch's testcontainers-deprecation fixes. CI should re-run green now. |
The BDD (full suite) CI step failed at 'uv sync --frozen' because the pytest-bdd dev dependency was pinned to a GitHub git ref/commit (pytest-dev/pytest-bdd#827). GitHub rejects anonymous fetch-by-SHA, and even the ref-based pin forces a SHA fetch when the uv git cache is cold, so the install step died with 'could not read Username'. No PyPI release carries the pytest-9.1 _register_fixture(nodeid=...) fix yet (pytest-dev/pytest-bdd#823); 8.1.0 is the latest. Vendor the prebuilt wheel (built from pytest-bdd commit 60f6625b) under backend/vendor/ and point [tool.uv.sources] at it so the dependency installs fully offline. Replace with a >=8.1.1 PyPI pin once the fix is released. Fixes the red BDD (full suite) check on head commit of fix/integration-testcontainers-deprecation-1788357736 (PR #2397).
Automated fix: vendored pytest-bdd wheel (BDD full-suite install failure)Root cause. The BDD (full suite) job died at Fix (commit Trade-off / follow-up. This is a stopgap until pytest-bdd |
farnalabs
left a comment
There was a problem hiding this comment.
Re-review feedback (head 0ef0b92) — reviewer verdict: CHANGES_REQUESTED
Context: the prior review APPROVED b9b5c85 at 14:57Z; since then the head moved (merge f4fec6d + 0ef0b92) and main gained #2400, #2396 and #2405 — this PR now overlaps all three.
Blocker — merging this PR breaks Lint (Backend) (already red on this head's check-runs)
backend/tests/integration/test_guardrail_correction.py: the'node_a'→:nidparam fix already landed on main via #2400 (d444457). The pull_request lint run checks out the merge ref, where main's"nid": str(rig["node_id"])(line 218) and this PR's added"nid"(line 220) both end up in the same dict →ruff F601 dictionary key literal "nid" repeated→Lint (Backend)failed on this head. Rebase onto origin/main; this hunk becomes redundant and should be dropped.
Major — the vendored wheel now duplicates main's #2405
backend/vendor/pytest_bdd-8.1.0-py3-none-any.whl+ the[tool.uv.sources]path pin: main fixed the sameuv sync --frozengit-fetch root cause by authenticating GitHub fetches (#2405, landed 16:23Z — 4 minutes before this head was pushed). A committed binary wheel is a heavier mechanism to maintain (manual rebuilds until a ≥8.1.1 PyPI release ships). Recommend dropping the vendoring after rebase and keeping main's authenticated git pin. For the record, I verified provenance: the wheel's sources are byte-identical to pytest-bdd PR #827 head (commit 60f6625, "fix: avoid deprecated nodeid argument to _register_fixture") — no tampering found. If vendoring is kept anyway, pin the wheel sha256 in a comment and document the build command.
Minor
.github/workflows/deploy.yml: the-n 2removal is unexplained in the PR body/commit message. Main's #2396 ("serialize shared-DB setup across -n 2 workers") fixed the actual xdist problem — after rebasing, restoring-n 2is likely correct; dropping it doubles the deploy integration runtime.backend/tests/bdd/steps/test_personas.py: the targetedwarnings.catch_warnings()suppression works (pyproject setserror::DeprecationWarning), but a module-scoped ignore infilterwarningswould keep other deprecations visible at these imports; also note in a comment which warning still fires, since the imports already use the non-deprecatedtestcontainers.community.*location.backend/uv.lock: the httpcore2/pandas marker simplifications (numpy/python-dateutil/pytz/tzdata markers dropped) are unrelated re-resolution churn — keep the lock diff minimal on rebase.
Verified good (no action needed)
backend/tests/integration/conftest.pyMODULO_SYSTEM_DATABASE_URL: traced the full path — the system engine is created lazily on first use, the autouse_reset_settings_cacheclears theget_settingslru_cache per test, andbootstrap_role.pyderives the system role name + password from this same env var, somodulo_system/syspassis self-consistent and the break-glass BYPASSRLS posture check passes. The bootstrappatch.dict-scoped env was indeed losing the var after bootstrap — this fixes it._with_credentialsis properly reused.backend/pyproject.tomltestcontainers[postgres,redis]extra + uv.lock: consistent with thetestcontainers.community.redisimport in the saq conftest.backend/tests/integration/db/test_migration_0166_uuid_promotion.pyandbackend/tests/integration/saq/conftest.py: comment-only clarifications, accurate.
modulo-reviewbot
left a comment
There was a problem hiding this comment.
Formal review: CHANGES_REQUESTED
Decision carried from the review node (authoritative in this topology). Blocking findings:
-
backend/tests/integration/test_guardrail_correction.py — BLOCKER: this hunk duplicates the identical fix already on main via #2400 (d444457); on the merge ref both "nid" keys land in the same dict and ruff F601 fails, which is why "Lint (Backend)" is red on this head's check-runs. Rebase onto origin/main and drop this hunk.
-
backend/vendor/pytest_bdd-8.1.0-py3-none-any.whl + backend/pyproject.toml [tool.uv.sources]: the vendored-wheel mechanism duplicates main's #2405 (authenticated git fetches fix the same
uv sync --frozenroot cause, landed 16:23Z, 4 min before this head). Recommend dropping the vendoring after rebase. Provenance was verified: the wheel is byte-identical to pytest-bdd PR #827 head (commit 60f6625) — no tampering; if kept anyway, pin the wheel sha256 and document the build command. -
.github/workflows/deploy.yml: the
-n 2removal for the deploy integration run is unexplained in the PR body/commit message; main's #2396 (serialize shared-DB setup across-n 2workers) fixed the actual xdist problem, so after rebasing, restoring-n 2is likely correct. As-is it doubles deploy integration runtime. -
backend/tests/bdd/steps/test_personas.py: the targeted
warnings.catch_warnings()DeprecationWarning suppression works (pyproject setserror::DeprecationWarning), but a module-scoped ignore infilterwarningswould keep other deprecations visible; also comment which warning still fires since the imports already use the non-deprecated testcontainers.community.* location.
Verified good (no action): conftest.py MODULO_SYSTEM_DATABASE_URL fix (lazy system-engine creation, per-test get_settings lru_cache clear, bootstrap_role.py derives the modulo_system role/password from the same env var, break-glass BYPASSRLS posture check passes, _with_credentials properly reused); pyproject testcontainers[postgres,redis] extra consistent with the saq conftest import and uv.lock; comment-only clarifications in test_migration_0166_uuid_promotion.py and saq conftest.py are accurate; uv.lock consistent (keep the marker-churn diff minimal on rebase).
Required action: rebase onto origin/main, drop the redundant "nid" hunk, and re-evaluate the vendored wheel and -n 2 removal against #2405/#2396.
Fix: Lint (Backend) failure — duplicate
|
farnalabs
left a comment
There was a problem hiding this comment.
Review feedback (non-blocking): see inline comments.
| - name: Integration tests | ||
| working-directory: backend | ||
| run: uv run --no-build --no-sync pytest tests/integration/ -m integration -n 2 --timeout=300 --cov=src/modulo --cov-report=xml --cov-fail-under=0 -q | ||
| run: uv run --no-build --no-sync pytest tests/integration/ -m integration --timeout=300 --cov=src/modulo --cov-report=xml --cov-fail-under=0 -q |
There was a problem hiding this comment.
nit: Removing -n 2 doubles the pre-deploy integration wall time, and main recently invested in making this suite parallel-safe (#2329, #2396). The commit message says "run integration suite serially" but nothing in the workflow records why serial is required now. Please add a one-line comment above this step (or restore -n 2 if the parallel blockers are actually gone).
| # "modulo_system has BYPASSRLS" posture assertion. bootstrap_roles creates | ||
| # modulo_system (LOGIN BYPASSRLS) with these credentials, so the system engine | ||
| # connects correctly and the gate's posture check passes. | ||
| session_monkeypatch.setenv("MODULO_SYSTEM_DATABASE_URL", _with_credentials(url, "modulo_system", "syspass")) |
There was a problem hiding this comment.
nit (redundant but harmless): migrated_db_url already sets MODULO_SYSTEM_DATABASE_URL to the identical value (_with_credentials(db_url, "modulo_system", "syspass")) and every db_url consumer transitively requests migrated_db_url, so this early setenv does not change observable behavior. Also note the comment's "every integration test that exercises them fails" overstates the pre-PR state, since main's existing wiring in migrated_db_url already set the var. Fine as belt-and-braces; consider trimming the comment. Verified: bootstrap_role.py does derive the system role name/password from this URL, so pointing it at modulo_system (not the admin URL) is correct.
farnalabs
left a comment
There was a problem hiding this comment.
Review feedback (non-blocking) — verified fixes + 3 minor nits
Verified during review:
- Vendored wheel is legitimate: it contains the claimed pytest 9.1 fix (
compat.pypassesnode=request.nodeinstead of the deprecatednodeidfor pytest >= 9.1, matching pytest-dev/pytest-bdd#827 / commit 60f6625b); dist-info RECORD hashes are internally consistent; the delta vs the PyPI 8.1.0 wheel is exactly the upstream PR-branch typing/refactor changes; no suspicious code (the base64/pickle helpers inutils.pyexist in upstream 8.1.0 too). uv.lock's path source + sha256 match the committed wheel. - The
test_guardrail_correction.pyfix is a real, provable fix: after migration 0166,feedback_records.producing_node_idis a UUID FK tonodes.id, so the old'node_a'literal fails the cast/FK; the boundrig["node_id"]is materialized ineval_definitionsfirst. pyproject.tomlhaserror::DeprecationWarning, so the scopedcatch_warningsaround the testcontainers imports intest_personas.pyis necessary and matches the existing pattern intests/connectors/conftest.py.testcontainers[postgres,redis]matches theRedisContainerusage intests/integration/saq/conftest.py;[tool.uv.sources]has no conflicts; uv.lock marker churn is benign re-lock consolidation.
Minor nits (non-blocking):
backend/Dockerfile.mutation—uv sync --dev --frozen(line 23) now requiresbackend/vendor/pytest_bdd-8.1.0-py3-none-any.whlin the build context, but the Dockerfile only COPYspyproject.toml+uv.lock(line 20), so the manual mutation-image build fails at sync. (It was already broken with the git pin — no git inpython:3.14-slim— so this is not a regression; a one-lineCOPY backend/vendor/ vendor/would complete the offline-sync goal. Nothing in CI builds this image.).github/workflows/deploy.yml— dropping-n 2doubles pre-deploy integration runtime while main recently invested in parallel-safety (#2329, #2396); please document why serial is required (see inline comment).backend/tests/integration/conftest.py— the newdb_urlsetenv is redundant withmigrated_db_url's identical setenv (see inline comment).
No test deletions, no skip/xfail additions, no frontend/API-shape changes. Suggestion for a follow-up: record the wheel's sha256 (78b8671e...) next to the [tool.uv.sources] comment for auditability, and swap to the >=8.1.1 PyPI pin when released (already noted in the comments).
modulo-reviewbot
left a comment
There was a problem hiding this comment.
Approved. CI is green and the PR is mergeable; re-reviewed at head 0d079e0 following the prior CHANGES_REQUESTED review.
Verified core fixes:
- Vendored pytest-bdd 8.1.0 wheel is legitimate: contains the claimed pytest>=9.1 fix in compat.py (node= instead of deprecated nodeid=, matching pytest-dev/pytest-bdd#827 commit 60f6625b), dist-info RECORD hashes internally consistent, and the byte delta vs the PyPI 8.1.0 wheel is only upstream typing/refactor changes; no suspicious code.
- tests/integration/test_guardrail_correction.py: real, provable fix — after migration 0166 feedback_records.producing_node_id is a UUID FK to nodes.id, so the previous 'node_a' literal fails the cast/FK; the bound :nid now uses rig["node_id"] and no duplicate param key remains.
- testcontainers.community import suppression is necessary under the error::DeprecationWarning filter and narrowly scoped, matching the existing pattern in tests/connectors/conftest.py.
- pyproject.toml/uv.lock consistent: pytest-bdd resolves from the vendor path with sha256, testcontainers extra widened to [postgres,redis] matching the RedisContainer usage; remaining marker churn is benign.
Non-blocking follow-ups (details in inline comments):
- Dockerfile.mutation: uv sync --dev --frozen needs backend/vendor/ copied into the build context (pre-existing breakage; nothing in CI builds this image).
- deploy.yml: dropping -n 2 doubles pre-deploy integration wall time while main invested in parallel-safety (#2329, #2396) — please add a one-line comment or restore parallelism.
- tests/integration/conftest.py: the new MODULO_SYSTEM_DATABASE_URL setenv in db_url is redundant with migrated_db_url's identical wiring (harmless).
Also suggested: record the wheel sha256 (78b8671e...) in the [tool.uv.sources] comment and swap to the >=8.1.1 PyPI pin once released.
Branch Fixer: no fix pushed — this PR is fully superseded by mainTriggered by the 1. The failure this PR was created to fix is gone on mainThis PR was auto-created after
The only failure in 33654686714 is 2. All 12 checks on this head are already green
3. Each review finding resolves to "already on main"
Also redundant: 4. The residual after rebasing is two comment blocksI merged RecommendationClose as superseded. Merging this branch as-is can only cause harm: it reverts #2396's parallel-safety work, drops main's Optional follow-ups, neither blocking (deliberately not bundled here):
No files changed, nothing pushed, branch left at |
|
Branch Fixer — merge-conflict (no fix required) The merge queue reported a conflict for this PR (run 33660959637), but on inspection the branch now merges cleanly into current Root cause: the conflict was against an older If a new conflict reappears after further |
… merging main Addresses the CHANGES_REQUESTED review on #2397. Main absorbed most of this branch's fixes independently, so this merges origin/main and reduces the PR to only the parts main does not already have. 1. Vendored pytest-bdd wheel dropped (review item 2). #2405 (5b3d2cf) landed GIT_CONFIG_KEY_0 insteadOf auth in every workflow, fixing the same `uv sync --frozen` root cause. Restored main's refs/pull/827/head git pin, removed [tool.uv.sources] and backend/vendor/. Verified `uv sync --frozen` resolves ANONYMOUSLY (no token, GIT_TERMINAL_PROMPT=0) and installs pytest-bdd from commit 60f6625b - the same commit the wheel was built from, so the pytest-9.1 _register_fixture fix is unchanged. Also moots the Dockerfile.mutation vendor/-in-build-context nit. 2. `-n 2` restored for the deploy integration run (review item 3). #2396 (4ad0558) serialises the shared-DB setup behind advisory lock (72002, 1), which is the actual xdist bug the removal was working around. Commented why it is safe so the next reader does not drop it again. 3. testcontainers DeprecationWarning suppression removed (review item 4). Proved no warning fires: on the locked testcontainers 4.15.0 both testcontainers.community.postgres and .redis import cleanly under `-W error`, and an in-tree pytest probe passed while a control test raising DeprecationWarning failed (confirming error::DeprecationWarning was live). The wrapper was a leftover from the pre-#2327 testcontainers.redis imports, so test_personas.py is now byte-identical to main - all deprecations stay visible instead of being blanket-ignored. 4. `nid` F601 blocker (review item 1) confirmed fixed: test_guardrail_correction.py is byte-identical to main and `ruff check .` passes on the materialised merge. Remaining delta vs main: the testcontainers[postgres,redis] extra (+ a minimal 9-line uv.lock edit, no marker churn), the session-wide MODULO_SYSTEM_DATABASE_URL wiring, and explanatory comments.
Branch Fixer: review feedback addressed (commit
|
Correction: this PR was already closed — superseded by #2402My previous comment was written against a live PR. Checking afterwards: this PR was closed at 17:38:02Z, ~10 minutes before I pushed Nothing of substance is left unlanded. The one fix unique to this branch — the session-wide
The only line not on main is the So closing this PR was correct — I'm standing down rather than reopening it. Leaving |
Auto-created by the Branch Fixer after the Deploy pre-deploy integration tests failed on main (commit fe2aefd).
Root cause
The integration suite broke under the current
testcontainersversion drift (psycopg2 is no longer a transitive dependency andtestcontainers.redisis deprecated). Two deterministic collection errors:tests/integration/saq/conftest.py(andtests/bdd/steps/test_personas.py) importedtestcontainers.redis, which now emits aDeprecationWarningthat pytest's strictfilterwarnings = errorturns into a collection error for the wholetests/integration/saqpackage.tests/integration/db/test_migration_0166_uuid_promotion.pydidget_connection_url().replace("postgresql://", "postgresql+asyncpg://", 1)— but Testcontainers' PostgresContainer returnspostgresql+psycopg2://, so the replace missed and the URL kept thepsycopg2driver, which is not installed (create_async_enginethen raisedModuleNotFoundError: No module named 'psycopg2').Fix
RedisContainerfromtestcontainers.community.redis(the same migration fix(deploy): resolve pre-deploy integration-test failures #2327 did for postgres) and declare theredisextra inpyproject.toml.tests/integration/conftest.pyin the migration test:.replace("postgresql://", "postgresql+asyncpg://", 1).replace("psycopg2", "asyncpg")so the asyncpg driver is used.These are the only code-level, deterministic failures; the remaining integration failures on the failing run were environmental flakiness (identical code passed on the prior green run) and are not addressed here. CI re-run is the verification gate.
Fixes: pre-deploy integration-test collection errors (saq + migration_0166).