0
0
mirror of https://github.com/mongodb/mongo.git synced 2024-12-01 09:32:32 +01:00
mongodb/jstests/replsets/apply_ops_wc.js

139 lines
4.4 KiB
JavaScript

/**
* apply_ops_wc.js
*
* This file tests SERVER-22270 that applyOps commands should take a writeConcern.
* This first tests that invalid write concerns cause writeConcern errors.
* Next, it tests replication with writeConcerns of w:2 and w:majority.
* When there are 3 nodes up in a replica set, applyOps commands succeed.
* It then stops replication at one seconday and confirms that applyOps commands still succeed.
* It finally stops replication at another secondary and confirms that applyOps commands fail.
*/
(function() {
"use strict";
var nodeCount = 3;
var replTest = new ReplSetTest({name: 'applyOpsWCSet', nodes: nodeCount});
replTest.startSet();
var cfg = replTest.getReplSetConfig();
cfg.settings = {};
cfg.settings.chainingAllowed = false;
replTest.initiate(cfg);
var testDB = "applyOps-wc-test";
// Get test collection.
var master = replTest.getPrimary();
var db = master.getDB(testDB);
var coll = db.apply_ops_wc;
function dropTestCollection() {
coll.drop();
assert.eq(0, coll.find().itcount(), "test collection not empty");
}
dropTestCollection();
// Set up the applyOps command.
var applyOpsReq = {
applyOps: [
{op: "i", ns: coll.getFullName(), o: {_id: 2, x: "b"}},
{op: "i", ns: coll.getFullName(), o: {_id: 3, x: "c"}},
{op: "i", ns: coll.getFullName(), o: {_id: 4, x: "d"}},
]
};
function assertApplyOpsCommandWorked(res) {
assert.eq(3, res.applied);
assert.commandWorkedIgnoringWriteConcernErrors(res);
assert.eq([true, true, true], res.results);
}
function assertWriteConcernError(res) {
assert(res.writeConcernError);
assert(res.writeConcernError.code);
assert(res.writeConcernError.errmsg);
}
var invalidWriteConcerns = [{w: 'invalid'}, {w: nodeCount + 1}];
function testInvalidWriteConcern(wc) {
jsTest.log("Testing invalid write concern " + tojson(wc));
applyOpsReq.writeConcern = wc;
dropTestCollection();
assert.commandWorked(coll.insert({_id: 1, x: "a"}));
var res = coll.runCommand(applyOpsReq);
assertApplyOpsCommandWorked(res);
assertWriteConcernError(res);
}
// Verify that invalid write concerns yield an error.
coll.insert({_id: 1, x: "a"});
invalidWriteConcerns.forEach(testInvalidWriteConcern);
var secondaries = replTest.getSecondaries();
var majorityWriteConcerns = [
{w: 2, wtimeout: 30000},
{w: 'majority', wtimeout: 30000},
];
function testMajorityWriteConcerns(wc) {
jsTest.log("Testing " + tojson(wc));
// Reset secondaries to ensure they can replicate.
secondaries[0].getDB('admin').runCommand({configureFailPoint: 'rsSyncApplyStop', mode: 'off'});
secondaries[1].getDB('admin').runCommand({configureFailPoint: 'rsSyncApplyStop', mode: 'off'});
// Set the writeConcern of the applyOps command.
applyOpsReq.writeConcern = wc;
dropTestCollection();
// applyOps with a full replica set should succeed.
assert.commandWorked(coll.insert({_id: 1, x: "a"}));
var res = db.runCommand(applyOpsReq);
assertApplyOpsCommandWorked(res);
assert(!res.writeConcernError,
'applyOps on a full replicaset had writeConcern error ' + tojson(res.writeConcernError));
dropTestCollection();
// Stop replication at one secondary.
secondaries[0].getDB('admin').runCommand(
{configureFailPoint: 'rsSyncApplyStop', mode: 'alwaysOn'});
// applyOps should succeed with only 1 node not replicating.
assert.commandWorked(coll.insert({_id: 1, x: "a"}));
res = db.runCommand(applyOpsReq);
assertApplyOpsCommandWorked(res);
assert(!res.writeConcernError,
'applyOps on a replicaset with 2 working nodes had writeConcern error ' +
tojson(res.writeConcernError));
dropTestCollection();
// Stop replication at a second secondary.
secondaries[1].getDB('admin').runCommand(
{configureFailPoint: 'rsSyncApplyStop', mode: 'alwaysOn'});
// applyOps should fail after two nodes have stopped replicating.
assert.commandWorked(coll.insert({_id: 1, x: "a"}));
applyOpsReq.writeConcern.wtimeout = 5000;
res = db.runCommand(applyOpsReq);
assertApplyOpsCommandWorked(res);
assertWriteConcernError(res);
}
majorityWriteConcerns.forEach(testMajorityWriteConcerns);
// Allow clean shutdown
secondaries[0].getDB('admin').runCommand({configureFailPoint: 'rsSyncApplyStop', mode: 'off'});
secondaries[1].getDB('admin').runCommand({configureFailPoint: 'rsSyncApplyStop', mode: 'off'});
replTest.stopSet();
})();