summaryrefslogtreecommitdiff
path: root/jstests/sharding
diff options
context:
space:
mode:
authorDavid Storch <david.storch@10gen.com>2018-06-15 16:19:56 -0400
committerDavid Storch <david.storch@10gen.com>2018-06-22 13:42:27 -0400
commit545263a62041c72e67927d59e9f7fa04f09c99b9 (patch)
treeb392f0ca48175bd7c40d4e95219f5c681895cf89 /jstests/sharding
parent8381c31204d5ed2dc9cd9bace213f9df923af6cb (diff)
downloadmongo-545263a62041c72e67927d59e9f7fa04f09c99b9.tar.gz
SERVER-35084 Modify change_stream_enforce_max_time_ms_on_mongos.js to ensure test schedules expected getMores.
Diffstat (limited to 'jstests/sharding')
-rw-r--r--jstests/sharding/change_stream_enforce_max_time_ms_on_mongos.js74
1 files changed, 62 insertions, 12 deletions
diff --git a/jstests/sharding/change_stream_enforce_max_time_ms_on_mongos.js b/jstests/sharding/change_stream_enforce_max_time_ms_on_mongos.js
index abdf387faa3..2295086a18c 100644
--- a/jstests/sharding/change_stream_enforce_max_time_ms_on_mongos.js
+++ b/jstests/sharding/change_stream_enforce_max_time_ms_on_mongos.js
@@ -79,7 +79,31 @@
assert.eq(getMoreTimeouts[0]._id, timeout);
}
+ // Kills the cursor with the given cursor id (if provided). Then opens a new change stream
+ // against 'mongosColl' and returns the new change stream's cursor id.
+ //
+ // We re-open the change stream in between each test case with a batchSize if 0. This is done to
+ // ensure that mongos delivers getMores to the shards for the first getMore against the mongos
+ // change stream cursor (thus avoiding issues such as SERVER-35084).
+ function reopenChangeStream(existingCursorId) {
+ if (existingCursorId) {
+ assert.commandWorked(mongosDB.runCommand(
+ {killCursors: mongosColl.getName(), cursors: [existingCursorId]}));
+ }
+
+ const csCmdRes = assert.commandWorked(mongosDB.runCommand({
+ aggregate: mongosColl.getName(),
+ pipeline: [{$changeStream: {}}],
+ comment: testComment,
+ cursor: {batchSize: 0}
+ }));
+ assert.eq(csCmdRes.cursor.firstBatch.length, 0);
+ assert.neq(csCmdRes.cursor.id, 0);
+ return csCmdRes.cursor.id;
+ }
+
// Timeout values used in the subsequent getMore tests.
+ const quarterSec = 250;
const halfSec = 500;
const oneSec = 2 * halfSec;
const fiveSecs = 5 * oneSec;
@@ -88,28 +112,28 @@
const testComment = "change stream sharded maxTimeMS test";
// Open a $changeStream on the empty, inactive collection.
- const csCmdRes = assert.commandWorked(mongosDB.runCommand({
- aggregate: mongosColl.getName(),
- pipeline: [{$changeStream: {}}],
- comment: testComment,
- cursor: {}
- }));
- assert.eq(csCmdRes.cursor.firstBatch.length, 0);
- assert.neq(csCmdRes.cursor.id, 0);
+ let csCursorId = reopenChangeStream();
// Confirm that getMores without an explicit maxTimeMS default to one second on the shards.
assert.commandWorked(
- mongosDB.runCommand({getMore: csCmdRes.cursor.id, collection: mongosColl.getName()}));
+ mongosDB.runCommand({getMore: csCursorId, collection: mongosColl.getName()}));
for (let shardDB of[shard0DB, shard1DB]) {
+ // The mongos is guaranteed to have already delivered getMores to each of the shards.
+ // However, the mongos await time can expire prior to the await time on the shards.
+ // Therefore, the getMore on mongos succeeding doesn't guarantee that the getMores on the
+ // shards have already been profiled. We use an assert.soon() here to wait for the maxTimeMS
+ // on the shards to expire, at which point the getMores will appear in the profile
+ // collection.
assert.soon(() => profilerHasAtLeastOneMatchingGetMore(
shardDB, mongosColl.getFullName(), testComment, oneSec));
}
// Verify that with no activity on the shards, a $changeStream with maxTimeMS waits for the full
// duration on mongoS. Allow some leniency since the server-side wait may wake spuriously.
+ csCursorId = reopenChangeStream(csCursorId);
let startTime = (new Date()).getTime();
assert.commandWorked(mongosDB.runCommand(
- {getMore: csCmdRes.cursor.id, collection: mongosColl.getName(), maxTimeMS: fiveSecs}));
+ {getMore: csCursorId, collection: mongosColl.getName(), maxTimeMS: fiveSecs}));
assert.gte((new Date()).getTime() - startTime, fiveSecs - halfSec);
// Confirm that each getMore dispatched to the shards during this period had a maxTimeMS of 1s.
@@ -118,22 +142,48 @@
}
// Issue a getMore with a sub-second maxTimeMS. This should propagate to the shards as-is.
+ csCursorId = reopenChangeStream(csCursorId);
assert.commandWorked(mongosDB.runCommand(
- {getMore: csCmdRes.cursor.id, collection: mongosColl.getName(), maxTimeMS: halfSec}));
+ {getMore: csCursorId, collection: mongosColl.getName(), maxTimeMS: halfSec}));
for (let shardDB of[shard0DB, shard1DB]) {
+ // The mongos is guaranteed to have already delivered getMores to each of the shards.
+ // However, the mongos await time can expire prior to the await time on the shards.
+ // Therefore, the getMore on mongos succeeding doesn't guarantee that the getMores on the
+ // shards have already been profiled. We use an assert.soon() here to wait for the maxTimeMS
+ // on the shards to expire, at which point the getMores will appear in the profile
+ // collection.
assert.soon(() => profilerHasAtLeastOneMatchingGetMore(
shardDB, mongosColl.getFullName(), testComment, halfSec));
}
// Write a document to shard0, and confirm that - despite the fact that shard1 is still idle - a
// getMore with a high maxTimeMS returns the document before this timeout expires.
+ csCursorId = reopenChangeStream(csCursorId);
assert.writeOK(mongosColl.insert({_id: -1}));
startTime = (new Date()).getTime();
const csResult = assert.commandWorked(mongosDB.runCommand(
- {getMore: csCmdRes.cursor.id, collection: mongosColl.getName(), maxTimeMS: thirtyMins}));
+ {getMore: csCursorId, collection: mongosColl.getName(), maxTimeMS: thirtyMins}));
assert.lte((new Date()).getTime() - startTime, fiveMins);
assert.docEq(csResult.cursor.nextBatch[0].fullDocument, {_id: -1});
+ // Open a change stream with the default maxTimeMS. Then verify that if the client starts
+ // issuing getMores with a subsecond maxTimeMS, that mongos eventually schedules getMores on the
+ // shards with this subsecond maxTimeMS value.
+ csCursorId = reopenChangeStream(csCursorId);
+ assert.commandWorked(
+ mongosDB.runCommand({getMore: csCursorId, collection: mongosColl.getName()}));
+ assert.soon(function() {
+ // Run a getMore with a 250ms maxTimeMS against mongos.
+ assert.commandWorked(mongosDB.runCommand(
+ {getMore: csCursorId, collection: mongosColl.getName(), maxTimeMS: quarterSec}));
+ // Check whether all shards now have a getMore with 250ms maxTimeMS recorded in their
+ // profile collections.
+ return [shard0DB, shard1DB].every(function(shardDB) {
+ return profilerHasAtLeastOneMatchingGetMore(
+ shardDB, mongosColl.getFullName(), testComment, quarterSec);
+ });
+ });
+
st.stop();
})();