mongo/jstests/slow1/replsets_priority1.js

201 lines
5.6 KiB
JavaScript

// come up with random priorities and make sure that the right member gets
// elected. then kill that member and make sure the next one gets elected.
// @tags: [
// # We are choosing not to test on MacOS since it's too noisy.
// slow_on_macos,
// ]
import {ReplSetTest} from "jstests/libs/replsettest.js";
import {isConfigCommitted, occasionally, reconnect} from "jstests/replsets/rslib.js";
const rs = new ReplSetTest({name: "testSet", nodes: 3, nodeOptions: {verbose: 2}});
rs.startSet();
rs.initiate(null, null, {initiateWithDefaultElectionTimeout: true});
let primary = rs.getPrimary();
let everyoneOkSoon = function () {
let status;
assert.soon(function () {
let ok = true;
status = primary.adminCommand({replSetGetStatus: 1});
if (!status.members) {
return false;
}
for (let i in status.members) {
if (status.members[i].health == 0) {
continue;
}
ok &= status.members[i].state == 1 || status.members[i].state == 2;
}
return ok;
}, tojson(status));
};
let checkPrimaryIs = function (node) {
print("nreplsets_priority1.js checkPrimaryIs(" + node.host + ")");
let status;
assert.soon(
function () {
let ok = true;
try {
status = primary.adminCommand({replSetGetStatus: 1});
} catch (e) {
print(e);
print("nreplsets_priority1.js checkPrimaryIs reconnecting");
reconnect(primary);
status = primary.adminCommand({replSetGetStatus: 1});
}
let str = "goal: " + node.host + "==1 states: ";
if (!status || !status.members) {
return false;
}
status.members.forEach(function (m) {
str += m.name + ": " + m.state + " ";
if (m.name == node.host) {
ok &= m.state == 1;
} else {
ok &= m.state != 1 || (m.state == 1 && m.health == 0);
}
});
print();
print(str);
print();
occasionally(function () {
print("\nstatus:");
printjson(status);
print();
}, 15);
return ok;
},
node.host + "==1",
240000,
1000,
);
everyoneOkSoon();
};
everyoneOkSoon();
jsTestLog("replsets_priority1.js initial sync");
// intial sync
primary.getDB("foo").bar.insert({x: 1});
rs.awaitReplication();
jsTestLog("replsets_priority1.js starting loop");
let n = 5;
for (let i = 0; i < n; i++) {
jsTestLog("Round " + i + ": FIGHT!");
var max = null;
var second = null;
primary = rs.getPrimary();
var config = primary.getDB("local").system.replset.findOne();
config.version++;
for (let j = 0; j < config.members.length; j++) {
let priority = Math.random() * 100;
print("random priority : " + priority);
config.members[j].priority = priority;
if (!max || priority > max.priority) {
max = config.members[j];
}
}
for (let j = 0; j < config.members.length; j++) {
if (config.members[j] == max) {
continue;
}
if (!second || config.members[j].priority > second.priority) {
second = config.members[j];
}
}
jsTestLog(
"replsets_priority1.js max is " +
max.host +
" with priority " +
max.priority +
", reconfiguring on " +
primary.host,
);
assert.soon(() => isConfigCommitted(primary));
assert.commandWorked(primary.adminCommand({replSetReconfig: config}));
jsTestLog("replsets_priority1.js wait for 2 secondaries");
assert.soon(function () {
rs.getPrimary();
return rs.getSecondaries().length == 2;
}, "2 secondaries");
jsTestLog("replsets_priority1.js wait for new config version " + config.version);
assert.soon(function () {
let versions = [0, 0];
let secondaries = rs.getSecondaries();
secondaries[0].setSecondaryOk();
versions[0] = secondaries[0].getDB("local").system.replset.findOne().version;
secondaries[1].setSecondaryOk();
versions[1] = secondaries[1].getDB("local").system.replset.findOne().version;
return versions[0] == config.version && versions[1] == config.version;
});
jsTestLog("replsets_priority1.js awaitReplication");
// the reconfiguration needs to be replicated! the hb sends it out
// separately from the repl
rs.awaitReplication();
jsTestLog("reconfigured. Checking statuses.");
checkPrimaryIs(max);
// Wait for election oplog entry to be replicated, to avoid rollbacks later on.
rs.awaitReplication();
jsTestLog("rs.stop");
rs.stop(max._id);
primary = rs.getPrimary();
jsTestLog("killed max primary. Checking statuses.");
jsTestLog("second is " + second.host + " with priority " + second.priority);
checkPrimaryIs(second);
// Wait for election oplog entry to be replicated, to avoid rollbacks later on.
let liveSecondaries = rs.nodes.filter(function (node) {
return node.host !== max.host && node.host !== second.host;
});
rs.awaitReplication(null, null, liveSecondaries);
jsTestLog("restart max " + max._id);
rs.restart(max._id);
primary = rs.getPrimary();
jsTestLog("max restarted. Checking statuses.");
checkPrimaryIs(max);
// Wait for election oplog entry to be replicated, to avoid rollbacks later on.
rs.awaitReplication();
}
rs.stopSet();