Skip to content

feat: mongodb instrumentation#127

Merged
sohankshirsagar merged 5 commits into
mainfrom
sohan/mongodb-instrumentation
Mar 4, 2026
Merged

feat: mongodb instrumentation#127
sohankshirsagar merged 5 commits into
mainfrom
sohan/mongodb-instrumentation

Conversation

@sohankshirsagar
Copy link
Copy Markdown
Contributor

@sohankshirsagar sohankshirsagar commented Mar 4, 2026

  • run bug finder
  • test mongoose

Summary

Adds record/replay instrumentation for the MongoDB Node.js driver (v5.x–7.x). This enables Tusk Drift to intercept and replay all MongoDB operations — including CRUD, cursor-based queries, aggregations, bulk writes, sessions, and index management — without requiring a live database during replay.

Changes

  • Core instrumentation (src/instrumentation/libraries/mongodb/Instrumentation.ts): Wraps MongoClient, Collection, Db, and cursor prototypes to intercept all database operations for record/replay. Handles both promise-returning methods (findOne, insertOne, updateMany, etc.) and cursor-returning methods (find, aggregate, listIndexes).
  • Connection handler (handlers/ConnectionHandler.ts): Manages MongoClient lifecycle (connect/close/db) — records real connections in record mode, skips TCP in replay mode.
  • BSON conversion utilities (utils/bsonConversion.ts): Serializes/deserializes BSON types (ObjectId, UUID, Binary, Decimal128, Long, Double, Int32, Timestamp, Code, DBRef, MinKey, MaxKey, BSONRegExp) to JSON-safe representations for span storage and reconstruction during replay.
  • Fake cursors & topology (mocks/FakeCursor.ts, mocks/FakeTopology.ts): Replay-mode mocks that implement the MongoDB cursor interface (toArray, next, forEach, async iterator, builder-pattern chaining) and topology, with lazy mock data loading.
  • Types (types.ts): TypeScript interfaces for MongoDB instrumentation config, input/output values, and module exports.
  • E2E tests: Full CJS and ESM test suites with Docker Compose setups (app + MongoDB container), covering insertOne/Many, find/findOne, update, delete, aggregate, cursor iteration, bulkWrite, sessions, index operations, and more.
  • CI: Added mongodb to the e2e test matrix in .github/workflows/e2e.yml.
  • README: Added MongoDB (v5.x–7.x) to the supported packages list.

Note

High Risk
Adds a large new instrumentation layer that monkey-patches the mongodb driver (including cursors/sessions/bulk ops) and introduces complex BSON serialization/replay behavior that could affect runtime DB interactions.

Overview
Adds first-class MongoDB (mongodb@5.x–7.x) record/replay instrumentation to the SDK and wires it into TuskDrift initialization.

The new MongodbInstrumentation wraps MongoClient lifecycle, Collection/Db CRUD and cursor-returning methods, sessions/transactions, and bulk operations, including BSON value sanitization/reconstruction and replay-only fake cursors/topology to run without a live DB.

Updates CI and docs by adding mongodb to the E2E matrix, introducing full CJS/ESM Docker-based MongoDB E2E suites, and adjusting Date instrumentation to preserve Date constructor naming for Mongoose compatibility.

Written by Cursor Bugbot for commit 68b906b. This will update automatically on new commits. Configure here.

Copy link
Copy Markdown
Contributor

@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.

10 issues found across 32 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="src/instrumentation/libraries/mongodb/handlers/ConnectionHandler.ts">

<violation number="1" location="src/instrumentation/libraries/mongodb/handlers/ConnectionHandler.ts:146">
P2: Guard the `connect` invocation against synchronous throws so span error handling runs for both sync and async failures.</violation>

<violation number="2" location="src/instrumentation/libraries/mongodb/handlers/ConnectionHandler.ts:212">
P2: Wrap the `close` invocation so synchronous exceptions are converted to promise rejections and handled by the existing error path.</violation>
</file>

<file name="src/instrumentation/libraries/mongodb/e2e-tests/cjs-mongodb/src/index.ts">

<violation number="1" location="src/instrumentation/libraries/mongodb/e2e-tests/cjs-mongodb/src/index.ts:466">
P1: Fatal error paths exit with status code 0, which can mask real test/app failures as successful runs.</violation>
</file>

<file name="src/instrumentation/libraries/mongodb/e2e-tests/esm-mongodb/src/index.ts">

<violation number="1" location="src/instrumentation/libraries/mongodb/e2e-tests/esm-mongodb/src/index.ts:466">
P1: Unhandled fatal errors exit with code 0, which can hide real test failures in CI. Exit non-zero for `uncaughtException`/`unhandledRejection` paths.</violation>
</file>

<file name="src/instrumentation/libraries/mongodb/e2e-tests/esm-mongodb/Dockerfile">

<violation number="1" location="src/instrumentation/libraries/mongodb/e2e-tests/esm-mongodb/Dockerfile:14">
P1: Avoid executing installer scripts via `curl | sh` without integrity verification. Download the script, verify checksum/signature, then execute it.</violation>
</file>

<file name="src/instrumentation/libraries/mongodb/Instrumentation.ts">

<violation number="1" location="src/instrumentation/libraries/mongodb/Instrumentation.ts:617">
P1: Bug: Async iterator span is never finalized. `cursorState.recorded = true` is set before the iteration loop, but `finalizeCursorSpan()` and `handleCursorError()` both check `if (cursorState.recorded) return;` as their first guard. Since `recorded` is already `true`, neither function ever actually ends the span or records the output documents. This causes leaked spans and missing replay data when cursors are consumed via `for await...of`.

Remove the early `cursorState.recorded = true` — `finalizeCursorSpan()` already sets it when it runs, which still prevents other terminal methods from double-finalizing.</violation>
</file>

<file name="src/instrumentation/libraries/mongodb/mocks/FakeCursor.ts">

<violation number="1" location="src/instrumentation/libraries/mongodb/mocks/FakeCursor.ts:49">
P1: `toArray()` should consume from the current cursor position and exhaust the cursor; returning all documents without updating `index` breaks cursor semantics during replay.</violation>

<violation number="2" location="src/instrumentation/libraries/mongodb/mocks/FakeCursor.ts:69">
P1: `forEach()` should iterate from the current cursor position and advance `index`; otherwise consumed documents are reprocessed and cursor state becomes inconsistent.</violation>

<violation number="3" location="src/instrumentation/libraries/mongodb/mocks/FakeCursor.ts:74">
P1: Async iterator should yield from current `index` and advance it; current implementation re-yields already-consumed documents.</violation>
</file>

<file name="src/instrumentation/libraries/mongodb/utils/bsonConversion.ts">

<violation number="1" location="src/instrumentation/libraries/mongodb/utils/bsonConversion.ts:499">
P1: Data corruption during replay: `wrapDirectOutput` passes plain objects through unwrapped, but `unwrapDirectOutput` treats *any* object with a `__directResult` property as a wrapped value. If a MongoDB document naturally has a field named `__directResult`, the unwrap step will discard the rest of the document and return only that field's value.

The safest fix is to always wrap (removing the object pass-through), which makes `wrap`/`unwrap` symmetric and eliminates the ambiguity.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread src/instrumentation/libraries/mongodb/Instrumentation.ts
Comment thread src/instrumentation/libraries/mongodb/mocks/FakeCursor.ts
Comment thread src/instrumentation/libraries/mongodb/mocks/FakeCursor.ts
Comment thread src/instrumentation/libraries/mongodb/mocks/FakeCursor.ts
Comment thread src/instrumentation/libraries/mongodb/utils/bsonConversion.ts
Comment thread src/instrumentation/libraries/mongodb/handlers/ConnectionHandler.ts
Comment thread src/instrumentation/libraries/mongodb/handlers/ConnectionHandler.ts
@tusk-dev
Copy link
Copy Markdown
Contributor

tusk-dev Bot commented Mar 4, 2026

⏩ Tusk is paused for this PR (09a1eec) View output ↗

Tip

New to Tusk? Learn more here.


View check history

Commit Status Output Created (UTC)
51960ac ✅ Generated 118 tests - 118 passed Tests Mar 4, 2026 6:48AM
09a1eec ⏩ Tusk is paused for this PR Output Mar 4, 2026 9:13AM

@sohankshirsagar sohankshirsagar added the Tusk - Pause For Current PR Pause Tusk for future commits in the current PR label Mar 4, 2026
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Comment thread src/instrumentation/libraries/mongodb/Instrumentation.ts
Comment thread src/instrumentation/libraries/mongodb/Instrumentation.ts
@sohankshirsagar sohankshirsagar merged commit 4772c2d into main Mar 4, 2026
17 checks passed
@sohankshirsagar sohankshirsagar deleted the sohan/mongodb-instrumentation branch March 4, 2026 21:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Tusk - Pause For Current PR Pause Tusk for future commits in the current PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants