Files
mongo/jstests/sharding/max_time_ms_sharded.js
Kaloian Manassiev a7e6d919ec SERVER-21050 Continuous config server primary step down
This change adds a continuous primary stepdown capability to the
ReplicaSetTest and hooks it into ShardingTest.
2015-12-23 10:39:04 -05:00

218 lines
9.0 KiB
JavaScript

// Test mongos implementation of time-limited operations: verify that mongos correctly forwards max
// time to shards, and that mongos correctly times out max time sharded getmore operations (which
// are run in series on shards).
//
// 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';
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 exceededTimeLimit = 50; // ErrorCodes::ExceededTimeLimit
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 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()}));
admin.runCommand({movePrimary: coll.getDB().getName(),
to: "shard0000"});
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: "shard0001"}));
//
// Insert 100 documents into sharded collection, such that each shard owns 50.
//
var bulk = coll.initializeUnorderedBulkOp();
for (var i = -50; i < 50; i++) {
bulk.insert({ _id: i });
}
assert.writeOK(bulk.execute());
assert.eq(50, shards[0].getCollection(coll.getFullName()).count());
assert.eq(50, 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.
//
// 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");
//
// Test that mongos correctly times out max time sharded getmore operations. Uses
// maxTimeNeverTimeOut to ensure mongod doesn't enforce a time limit.
//
// TODO: This is unimplemented. A test for this functionality should be written as
// part of the work for SERVER-19410.
//
configureMaxTimeNeverTimeOut("alwaysOn");
// Positive test. TODO: see above.
// Negative test. ~10s operation, with a high (1-day) limit.
cursor = coll.find({$where: function() { sleep(100); 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");
//
// 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");
res = coll.runCommand("validate", {maxTimeMS: 60*1000});
assert.commandFailed(res,
"expected validate to fail in mongod due to maxTimeAlwaysTimeOut fail point");
assert.eq(res["code"],
exceededTimeLimit,
"expected code " + exceededTimeLimit + " from validate, 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");
// Positive test for "count".
configureMaxTimeAlwaysTimeOut("alwaysOn");
res = coll.runCommand("count", {maxTimeMS: 60*1000});
assert.commandFailed(res,
"expected count to fail in mongod due to maxTimeAlwaysTimeOut fail point");
assert.eq(res["code"],
exceededTimeLimit,
"expected code " + exceededTimeLimit + " from count , 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");
// Positive test for "collStats".
configureMaxTimeAlwaysTimeOut("alwaysOn");
res = coll.runCommand("collStats", {maxTimeMS: 60*1000});
assert.commandFailed(res,
"expected collStats to fail in mongod due to maxTimeAlwaysTimeOut fail point");
assert.eq(res["code"],
exceededTimeLimit,
"expected code " + exceededTimeLimit + " from collStats, 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");
// 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.commandFailed(res,
"expected mapReduce to fail in mongod due to maxTimeAlwaysTimeOut fail point");
assert.eq(res["code"],
exceededTimeLimit,
"expected code " + exceededTimeLimit + " from mapReduce, 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");
// Positive test for "aggregate".
configureMaxTimeAlwaysTimeOut("alwaysOn");
res = coll.runCommand("aggregate", {pipeline: [],
maxTimeMS: 60*1000});
assert.commandFailed(res,
"expected aggregate to fail in mongod due to maxTimeAlwaysTimeOut fail point");
assert.eq(res["code"],
exceededTimeLimit,
"expected code " + exceededTimeLimit + " from aggregate , instead got: " + tojson(res));
// Negative test for "aggregate".
configureMaxTimeAlwaysTimeOut("off");
assert.commandWorked(coll.runCommand("aggregate", {pipeline: [],
maxTimeMS: 60*1000}),
"expected aggregate to not hit time limit in mongod");
// Positive test for "moveChunk".
configureMaxTimeAlwaysTimeOut("alwaysOn");
res = admin.runCommand({moveChunk: coll.getFullName(),
find: {_id: 0},
to: "shard0000",
maxTimeMS: 1000*60*60*24});
assert.commandFailed(res,
"expected moveChunk to fail in mongod due to maxTimeAlwaysTimeOut fail point");
assert.eq(res["code"],
exceededTimeLimit,
"expected code " + exceededTimeLimit + " from moveChunk, instead got: " + tojson(res));
// Negative test for "moveChunk".
configureMaxTimeAlwaysTimeOut("off");
assert.commandWorked(admin.runCommand({moveChunk: coll.getFullName(),
find: {_id: 0},
to: "shard0000",
maxTimeMS: 1000*60*60*24}),
"expected moveChunk to not hit time limit in mongod");
// TODO Test additional commmands.
st.stop();
})();