mongo/jstests/replsets/commands_that_write_accept_...

193 lines
5.4 KiB
JavaScript

/**
* This file tests that commands that do writes accept a write concern. This file does not test
* mongos commands or user management commands, both of which are tested separately. This test
* defines various database commands and what they expect to be true before and after the fact.
* It then runs the commands with an invalid writeConcern and a valid writeConcern and
* ensures that they succeed and fail appropriately.
*/
(function() {
"use strict";
var replTest = new ReplSetTest({
name: 'WCSet',
// Set priority of secondaries to zero to prevent spurious elections.
nodes: [{}, {rsConfig: {priority: 0}}, {rsConfig: {priority: 0}}],
settings: {chainingAllowed: false}
});
replTest.startSet();
replTest.initiate();
var primary = replTest.getPrimary();
var dbName = "wc-test";
var db = primary.getDB(dbName);
var collName = 'leaves';
var coll = db[collName];
function dropTestCollection() {
replTest.awaitReplication();
coll.drop();
assert.eq(0, coll.find().itcount(), "test collection not empty");
}
dropTestCollection();
var commands = [];
commands.push({
req: {insert: collName, documents: [{type: 'maple'}]},
setupFunc: function() {},
confirmFunc: function() {
assert.eq(coll.count({type: 'maple'}), 1);
}
});
commands.push({
req: {createIndexes: collName, indexes: [{key: {'type': 1}, name: 'type_index'}]},
setupFunc: function() {
coll.insert({type: 'oak'});
assert.eq(coll.getIndexes().length, 1);
},
confirmFunc: function() {
assert.eq(coll.getIndexes().length, 2);
}
});
commands.push({
req: {
update: collName,
updates: [{
q: {type: 'oak'},
u: [{$set: {type: 'ginkgo'}}],
}],
writeConcern: {w: 'majority'}
},
setupFunc: function() {
coll.insert({type: 'oak'});
assert.eq(coll.count({type: 'ginkgo'}), 0);
assert.eq(coll.count({type: 'oak'}), 1);
},
confirmFunc: function() {
assert.eq(coll.count({type: 'ginkgo'}), 1);
assert.eq(coll.count({type: 'oak'}), 0);
}
});
commands.push({
req: {
findAndModify: collName,
query: {type: 'oak'},
update: {$set: {type: 'ginkgo'}},
writeConcern: {w: 'majority'}
},
setupFunc: function() {
coll.insert({type: 'oak'});
assert.eq(coll.count({type: 'ginkgo'}), 0);
assert.eq(coll.count({type: 'oak'}), 1);
},
confirmFunc: function() {
assert.eq(coll.count({type: 'ginkgo'}), 1);
assert.eq(coll.count({type: 'oak'}), 0);
}
});
commands.push({
req: {
findAndModify: collName,
query: {type: 'oak'},
update: [{$set: {type: 'ginkgo'}}],
writeConcern: {w: 'majority'}
},
setupFunc: function() {
coll.insert({type: 'oak'});
assert.eq(coll.count({type: 'ginkgo'}), 0);
assert.eq(coll.count({type: 'oak'}), 1);
},
confirmFunc: function() {
assert.eq(coll.count({type: 'ginkgo'}), 1);
assert.eq(coll.count({type: 'oak'}), 0);
}
});
commands.push({
req: {applyOps: [{op: "u", ns: coll.getFullName(), o: {_id: 1, type: "willow"}, o2: {_id: 1}}]},
setupFunc: function() {
coll.insert({_id: 1, type: 'oak'});
assert.eq(coll.count({type: 'willow'}), 0);
},
confirmFunc: function() {
assert.eq(coll.count({type: 'willow'}), 1);
}
});
commands.push({
req: {aggregate: collName, pipeline: [{$sort: {type: 1}}, {$out: "foo"}], cursor: {}},
setupFunc: function() {
coll.insert({_id: 1, type: 'oak'});
coll.insert({_id: 2, type: 'maple'});
},
confirmFunc: function() {
assert.eq(db.foo.count({type: 'oak'}), 1);
assert.eq(db.foo.count({type: 'maple'}), 1);
db.foo.drop();
}
});
commands.push({
req: {
mapReduce: collName,
map: function() {
this.tags.forEach(function(z) {
emit(z, 1);
});
},
reduce: function(key, values) {
return {count: values.length};
},
out: "foo"
},
setupFunc: function() {
coll.insert({x: 1, tags: ["a", "b"]});
coll.insert({x: 2, tags: ["b", "c"]});
coll.insert({x: 3, tags: ["c", "a"]});
coll.insert({x: 4, tags: ["b", "c"]});
},
confirmFunc: function() {
assert.eq(db.foo.findOne({_id: 'a'}).value.count, 2);
assert.eq(db.foo.findOne({_id: 'b'}).value.count, 3);
assert.eq(db.foo.findOne({_id: 'c'}).value.count, 3);
db.foo.drop();
}
});
function testValidWriteConcern(cmd) {
cmd.req.writeConcern = {w: 'majority', wtimeout: ReplSetTest.kDefaultTimeoutMS};
jsTest.log("Testing " + tojson(cmd.req));
dropTestCollection();
cmd.setupFunc();
var res = db.runCommand(cmd.req);
assert.commandWorked(res);
assert(!res.writeConcernError,
'command on a full replicaset had writeConcernError: ' + tojson(res));
cmd.confirmFunc();
}
function testInvalidWriteConcern(cmd) {
cmd.req.writeConcern = {w: 'invalid'};
jsTest.log("Testing " + tojson(cmd.req));
dropTestCollection();
cmd.setupFunc();
var res = coll.runCommand(cmd.req);
assert.commandFailedWithCode(res, ErrorCodes.UnknownReplWriteConcern);
cmd.confirmFunc();
}
commands.forEach(function(cmd) {
testValidWriteConcern(cmd);
testInvalidWriteConcern(cmd);
});
replTest.stopSet();
})();