Uploaded image for project: 'Core Server'
  1. Core Server
  2. SERVER-31134

Adapt change stream tests to relax assertions on change visibility

    • Fully Compatible
    • Repl 2017-10-02, Repl 2017-10-23

      Many of the tests in the change stream suite do something like this:

      jstests/change_streams/change_streams.js
          cursor = startWatchingChanges([{$changeStream: {}}], db.t1);
          assert.writeOK(db.t1.insert({_id: 1, a: 2}));
          expected = {
              _id: {
                  documentKey: {_id: 1},
                  uuid: t1Uuid,
              },
              documentKey: {_id: 1},
              fullDocument: {_id: 1, a: 2},
              ns: {db: "test", coll: "t1"},
              operationType: "insert",
          };
          assertNextBatchMatches({cursor: cursor, expectedBatch: [expected]});
      

      To add some commentary, the problematic pattern is:

      1. Open a change stream
      2. Do some write
      3. Assert that write is visible in the next getMore for that change stream.

      These tests are okay to run against a replica set or an unsharded collection through mongos, but do not work against a sharded collection. A change stream running against a sharded collection cannot always see changes in the next batch, because it needs to return changes in order of their cluster time, and so can't immediately return results from one shard without getting a guarantee from another shard that it won't return things ahead of that one.

      In case that was confusing - here's an example:
      Suppose there are two shards, and we just inserted a document to shard 1. mongos's change stream cursor will see that change, and see that it happened at time T1. It wants to return that change, but it is paranoid that the cursor on shard 2 might come back with a change at time T0 (< T1) that would have to come first. So it waits to hear back from shard 2. Shard 2 might not respond for a while, particularly in a test when there aren't any writes happening. We do know that shard 2 will eventually respond with an updated timestamp due to the periodic noop write that is going on in the background.

      So, in order to re-use the tests in the jstests/change_streams directory, we need to convert assertions like the one above into a style more like:

      1. Open a change stream cursor
      2. Do a write
      3. assert.soon that getMores on that cursor will eventually return that change.

      When we eventually enable a passthrough that runs with sharded collections, we will need to be sure the periodic noop write is happening (it's disabled by default in ShardingTest, I'm not sure about through resmoke.py) - and should consider making the frequency configurable, rather than the default 10 seconds.

            Assignee:
            judah.schvimer@mongodb.com Judah Schvimer
            Reporter:
            charlie.swanson@mongodb.com Charlie Swanson
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated:
              Resolved: