diff options
Diffstat (limited to 'jstests/sharding/max_time_ms_sharded.js')
-rw-r--r-- | jstests/sharding/max_time_ms_sharded.js | 463 |
1 files changed, 231 insertions, 232 deletions
diff --git a/jstests/sharding/max_time_ms_sharded.js b/jstests/sharding/max_time_ms_sharded.js index d46ba9af74a..16c56658a5d 100644 --- a/jstests/sharding/max_time_ms_sharded.js +++ b/jstests/sharding/max_time_ms_sharded.js @@ -5,267 +5,266 @@ // Note that mongos does not time out commands or query ops (which remains responsibility of mongod, // pending development of an interrupt framework for mongos). (function() { - 'use strict'; +'use strict'; - var st = new ShardingTest({shards: 2}); +var st = new ShardingTest({shards: 2}); - var mongos = st.s0; - var shards = [st.shard0, st.shard1]; - var coll = mongos.getCollection("foo.bar"); - var admin = mongos.getDB("admin"); - var cursor; - var res; +var mongos = st.s0; +var shards = [st.shard0, st.shard1]; +var coll = mongos.getCollection("foo.bar"); +var admin = mongos.getDB("admin"); +var cursor; +var res; - // Helper function to configure "maxTimeAlwaysTimeOut" fail point on shards, which forces mongod - // to throw if it receives an operation with a max time. See fail point declaration for complete - // description. - var configureMaxTimeAlwaysTimeOut = function(mode) { - assert.commandWorked(shards[0].getDB("admin").runCommand( - {configureFailPoint: "maxTimeAlwaysTimeOut", mode: mode})); - assert.commandWorked(shards[1].getDB("admin").runCommand( - {configureFailPoint: "maxTimeAlwaysTimeOut", mode: mode})); - }; +// Helper function to configure "maxTimeAlwaysTimeOut" fail point on shards, which forces mongod +// to throw if it receives an operation with a max time. See fail point declaration for complete +// description. +var configureMaxTimeAlwaysTimeOut = function(mode) { + assert.commandWorked(shards[0].getDB("admin").runCommand( + {configureFailPoint: "maxTimeAlwaysTimeOut", mode: mode})); + assert.commandWorked(shards[1].getDB("admin").runCommand( + {configureFailPoint: "maxTimeAlwaysTimeOut", mode: mode})); +}; - // Helper function to configure "maxTimeAlwaysTimeOut" fail point on shards, which prohibits - // mongod from enforcing time limits. See fail point declaration for complete description. - var configureMaxTimeNeverTimeOut = function(mode) { - assert.commandWorked(shards[0].getDB("admin").runCommand( - {configureFailPoint: "maxTimeNeverTimeOut", mode: mode})); - assert.commandWorked(shards[1].getDB("admin").runCommand( - {configureFailPoint: "maxTimeNeverTimeOut", mode: mode})); - }; +// Helper function to configure "maxTimeAlwaysTimeOut" fail point on shards, which prohibits +// mongod from enforcing time limits. See fail point declaration for complete description. +var configureMaxTimeNeverTimeOut = function(mode) { + assert.commandWorked(shards[0].getDB("admin").runCommand( + {configureFailPoint: "maxTimeNeverTimeOut", mode: mode})); + assert.commandWorked(shards[1].getDB("admin").runCommand( + {configureFailPoint: "maxTimeNeverTimeOut", mode: mode})); +}; - // - // Pre-split collection: shard 0 takes {_id: {$lt: 0}}, shard 1 takes {_id: {$gte: 0}}. - // - assert.commandWorked(admin.runCommand({enableSharding: coll.getDB().getName()})); - st.ensurePrimaryShard(coll.getDB().toString(), st.shard0.shardName); - assert.commandWorked(admin.runCommand({shardCollection: coll.getFullName(), key: {_id: 1}})); - assert.commandWorked(admin.runCommand({split: coll.getFullName(), middle: {_id: 0}})); - assert.commandWorked( - admin.runCommand({moveChunk: coll.getFullName(), find: {_id: 0}, to: st.shard1.shardName})); +// +// Pre-split collection: shard 0 takes {_id: {$lt: 0}}, shard 1 takes {_id: {$gte: 0}}. +// +assert.commandWorked(admin.runCommand({enableSharding: coll.getDB().getName()})); +st.ensurePrimaryShard(coll.getDB().toString(), st.shard0.shardName); +assert.commandWorked(admin.runCommand({shardCollection: coll.getFullName(), key: {_id: 1}})); +assert.commandWorked(admin.runCommand({split: coll.getFullName(), middle: {_id: 0}})); +assert.commandWorked( + admin.runCommand({moveChunk: coll.getFullName(), find: {_id: 0}, to: st.shard1.shardName})); - // - // Insert 1000 documents into sharded collection, such that each shard owns 500. - // - const nDocsPerShard = 500; - var bulk = coll.initializeUnorderedBulkOp(); - for (var i = -nDocsPerShard; i < nDocsPerShard; i++) { - bulk.insert({_id: i}); - } - assert.writeOK(bulk.execute()); - assert.eq(nDocsPerShard, shards[0].getCollection(coll.getFullName()).count()); - assert.eq(nDocsPerShard, shards[1].getCollection(coll.getFullName()).count()); +// +// Insert 1000 documents into sharded collection, such that each shard owns 500. +// +const nDocsPerShard = 500; +var bulk = coll.initializeUnorderedBulkOp(); +for (var i = -nDocsPerShard; i < nDocsPerShard; i++) { + bulk.insert({_id: i}); +} +assert.writeOK(bulk.execute()); +assert.eq(nDocsPerShard, shards[0].getCollection(coll.getFullName()).count()); +assert.eq(nDocsPerShard, shards[1].getCollection(coll.getFullName()).count()); - // - // Test that mongos correctly forwards max time to shards for sharded queries. Uses - // maxTimeAlwaysTimeOut to ensure mongod throws if it receives a max time. - // +// +// Test that mongos correctly forwards max time to shards for sharded queries. Uses +// maxTimeAlwaysTimeOut to ensure mongod throws if it receives a max time. +// - // Positive test. - configureMaxTimeAlwaysTimeOut("alwaysOn"); - cursor = coll.find(); - cursor.maxTimeMS(60 * 1000); - assert.throws(function() { - cursor.next(); - }, [], "expected query to fail in mongod due to maxTimeAlwaysTimeOut fail point"); +// Positive test. +configureMaxTimeAlwaysTimeOut("alwaysOn"); +cursor = coll.find(); +cursor.maxTimeMS(60 * 1000); +assert.throws(function() { + cursor.next(); +}, [], "expected query to fail in mongod due to maxTimeAlwaysTimeOut fail point"); - // Negative test. - configureMaxTimeAlwaysTimeOut("off"); - cursor = coll.find(); - cursor.maxTimeMS(60 * 1000); - assert.doesNotThrow(function() { - cursor.next(); - }, [], "expected query to not hit time limit in mongod"); +// Negative test. +configureMaxTimeAlwaysTimeOut("off"); +cursor = coll.find(); +cursor.maxTimeMS(60 * 1000); +assert.doesNotThrow(function() { + cursor.next(); +}, [], "expected query to not hit time limit in mongod"); - // - // Test that mongos correctly times out max time sharded getmore operations. Uses - // maxTimeNeverTimeOut to ensure mongod doesn't enforce a time limit. - // +// +// Test that mongos correctly times out max time sharded getmore operations. Uses +// maxTimeNeverTimeOut to ensure mongod doesn't enforce a time limit. +// - configureMaxTimeNeverTimeOut("alwaysOn"); +configureMaxTimeNeverTimeOut("alwaysOn"); - // Positive test. ~10s operation, 2s limit. The operation takes ~10s because each shard - // processes 250 batches of ~40ms each, and the shards are processing getMores in parallel. - cursor = coll.find({ - $where: function() { - sleep(20); - return true; - } - }); - cursor.batchSize(2); - cursor.maxTimeMS(2 * 1000); - assert.doesNotThrow( - () => cursor.next(), [], "did not expect mongos to time out first batch of query"); - assert.throws(() => cursor.itcount(), [], "expected mongos to abort getmore due to time limit"); +// Positive test. ~10s operation, 2s limit. The operation takes ~10s because each shard +// processes 250 batches of ~40ms each, and the shards are processing getMores in parallel. +cursor = coll.find({ + $where: function() { + sleep(20); + return true; + } +}); +cursor.batchSize(2); +cursor.maxTimeMS(2 * 1000); +assert.doesNotThrow( + () => cursor.next(), [], "did not expect mongos to time out first batch of query"); +assert.throws(() => cursor.itcount(), [], "expected mongos to abort getmore due to time limit"); - // Negative test. ~5s operation, with a high (1-day) limit. - cursor = coll.find({ - $where: function() { - sleep(10); - return true; - } - }); - cursor.batchSize(2); - cursor.maxTimeMS(1000 * 60 * 60 * 24); - assert.doesNotThrow(function() { - cursor.next(); - }, [], "did not expect mongos to time out first batch of query"); - assert.doesNotThrow(function() { - cursor.itcount(); - }, [], "did not expect getmore ops to hit the time limit"); +// Negative test. ~5s operation, with a high (1-day) limit. +cursor = coll.find({ + $where: function() { + sleep(10); + return true; + } +}); +cursor.batchSize(2); +cursor.maxTimeMS(1000 * 60 * 60 * 24); +assert.doesNotThrow(function() { + cursor.next(); +}, [], "did not expect mongos to time out first batch of query"); +assert.doesNotThrow(function() { + cursor.itcount(); +}, [], "did not expect getmore ops to hit the time limit"); - configureMaxTimeNeverTimeOut("off"); +configureMaxTimeNeverTimeOut("off"); - // - // Test that mongos correctly forwards max time to shards for sharded commands. Uses - // maxTimeAlwaysTimeOut to ensure mongod throws if it receives a max time. - // +// +// Test that mongos correctly forwards max time to shards for sharded commands. Uses +// maxTimeAlwaysTimeOut to ensure mongod throws if it receives a max time. +// - // Positive test for "validate". - configureMaxTimeAlwaysTimeOut("alwaysOn"); - assert.commandFailedWithCode( - coll.runCommand("validate", {maxTimeMS: 60 * 1000}), - ErrorCodes.MaxTimeMSExpired, - "expected vailidate to fail with code " + ErrorCodes.MaxTimeMSExpired + - " due to maxTimeAlwaysTimeOut fail point, but instead got: " + tojson(res)); +// Positive test for "validate". +configureMaxTimeAlwaysTimeOut("alwaysOn"); +assert.commandFailedWithCode( + coll.runCommand("validate", {maxTimeMS: 60 * 1000}), + ErrorCodes.MaxTimeMSExpired, + "expected vailidate to fail with code " + ErrorCodes.MaxTimeMSExpired + + " due to maxTimeAlwaysTimeOut fail point, but instead got: " + tojson(res)); - // Negative test for "validate". - configureMaxTimeAlwaysTimeOut("off"); - assert.commandWorked(coll.runCommand("validate", {maxTimeMS: 60 * 1000}), - "expected validate to not hit time limit in mongod"); +// Negative test for "validate". +configureMaxTimeAlwaysTimeOut("off"); +assert.commandWorked(coll.runCommand("validate", {maxTimeMS: 60 * 1000}), + "expected validate to not hit time limit in mongod"); - // Positive test for "count". - configureMaxTimeAlwaysTimeOut("alwaysOn"); - assert.commandFailedWithCode(coll.runCommand("count", {maxTimeMS: 60 * 1000}), - ErrorCodes.MaxTimeMSExpired, - "expected count to fail with code " + ErrorCodes.MaxTimeMSExpired + - " due to maxTimeAlwaysTimeOut fail point, but instead got: " + - tojson(res)); +// Positive test for "count". +configureMaxTimeAlwaysTimeOut("alwaysOn"); +assert.commandFailedWithCode( + coll.runCommand("count", {maxTimeMS: 60 * 1000}), + ErrorCodes.MaxTimeMSExpired, + "expected count to fail with code " + ErrorCodes.MaxTimeMSExpired + + " due to maxTimeAlwaysTimeOut fail point, but instead got: " + tojson(res)); - // Negative test for "count". - configureMaxTimeAlwaysTimeOut("off"); - assert.commandWorked(coll.runCommand("count", {maxTimeMS: 60 * 1000}), - "expected count to not hit time limit in mongod"); +// Negative test for "count". +configureMaxTimeAlwaysTimeOut("off"); +assert.commandWorked(coll.runCommand("count", {maxTimeMS: 60 * 1000}), + "expected count to not hit time limit in mongod"); - // Positive test for "collStats". - configureMaxTimeAlwaysTimeOut("alwaysOn"); - assert.commandFailedWithCode( - coll.runCommand("collStats", {maxTimeMS: 60 * 1000}), - ErrorCodes.MaxTimeMSExpired, - "expected collStats to fail with code " + ErrorCodes.MaxTimeMSExpired + - " due to maxTimeAlwaysTimeOut fail point, but instead got: " + tojson(res)); +// Positive test for "collStats". +configureMaxTimeAlwaysTimeOut("alwaysOn"); +assert.commandFailedWithCode( + coll.runCommand("collStats", {maxTimeMS: 60 * 1000}), + ErrorCodes.MaxTimeMSExpired, + "expected collStats to fail with code " + ErrorCodes.MaxTimeMSExpired + + " due to maxTimeAlwaysTimeOut fail point, but instead got: " + tojson(res)); - // Negative test for "collStats". - configureMaxTimeAlwaysTimeOut("off"); - assert.commandWorked(coll.runCommand("collStats", {maxTimeMS: 60 * 1000}), - "expected collStats to not hit time limit in mongod"); +// Negative test for "collStats". +configureMaxTimeAlwaysTimeOut("off"); +assert.commandWorked(coll.runCommand("collStats", {maxTimeMS: 60 * 1000}), + "expected collStats to not hit time limit in mongod"); - // Positive test for "mapReduce". - configureMaxTimeAlwaysTimeOut("alwaysOn"); - res = coll.runCommand("mapReduce", { - map: function() { - emit(0, 0); - }, - reduce: function(key, values) { - return 0; - }, - out: {inline: 1}, - maxTimeMS: 60 * 1000 - }); - assert.commandFailedWithCode( - res, - ErrorCodes.MaxTimeMSExpired, - "expected mapReduce to fail with code " + ErrorCodes.MaxTimeMSExpired + - " due to maxTimeAlwaysTimeOut fail point, but instead got: " + tojson(res)); +// Positive test for "mapReduce". +configureMaxTimeAlwaysTimeOut("alwaysOn"); +res = coll.runCommand("mapReduce", { + map: function() { + emit(0, 0); + }, + reduce: function(key, values) { + return 0; + }, + out: {inline: 1}, + maxTimeMS: 60 * 1000 +}); +assert.commandFailedWithCode( + res, + ErrorCodes.MaxTimeMSExpired, + "expected mapReduce to fail with code " + ErrorCodes.MaxTimeMSExpired + + " due to maxTimeAlwaysTimeOut fail point, but instead got: " + tojson(res)); - // Negative test for "mapReduce". - configureMaxTimeAlwaysTimeOut("off"); - assert.commandWorked(coll.runCommand("mapReduce", { - map: function() { - emit(0, 0); - }, - reduce: function(key, values) { - return 0; - }, - out: {inline: 1}, - maxTimeMS: 60 * 1000 - }), - "expected mapReduce to not hit time limit in mongod"); +// Negative test for "mapReduce". +configureMaxTimeAlwaysTimeOut("off"); +assert.commandWorked(coll.runCommand("mapReduce", { + map: function() { + emit(0, 0); + }, + reduce: function(key, values) { + return 0; + }, + out: {inline: 1}, + maxTimeMS: 60 * 1000 +}), + "expected mapReduce to not hit time limit in mongod"); - // Positive test for "aggregate". - configureMaxTimeAlwaysTimeOut("alwaysOn"); - assert.commandFailedWithCode( - coll.runCommand("aggregate", {pipeline: [], cursor: {}, maxTimeMS: 60 * 1000}), - ErrorCodes.MaxTimeMSExpired, - "expected aggregate to fail with code " + ErrorCodes.MaxTimeMSExpired + - " due to maxTimeAlwaysTimeOut fail point, but instead got: " + tojson(res)); +// Positive test for "aggregate". +configureMaxTimeAlwaysTimeOut("alwaysOn"); +assert.commandFailedWithCode( + coll.runCommand("aggregate", {pipeline: [], cursor: {}, maxTimeMS: 60 * 1000}), + ErrorCodes.MaxTimeMSExpired, + "expected aggregate to fail with code " + ErrorCodes.MaxTimeMSExpired + + " due to maxTimeAlwaysTimeOut fail point, but instead got: " + tojson(res)); - // Negative test for "aggregate". - configureMaxTimeAlwaysTimeOut("off"); - assert.commandWorked( - coll.runCommand("aggregate", {pipeline: [], cursor: {}, maxTimeMS: 60 * 1000}), - "expected aggregate to not hit time limit in mongod"); +// Negative test for "aggregate". +configureMaxTimeAlwaysTimeOut("off"); +assert.commandWorked(coll.runCommand("aggregate", {pipeline: [], cursor: {}, maxTimeMS: 60 * 1000}), + "expected aggregate to not hit time limit in mongod"); - // Test that the maxTimeMS is still enforced on the shards even if we do not spend much time in - // mongos blocking. +// Test that the maxTimeMS is still enforced on the shards even if we do not spend much time in +// mongos blocking. - // Manually run a find here so we can be sure cursor establishment happens with batch size 0. - res = assert.commandWorked(coll.runCommand({ - find: coll.getName(), - filter: { - $where: function() { - if (this._id < 0) { - // Slow down the query only on one of the shards. Each shard has 500 documents - // so we expect this shard to take ~10 seconds to return a batch of 500. - sleep(20); - } - return true; +// Manually run a find here so we can be sure cursor establishment happens with batch size 0. +res = assert.commandWorked(coll.runCommand({ + find: coll.getName(), + filter: { + $where: function() { + if (this._id < 0) { + // Slow down the query only on one of the shards. Each shard has 500 documents + // so we expect this shard to take ~10 seconds to return a batch of 500. + sleep(20); } - }, - maxTimeMS: 2000, - batchSize: 0 - })); - // Use a batch size of 500 to allow returning results from the fast shard as soon as they're - // ready, as opposed to waiting to return one 16MB batch at a time. - const kBatchSize = nDocsPerShard; - cursor = new DBCommandCursor(coll.getDB(), res, kBatchSize); - // The fast shard should return relatively quickly. - for (let i = 0; i < nDocsPerShard; ++i) { - let next = assert.doesNotThrow( - () => cursor.next(), [], "did not expect mongos to time out first batch of query"); - assert.gte(next._id, 0); - } - // Sleep on the client-side so mongos's time budget is not being used. - sleep(3 * 1000); - // Even though mongos has not been blocking this whole time, the shard has been busy computing - // the next batch and should have timed out. - assert.throws(() => cursor.next(), [], "expected mongos to abort getMore due to time limit"); + return true; + } + }, + maxTimeMS: 2000, + batchSize: 0 +})); +// Use a batch size of 500 to allow returning results from the fast shard as soon as they're +// ready, as opposed to waiting to return one 16MB batch at a time. +const kBatchSize = nDocsPerShard; +cursor = new DBCommandCursor(coll.getDB(), res, kBatchSize); +// The fast shard should return relatively quickly. +for (let i = 0; i < nDocsPerShard; ++i) { + let next = assert.doesNotThrow( + () => cursor.next(), [], "did not expect mongos to time out first batch of query"); + assert.gte(next._id, 0); +} +// Sleep on the client-side so mongos's time budget is not being used. +sleep(3 * 1000); +// Even though mongos has not been blocking this whole time, the shard has been busy computing +// the next batch and should have timed out. +assert.throws(() => cursor.next(), [], "expected mongos to abort getMore due to time limit"); - // The moveChunk tests are disabled due to SERVER-30179 - // - // // Positive test for "moveChunk". - // configureMaxTimeAlwaysTimeOut("alwaysOn"); - // res = admin.runCommand({ - // moveChunk: coll.getFullName(), - // find: {_id: 0}, - // to: st.shard0.shardName, - // maxTimeMS: 1000 * 60 * 60 * 24 - // }); - // assert.commandFailed( - // res, - // "expected moveChunk to fail due to maxTimeAlwaysTimeOut fail point, but instead got: " + - // tojson(res)); +// The moveChunk tests are disabled due to SERVER-30179 +// +// // Positive test for "moveChunk". +// configureMaxTimeAlwaysTimeOut("alwaysOn"); +// res = admin.runCommand({ +// moveChunk: coll.getFullName(), +// find: {_id: 0}, +// to: st.shard0.shardName, +// maxTimeMS: 1000 * 60 * 60 * 24 +// }); +// assert.commandFailed( +// res, +// "expected moveChunk to fail due to maxTimeAlwaysTimeOut fail point, but instead got: " + +// tojson(res)); - // // Negative test for "moveChunk". - // configureMaxTimeAlwaysTimeOut("off"); - // assert.commandWorked(admin.runCommand({ - // moveChunk: coll.getFullName(), - // find: {_id: 0}, - // to: st.shard0.shardName, - // maxTimeMS: 1000 * 60 * 60 * 24 - // }), - // "expected moveChunk to not hit time limit in mongod"); +// // Negative test for "moveChunk". +// configureMaxTimeAlwaysTimeOut("off"); +// assert.commandWorked(admin.runCommand({ +// moveChunk: coll.getFullName(), +// find: {_id: 0}, +// to: st.shard0.shardName, +// maxTimeMS: 1000 * 60 * 60 * 24 +// }), +// "expected moveChunk to not hit time limit in mongod"); - st.stop(); +st.stop(); })(); |