Introduce white-box integration tests for cluster-wide change stream v2 shard targeting

XMLWordPrintableJSON

    • Type: Task
    • Resolution: Fixed
    • Priority: Major - P3
    • 9.0.0-rc0
    • Affects Version/s: None
    • Component/s: None
    • Query Execution
    • Fully Compatible
    • QE 2026-03-30, QE 2026-03-16, QE 2026-04-13
    • None
    • None
    • None
    • None
    • None
    • None
    • None

      Summary

      SERVER-111381 implemented AllDatabasesChangeStreamShardTargeterImpl with C++ unit tests and JS smoke tests, but lacks white-box integration tests that verify observable shard-targeting behavior: which shards have open cursors after each lifecycle event, and that placement history is consulted at the right times.

      Approach

      Two jstest files using two observability mechanisms:

      1. *$currentOp with 
        Unknown macro: {Unknown macro}

        * — inspects which shards have open change stream cursors. Cursors identified via unique comment per test case.

      1. Log offset snapshots — before each operation, snapshot checkLog.getGlobalLog(mongos).length. After the operation, search only the new log entries for expected LOGV2 IDs and attributes. This avoids false matches from prior test steps.

      Shared fixture: A single ShardingTest created in before()beforeEach()/afterEach() only clean up databases/collections. Verbose query logging on all nodes via logComponentVerbosity: {query: {verbosity: 3{}}}.

      Test Files

      • jstests/sharding/query/change_streams/change_stream_all_databases_v2_strict_whitebox.js — 3 shards
      • jstests/sharding/query/change_streams/change_stream_all_databases_v2_ignore_removed_shards_whitebox.js — 4 shards (needs spare after removals)

      File 1: Strict Mode (change_stream_all_databases_v2_strict_whitebox.js)

      Fixture: 3 shards. Tags: featureFlagChangeStreamPreciseShardTargetingrequires_shardinguses_change_streamsassumes_balancer_off.


      Test 1.1: Initialize with data on multiple shards

      Setup: Create DB (primary shard0). Shard collection, split chunks across shard0 and shard1. Insert documents on both.

      Steps:

      1. Snapshot log offset on mongos.
      2. Open cluster-wide v2 change stream.
      3. Assert cursors: shard0 (has data), shard1 (has data). No cursor on shard2 (no data). Config cursor open.
      4. Assert log: ID 11138104 on mongos with shards listing shard0 and shard1.
      5. Insert a document, verify event received.

      Test 1.2: Initialize on empty cluster — config server cursor only

      Setup: No user databases.

      Steps:

      1. Snapshot log offset.
      2. Open cluster-wide v2 change stream.
      3. Assert cursors: No data shard cursors. Config cursor open.
      4. Assert log: ID 11138104 with empty shards.
      5. Snapshot log offset again.
      6. Create database + collection (triggers DatabaseCreatedControlEvent).
      7. Assert cursors: Data shard cursor now open on the DB's primary shard. Config cursor still open.
      8. Assert log: ID 11138117 ("Handling placement refresh") with updated shard set.
      9. Insert document, verify event received.

      Test 1.3: DatabaseCreated on a different shard opens cursor on that shard

      Setup: DB1 with primary on shard0, unsharded collection with data.

      Steps:

      1. Open change stream. Assert cursors on shard0 + config.
      2. Snapshot log offset.
      3. Create DB2 with primaryShard: shard1. Create collection in DB2.
      4. Assert cursors: Cursor now also open on shard1. shard2 still no cursor. Config still open.
      5. Assert log: ID 11138117 with shards including shard1.
      6. Insert into DB2, verify event received.

      Test 1.4: MoveChunk triggers placement refresh

      Setup: Collection sharded across shard0 and shard1 (data on both).

      Steps:

      1. Open change stream. Assert cursors on shard0, shard1 + config.
      2. Snapshot log offset.
      3. moveChunk all chunks from shard0 to shard2.
      4. Assert cursors: Cursor opened on shard2. Cursor on shard0 closed (no data). shard1 unchanged. Config still open.
      5. Assert log: ID 11138117 with updated shard set.
      6. Insert targeting shard2, verify event.

      Test 1.5: MovePrimary triggers placement refresh

      Setup: Unsharded collection on shard0 (shard0 is DB primary).

      Steps:

      1. Open change stream. Assert cursor on shard0 + config.
      2. Snapshot log offset.
      3. movePrimary to shard1.
      4. Assert cursors: Cursor on shard1 opened. Cursor on shard0 closed. Config still open.
      5. Assert log: ID 11138117.
      6. Insert, verify event.

      Test 1.6: NamespacePlacementChanged via reshardCollection triggers placement refresh

      Setup: Collection sharded across shard0 and shard1 (key {}{_id: 1}{}).

      Steps:

      1. Open change stream. Assert cursors on shard0, shard1 + config.
      2. Snapshot log offset.
      3. reshardCollection with new key {{{} {a: 1}
        {}}}, distribute chunks to shard1 and shard2.
      1. Assert cursors: Cursor opened on shard2. Cursor on shard0 closed. shard1 unchanged. Config still open.
      2. Assert log: ID 11138117 with updated shard set showing shard1, shard2.
      3. Insert, verify event with new document key shape.

      Test 1.7: Multiple databases on different shards

      Setup: DB1 (primary shard0), DB2 (primary shard1), DB3 (primary shard2). Each with an unsharded collection.

      Steps:

      1. Open change stream.
      2. Assert cursors: shard0, shard1, shard2 all have cursors. Config cursor open.
      3. Insert one document into each DB, verify all 3 events received.

            Assignee:
            Lyublena Antova
            Reporter:
            Denis Grebennicov
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: