Skip to content

test(django): Remove @pytest.mark.forked dependency from Django integration tests #6411

@sl0thentr0py

Description

@sl0thentr0py

Background

The Django integration test suite uses @pytest.mark.forked (via pytest-forked) on 52 tests across 5 files to isolate global state. This dates back to #522 ("Less boxed testing") and was a pragmatic substitute for proper teardown.

Problem

pytest-forked is actively harmful in some scenarios:

  • Python 3.12 + asyncio + GitHub Actions: Forking a multi-threaded process and then running an asyncio loop in the child causes silent hangs (the loop inherits dead threads). This consumed the full 30-minute CI budget on the Django ASGI tests until test(django): Remove forking in ASGI tests #6410 dropped forked from those 10 tests.
  • Slow: Fork-per-test multiplies suite runtime.
  • Hides real isolation bugs: Tests pass under fork but would fail under proper sequential execution, masking integration setup that isn't idempotent.

Goal

Remove @pytest.mark.forked from every test under tests/integrations/django/ and replace it with explicit isolation.

Proposed approach

  1. Extend (or autouse-wrap) the sentry_init fixture so the non-forked path also resets:
    • sentry_sdk.integrations._processed_integrations
    • sentry_sdk.integrations._installed_integrations
  2. Add a reset_django_state fixture that snapshots and restores:
    • settings.MIDDLEWARE
    • Django signal receivers (request_started, request_finished, etc.)
    • Anything else DjangoIntegration.setup_once connects
  3. Audit DjangoIntegration.setup_once (and submodule patches under sentry_sdk/integrations/django/) for non-idempotent module-level patching.
  4. Migrate test files one at a time: drop the marker, run, fix the resulting leaks, repeat.

Current state

Files still using @pytest.mark.forked under tests/integrations/django/ (count via grep -rc):

  • test_basic.py (13)
  • test_cache_module.py (14)
  • test_db_query_data.py (10)
  • test_db_transactions.py (12)
  • test_data_scrubbing.py (3)

The ASGI subset (tests/integrations/django/asgi/test_asgi.py) was removed in #6410.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions