Skip to content

Improve backend CI test efficiency#429

Merged
thewrz merged 10 commits into
mainfrom
chore/backend-ci-refactor
Jun 14, 2026
Merged

Improve backend CI test efficiency#429
thewrz merged 10 commits into
mainfrom
chore/backend-ci-refactor

Conversation

@thewrz

@thewrz thewrz commented Jun 14, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Rework backend pytest fixtures to keep one SQLite schema per process and isolate each test with transaction rollback.
  • Add a no-background FastAPI test lifespan and direct JWT auth headers to remove repeated startup and bcrypt overhead from ordinary endpoint tests.
  • Add slow-test duration reporting, conservative xdist execution, and a SessionLocal alias audit guard.

Impact

  • Keeps production app startup behavior unchanged: app = create_app() still uses the real lifespan.
  • Keeps the backend coverage gate enforced at 85%.
  • Cuts the local full backend run to about one minute with pytest -n 4 --dist=loadfile.

Testing

  • Backend lint: ruff check .
  • Backend format: ruff format --check .
  • Backend security: bandit -r app -c pyproject.toml -q
  • Lockfile: uv lock --check
  • Backend tests: pytest -n 4 --dist=loadfile --cov=app --cov-report=term-missing --cov-branch --cov-fail-under=85 --durations=25 --durations-min=1.0 --tb=short -q (2827 passed, coverage 87.90%, 63.21s)
  • Alembic: alembic upgrade head && alembic check against temporary Postgres 16 (No new upgrade operations detected)

Note: local default localhost:5432 was occupied by another project database, so Alembic was verified with an explicit temporary Postgres URL on port 55432.

Summary by CodeRabbit

Release Notes

  • Chores

    • Optimized backend CI to run tests in parallel and added test duration reporting to help spot slowdowns.
    • Updated development tooling to support parallel pytest runs locally.
  • Tests

    • Improved backend test harness reliability with tighter in-memory SQLite isolation, transaction/savepoint handling, and regression coverage for lifespan/background task behavior.
    • Streamlined authentication setup by generating test auth tokens directly (no login requests).
  • Bug Fixes

    • Standardized 500 error responses to avoid exposing debug details.

thewrz and others added 9 commits June 14, 2026 10:14
Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: Codex <noreply@openai.com>
@coderabbitai

coderabbitai Bot commented Jun 14, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 7f20a4dd-94fe-462d-9f3f-a3912aabcbd6

📥 Commits

Reviewing files that changed from the base of the PR and between 516e06f and ca5783f.

📒 Files selected for processing (2)
  • server/app/main.py
  • server/tests/test_api.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • server/app/main.py

📝 Walkthrough

Walkthrough

Refactors server/app/main.py into a create_app() factory with a no_background_lifespan seam. Reworks server/tests/conftest.py to use session-scoped SQLite schema setup, per-test SAVEPOINT-backed transaction rollback, centralized SessionLocal module patching, and direct JWT auth headers. Adds harness regression tests, updates affected tests, adds pytest-xdist, and enables -n 4 --dist=loadfile in CI.

Changes

Backend CI Efficiency Refactor

Layer / File(s) Summary
App factory, lifespan control, and exception handling
server/app/main.py
Extracts global_exception_handler, adds run_background_tasks flag to lifespan, introduces no_background_lifespan helper, and wraps all app wiring in create_app(); module-level app is now assigned via create_app().
Test harness: transaction isolation, SessionLocal patching, direct JWT auth
server/tests/conftest.py
Adds session-scoped _database_schema and SAVEPOINT-backed per-test db fixture with monkeypatched SessionLocal across listed modules; builds test_app via create_app(no_background_lifespan); replaces HTTP-login auth fixtures with direct JWT header generation using precomputed password hash constants.
Harness regression tests
server/tests/test_test_harness.py
New test file verifying: external-transaction + savepoint mode, cross-test rollback, no-background lifespan skips tasks, real lifespan starts/cancels tasks, _auth_headers_for_user produces valid tokens, and an AST scan confirms all SessionLocal-importing modules are classified in the registry.
Updated tests for new harness
server/tests/test_api.py, server/tests/test_llm_call_log_retention.py
test_api.py builds test_app via create_app(no_background_lifespan) instead of the global app. test_llm_call_log_retention.py removes monkeypatch session wiring, relying on centralized SessionLocal patching from conftest.py.
CI xdist parallelism and dependency
.github/workflows/ci.yml, server/pyproject.toml
Changes backend CI test command to pytest -n 4 --dist=loadfile with --durations=25 --durations-min=1.0; adds pytest-xdist>=3.6.0 to dev optional dependencies.
Design spec and implementation plan
docs/superpowers/specs/..., docs/superpowers/plans/...
Adds design document (DB isolation strategy, lifespan seam, auth fixtures, SessionLocal bypass handling, xdist rollout, risk register) and implementation plan (Tasks 1–7 with file maps, code targets, verification steps).

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • wrzonance/WrzDJ#372: Adds health_monitor_loop to the background tasks started in server/app/main.py's lifespan—directly overlaps with this PR's refactoring of that same lifespan into the run_background_tasks flag and no_background_lifespan helper.
  • wrzonance/WrzDJ#363: Introduces the async LLM call log cleanup task wired into the same lifespan context manager that this PR refactors, and the test_llm_call_log_retention.py changes here directly modify tests that cover that cleanup behavior.
  • wrzonance/WrzDJ#379: The refactored server/tests/conftest.py test harness (centralized SessionLocal patching, session-scoped SQLite, and new auth_headers fixture shape) directly impacts endpoint and gateway tests that rely on stable database isolation and authentication header fixtures.

Poem

🐇 Hop hop, the tests run four at a time,
No logins, no bcrypt—just tokens sublime!
A factory spun create_app with care,
Savepoints rolled back what the tests left there.
The rabbit checked docs, specs, and the plan—
And watched the CI shrink to a 3-minute span! 🕐

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 43.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Improve backend CI test efficiency' directly and clearly summarizes the main objective of the PR, which is to refactor backend CI testing infrastructure for efficiency.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/backend-ci-refactor

Comment @coderabbitai help to get the list of available commands and usage tips.

@thewrz thewrz marked this pull request as ready for review June 14, 2026 21:00

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@server/app/main.py`:
- Around line 111-113: The code currently includes exception details in the
JSONResponse when not in production (the condition `if not
settings.is_production: content["debug"] = str(exc)`), which exposes internal
error information to API clients. Remove the entire conditional block that adds
the debug information to the response content. Instead, ensure that error
details are only logged server-side and a generic error message is always
returned to clients, regardless of environment. This prevents sensitive internal
error information from being exposed through public API endpoints.
- Around line 185-187: The `resolved_uploads_dir` is a method but is being
passed to `Path()` without being called. Change `settings.resolved_uploads_dir`
to `settings.resolved_uploads_dir()` (add parentheses to invoke the method and
get the actual path string) in the line where `uploads_dir` is assigned using
`Path()`. This will ensure that the string path is passed to `Path` instead of
the bound method object.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 5f4c429c-4bd4-4ad3-bd68-2ea6a563f677

📥 Commits

Reviewing files that changed from the base of the PR and between b2f553c and 516e06f.

⛔ Files ignored due to path filters (1)
  • server/uv.lock is excluded by !**/*.lock
📒 Files selected for processing (9)
  • .github/workflows/ci.yml
  • docs/superpowers/plans/2026-06-14-backend-ci-efficiency.md
  • docs/superpowers/specs/2026-06-14-backend-ci-efficiency-design.md
  • server/app/main.py
  • server/pyproject.toml
  • server/tests/conftest.py
  • server/tests/test_api.py
  • server/tests/test_llm_call_log_retention.py
  • server/tests/test_test_harness.py

Comment thread server/app/main.py Outdated
Comment thread server/app/main.py
Co-Authored-By: Codex <noreply@openai.com>
@thewrz thewrz merged commit 43d1552 into main Jun 14, 2026
11 checks passed
@thewrz thewrz deleted the chore/backend-ci-refactor branch June 14, 2026 21:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant