/* * Simple test to ensure that an invalid reconfig fails, a valid one succeeds, and a reconfig won't * succeed without force if force is needed. */ (function() { "use strict"; // Skip db hash check because secondary is left with a different config. TestData.skipCheckDBHashes = true; var numNodes = 5; var replTest = new ReplSetTest({name: 'testSet', nodes: numNodes}); var nodes = replTest.startSet(); replTest.initiate(); var primary = replTest.getPrimary(); replTest.awaitSecondaryNodes(); jsTestLog("Valid reconfig"); var config = primary.getDB("local").system.replset.findOne(); printjson(config); config.version++; config.members[nodes.indexOf(primary)].priority = 2; assert.commandWorked(primary.getDB("admin").runCommand({replSetReconfig: config})); // Successful reconfig writes a no-op into the oplog. const expectedNoOp = { op: "n", o: {msg: "Reconfig set", version: config.version} }; const primaryOplog = primary.getDB("local")['oplog.rs']; const lastOp = primaryOplog.find(expectedNoOp).sort({'$natural': -1}).limit(1).toArray(); assert(lastOp.length > 0); replTest.awaitReplication(); jsTestLog("Invalid reconfig"); config.version++; var badMember = {_id: numNodes, host: "localhost:12345", priority: "High"}; config.members.push(badMember); var invalidConfigCode = 93; assert.commandFailedWithCode(primary.adminCommand({replSetReconfig: config}), invalidConfigCode); jsTestLog("No force when needed."); config.members = config.members.slice(0, numNodes - 1); var secondary = replTest.getSecondary(); config.members[nodes.indexOf(secondary)].priority = 5; var admin = secondary.getDB("admin"); var forceRequiredCode = 10107; assert.commandFailedWithCode(admin.runCommand({replSetReconfig: config}), forceRequiredCode); jsTestLog("Force when appropriate"); assert.commandWorked(admin.runCommand({replSetReconfig: config, force: true})); // Wait for the last node to know it is REMOVED before stopping the test. jsTestLog("Waiting for the last node to be REMOVED."); assert.soonNoExcept(() => { assert.commandFailedWithCode(nodes[4].adminCommand({'replSetGetStatus': 1}), ErrorCodes.InvalidReplicaSetConfig); return true; }); jsTestLog("Finished waiting for the last node to be REMOVED."); replTest.stopSet(); }());