Skip to content

[P0][Test Isolation] Admin permission test leaks real DuckDB PostgreSQL attach and blocks next clean_tables TRUNCATE #22

Description

@fxbin

Parent: #14

Reproduced CI evidence

Diagnostic PR #18 / Actions job 94998930748 ran the PostgreSQL suite with -vv and faulthandler_timeout=30.

Observed sequence:

  1. tests/test_admin_api_permissions.py::test_management_apis_require_admin_role passed.
  2. The next test, test_webnovel_read_apis_require_login_not_admin, never reached its body.
  3. After 30s, faulthandler showed pytest blocked in async fixture setup (pytest_asyncio async-generator fixture wrapper / event loop select).
  4. The suite remained blocked until the 180s diagnostic shell timeout killed it (exit 124).
  5. PostgreSQL logged an open transaction when the process was killed.

Root-cause chain

admin_api_client is a permission-test fixture backed by an in-memory SQLite DB, but the first test includes /settings/duckdb/status in its endpoint list.

For the admin request that endpoint calls the real module-level duckdb_service.get_analytics().status(). The singleton opens an in-memory DuckDB connection and ATTACHes the configured CI PostgreSQL database read-only. The permission fixture does not close/reset that global analytics singleton at teardown.

Before every test, the global autouse clean_tables fixture executes TRUNCATE TABLE ... CASCADE across the PostgreSQL schema. After the first permission test has opened the real DuckDB/Postgres attach, setup for the second test can wait on that database resource/transaction instead of reaching the test body.

The repository already has the correct isolation pattern in test_settings_notifications_api.py::test_duckdb_status_reports_database_diagnostics, which monkeypatches duckdb_service.get_analytics with FakeAnalytics.

Objective

Make the admin authorization test hermetic: it must validate authorization status codes without opening the real DuckDB analytical layer or PostgreSQL attachment.

Minimal fix

  • monkeypatch app.services.duckdb_service.get_analytics in admin_api_client to a deterministic fake analytics status;
  • do not weaken the 401/403/200 assertions;
  • do not change production DuckDB behavior;
  • keep the dedicated DuckDB status behavior test as the place that validates endpoint payload/diagnostics.

Acceptance gates

  • the two first tests in test_admin_api_permissions.py run sequentially without fixture hang against PostgreSQL CI;
  • test_management_apis_require_admin_role still verifies /settings/duckdb/status is admin-only;
  • permission tests do not initialize the module-level real DuckDB analytics singleton;
  • diagnostic suite progresses beyond the second test;
  • no production code changes are required unless new evidence proves otherwise;
  • final PR contains durable test code only, no process artifacts.

Verifier focus

Verify this is isolation rather than hiding behavior: the dedicated DuckDB status test must continue to cover status payload behavior separately.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions