130 lines
5.2 KiB
JavaScript
130 lines
5.2 KiB
JavaScript
// Test that mapReduce correctly fails if the target collection is not unsharded or sharded by just
|
|
// _id.
|
|
(function() {
|
|
"use strict";
|
|
|
|
const st = new ShardingTest({shards: 2, mongos: 2});
|
|
|
|
const dbName = jsTest.name();
|
|
const nsString = dbName + ".coll";
|
|
const numDocs = 50000;
|
|
const numKeys = 1000;
|
|
|
|
assert.commandWorked(st.s.adminCommand({enableSharding: dbName}));
|
|
st.ensurePrimaryShard(dbName, st.shard0.shardName);
|
|
assert.commandWorked(st.s.adminCommand({shardCollection: nsString, key: {key: 1}}));
|
|
|
|
// Load chunk data through the stale mongos before moving a chunk.
|
|
const staleMongos1 = st.s1;
|
|
staleMongos1.getCollection(nsString).find().itcount();
|
|
|
|
assert.commandWorked(st.s.adminCommand({split: nsString, middle: {key: numKeys / 2}}));
|
|
assert.commandWorked(
|
|
st.s.adminCommand({moveChunk: nsString, find: {key: 0}, to: st.shard1.shardName}));
|
|
|
|
const bulk = st.s.getCollection(nsString).initializeUnorderedBulkOp();
|
|
for (let i = 0; i < numDocs; i++) {
|
|
bulk.insert({_id: i, key: (i % numKeys), value: i % numKeys});
|
|
}
|
|
assert.commandWorked(bulk.execute());
|
|
|
|
const map = function() {
|
|
emit(this.key, this.value);
|
|
};
|
|
const reduce = function(k, values) {
|
|
let total = 0;
|
|
for (let i = 0; i < values.length; i++) {
|
|
total += values[i];
|
|
}
|
|
return total;
|
|
};
|
|
|
|
// Create and shard the output collection, with a shard key other than _id.
|
|
const outColl = "mr_out";
|
|
assert.commandWorked(
|
|
st.s.adminCommand({shardCollection: dbName + "." + outColl, key: {not_id: 1}}));
|
|
|
|
// Insert a document into the output collection such that it is not dropped and recreated by the
|
|
// legacy mapReduce.
|
|
assert.commandWorked(st.s.getDB(dbName).getCollection(outColl).insert({_id: -1, not_id: 0}));
|
|
|
|
// Through the same mongos, verify that mapReduce fails since the output collection is not sharded
|
|
// by _id.
|
|
assert.commandFailedWithCode(
|
|
st.s.getDB(dbName).runCommand(
|
|
{mapReduce: "coll", map: map, reduce: reduce, out: {merge: outColl, sharded: true}}),
|
|
31313);
|
|
|
|
assert.commandFailedWithCode(
|
|
st.s.getDB(dbName).runCommand(
|
|
{mapReduce: "coll", map: map, reduce: reduce, out: {reduce: outColl, sharded: true}}),
|
|
31313);
|
|
|
|
// Expect a similar failure through a stale mongos.
|
|
assert.commandFailedWithCode(
|
|
staleMongos1.getDB(dbName).runCommand(
|
|
{mapReduce: "coll", map: map, reduce: reduce, out: {merge: outColl, sharded: true}}),
|
|
31313);
|
|
|
|
// Mode replace is unique, since the legacy mapReduce will unconditionally drop and reshard the
|
|
// target collection on _id.
|
|
assert.commandFailedWithCode(
|
|
st.s.getDB(dbName).runCommand(
|
|
{mapReduce: "coll", map: map, reduce: reduce, out: {replace: outColl, sharded: true}}),
|
|
31313);
|
|
|
|
function testAgainstValidShardedOutput(shardKey) {
|
|
// Drop and reshard the target collection.
|
|
st.s.getDB(dbName).getCollection(outColl).drop();
|
|
assert.commandWorked(
|
|
st.s.adminCommand({shardCollection: dbName + "." + outColl, key: shardKey}));
|
|
|
|
// Insert a document into the output collection such that it is not dropped and recreated by the
|
|
// legacy mapReduce.
|
|
assert.commandWorked(st.s.getDB(dbName).getCollection(outColl).insert({_id: -1}));
|
|
|
|
// Test that mapReduce succeeds since the target collection is sharded by _id.
|
|
assert.commandWorked(st.s.getDB(dbName).runCommand(
|
|
{mapReduce: "coll", map: map, reduce: reduce, out: {merge: outColl, sharded: true}}));
|
|
|
|
// Run the same mapReduce through a stale mongos and expect it to pass as well.
|
|
assert.commandWorked(st.s.getDB(dbName).getCollection(outColl).remove({}));
|
|
assert.commandWorked(staleMongos1.getDB(dbName).runCommand(
|
|
{mapReduce: "coll", map: map, reduce: reduce, out: {merge: outColl, sharded: true}}));
|
|
}
|
|
|
|
// Test against output collection sharded by {_id: 1}.
|
|
testAgainstValidShardedOutput({_id: 1});
|
|
|
|
// Test against output collection sharded by {_id: "hashed"}.
|
|
testAgainstValidShardedOutput({_id: "hashed"});
|
|
|
|
// Test that MR fails if the output collection is sharded by a compound key including _id.
|
|
(function testCompoundShardKey() {
|
|
// Drop and reshard the target collection.
|
|
st.s.getDB(dbName).getCollection(outColl).drop();
|
|
assert.commandWorked(
|
|
st.s.adminCommand({shardCollection: dbName + "." + outColl, key: {_id: 1, a: 1}}));
|
|
|
|
// Insert a document into the output collection such that it is not dropped and recreated by the
|
|
// legacy mapReduce.
|
|
assert.commandWorked(st.s.getDB(dbName).getCollection(outColl).insert({_id: -1, a: 1}));
|
|
|
|
// Test that mapReduce succeeds since the target collection is not sharded by only _id.
|
|
assert.commandFailedWithCode(
|
|
st.s.getDB(dbName).runCommand(
|
|
{mapReduce: "coll", map: map, reduce: reduce, out: {merge: outColl, sharded: true}}),
|
|
31313);
|
|
|
|
// Run the same mapReduce through a stale mongos and expect it to fail as well. Make sure to
|
|
// leave at least one document in the target collection for the same reason as above.
|
|
assert.commandWorked(st.s.getDB(dbName).getCollection(outColl).remove({_id: {$gt: 0}}));
|
|
assert.commandFailedWithCode(
|
|
staleMongos1.getDB(dbName).runCommand(
|
|
{mapReduce: "coll", map: map, reduce: reduce, out: {merge: outColl, sharded: true}}),
|
|
31313);
|
|
})();
|
|
|
|
st.stop();
|
|
})();
|