Skip to content

Conversation

@jy-tan
Copy link
Contributor

@jy-tan jy-tan commented Jan 28, 2026

Summary

Fixes three critical issues causing stack test failures in REPLAY mode, enabling all previously commented-out tests to pass. The fixes address cursor.description handling in psycopg2, dynamic session key comparisons in Django Redis, and complete async psycopg3 instrumentation including pipeline mode support.

Changes

Issue 1: django-postgres - cursor.description is None in REPLAY mode

  • Modified psycopg2 InstrumentedConnection.cursor() to return MockCursor directly in REPLAY mode
  • Added query attribute to MockCursor (required by Django's transaction handling)
  • Added _is_dict_cursor flag to handle RealDictCursor/DictCursor factories correctly
  • Re-enabled all previously commented-out django-postgres tests

Issue 2: django-redis - Dynamic session_key causing comparison failures

  • Added comparison.ignore_fields: ["session_key", "cleared_session_key"] to config
  • Chose config-based approach over modifying application code to keep test apps realistic
  • Re-enabled all previously commented-out session tests

Issue 3: fastapi-postgres - Incomplete async psycopg3 instrumentation

  • Fixed AsyncConnectionPool import (from psycopg_pool, not psycopg)
  • Added psycopg-pool to requirements.txt
  • Implemented comprehensive async instrumentation:
    • _patch_async_connection() - patches AsyncConnection.connect()
    • _patch_async_connection_pool() - injects cursor_factory into pool's kwargs parameter
    • InstrumentedAsyncCursor class with full tracing support
    • _setup_async_lazy_capture() for async cursor fetch methods in RECORD mode
    • _patch_async_pipeline() and _setup_async_pipeline_fetch_interception() for pipeline mode
  • Added MockAsyncConnection and MockAsyncCursor to mocks.py for REPLAY mode
  • Made _mock_execute_with_data() async-aware with is_async parameter
  • Re-enabled all previously commented-out fastapi-postgres tests

Technical Notes

  • Async pipeline mode required special handling: cursor.execute() returns immediately without results in pipeline mode, so we intercept fetch methods to capture data when the application actually fetches it (inside the pipeline context), rather than waiting for pipeline exit.
  • MockCursor in REPLAY mode was chosen because psycopg2's cursor.description is a read-only C-level property that cannot be set on real cursors.

TODO next PR: create a stack test that mimics real-world examples, like FastAPI + SQLAlchemy/Alembic

Copy link

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

No issues found across 9 files

@jy-tan jy-tan merged commit 5224b86 into main Jan 28, 2026
22 checks passed
@jy-tan jy-tan deleted the instrumentation-stack-test-fixes branch January 28, 2026 07:59
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.

3 participants