mirror of
https://github.com/mongodb/mongo.git
synced 2024-11-24 16:46:00 +01:00
2fd5f78d5a
GitOrigin-RevId: df168ee363c3f0e86526270437d3688ac4bb326d
105 lines
5.5 KiB
JavaScript
105 lines
5.5 KiB
JavaScript
/**
|
|
* This test checks that the 'newTermStartDate' and 'newTermAppliedDate' metrics in
|
|
* 'electionParticipantMetrics' are set and updated correctly. We test this with a three node
|
|
* replica set by successfully stepping up one of the secondaries, then failing to step up the
|
|
* original primary. We check that the metrics are appropriately set or unset after each election.
|
|
*/
|
|
import {ReplSetTest} from "jstests/libs/replsettest.js";
|
|
|
|
const testName = jsTestName();
|
|
const rst = new ReplSetTest({name: testName, nodes: [{}, {}, {rsConfig: {priority: 0}}]});
|
|
rst.startSet();
|
|
|
|
// Make sure there are no election timeouts firing for the duration of the test. This helps
|
|
// ensure that the test will only pass if the election succeeds.
|
|
rst.initiate();
|
|
|
|
const originalPrimary = rst.getPrimary();
|
|
const newPrimary = rst.getSecondaries()[0];
|
|
const testNode = rst.getSecondaries()[1];
|
|
|
|
// Set up a failpoint that forces the original primary to vote no in this election. This guarantees
|
|
// that 'testNode' will be a participant in this election, since its vote will be needed for the new
|
|
// primary to win.
|
|
assert.commandWorked(
|
|
originalPrimary.adminCommand({configureFailPoint: "voteNoInElection", mode: "alwaysOn"}));
|
|
|
|
// Step up the new primary.
|
|
rst.stepUp(newPrimary);
|
|
|
|
// Since the new term oplog entry needs to be replicated onto testNode for the metrics to be set, we
|
|
// must await replication before checking the metrics.
|
|
rst.awaitReplication();
|
|
|
|
let testNodeReplSetGetStatus = assert.commandWorked(testNode.adminCommand({replSetGetStatus: 1}));
|
|
let testNodeElectionParticipantMetrics = testNodeReplSetGetStatus.electionParticipantMetrics;
|
|
|
|
const originalNewTermStartDate = testNodeElectionParticipantMetrics.newTermStartDate;
|
|
const originalNewTermAppliedDate = testNodeElectionParticipantMetrics.newTermAppliedDate;
|
|
|
|
// These fields should be set, since testNode has received and applied the new term oplog entry
|
|
// after the election.
|
|
assert(originalNewTermStartDate,
|
|
() => "Response should have an 'electionParticipantMetrics.newTermStartDate' field: " +
|
|
tojson(testNodeElectionParticipantMetrics));
|
|
assert(originalNewTermAppliedDate,
|
|
() => "Response should have an 'electionParticipantMetrics.newTermAppliedDate' field: " +
|
|
tojson(testNodeElectionParticipantMetrics));
|
|
|
|
// Set up a failpoint that forces newPrimary and testNode to vote no in the election, in addition to
|
|
// the new primary above. This will cause the dry run to fail for the original primary.
|
|
assert.commandWorked(
|
|
newPrimary.adminCommand({configureFailPoint: "voteNoInElection", mode: "alwaysOn"}));
|
|
assert.commandWorked(
|
|
testNode.adminCommand({configureFailPoint: "voteNoInElection", mode: "alwaysOn"}));
|
|
|
|
// Attempt to step up the original primary.
|
|
assert.commandFailedWithCode(originalPrimary.adminCommand({replSetStepUp: 1}),
|
|
ErrorCodes.CommandFailed);
|
|
|
|
testNodeReplSetGetStatus = assert.commandWorked(testNode.adminCommand({replSetGetStatus: 1}));
|
|
testNodeElectionParticipantMetrics = testNodeReplSetGetStatus.electionParticipantMetrics;
|
|
|
|
// The 'newTermStartDate' and 'newTermAppliedDate' fields should not be cleared, since the term is
|
|
// not incremented when a dry run election is initiated.
|
|
assert(testNodeElectionParticipantMetrics.newTermStartDate,
|
|
() => "Response should have an 'electionParticipantMetrics.newTermStartDate' field: " +
|
|
tojson(testNodeElectionParticipantMetrics));
|
|
assert(testNodeElectionParticipantMetrics.newTermAppliedDate,
|
|
() => "Response should have an 'electionParticipantMetrics.newTermAppliedDate' field: " +
|
|
tojson(testNodeElectionParticipantMetrics));
|
|
|
|
// The fields should store the same dates, since a new term oplog entry was not received.
|
|
assert.eq(originalNewTermStartDate, testNodeElectionParticipantMetrics.newTermStartDate);
|
|
assert.eq(originalNewTermAppliedDate, testNodeElectionParticipantMetrics.newTermAppliedDate);
|
|
|
|
// Clear the previous failpoint and set up a new one that forces the two current secondaries to vote
|
|
// yes for the candidate in the dry run election and no in the real election. This will cause the
|
|
// real election to fail.
|
|
assert.commandWorked(
|
|
newPrimary.adminCommand({configureFailPoint: "voteNoInElection", mode: "off"}));
|
|
assert.commandWorked(newPrimary.adminCommand(
|
|
{configureFailPoint: "voteYesInDryRunButNoInRealElection", mode: "alwaysOn"}));
|
|
assert.commandWorked(testNode.adminCommand({configureFailPoint: "voteNoInElection", mode: "off"}));
|
|
assert.commandWorked(testNode.adminCommand(
|
|
{configureFailPoint: "voteYesInDryRunButNoInRealElection", mode: "alwaysOn"}));
|
|
|
|
// Attempt to step up the original primary.
|
|
assert.commandFailedWithCode(originalPrimary.adminCommand({replSetStepUp: 1}),
|
|
ErrorCodes.CommandFailed);
|
|
|
|
testNodeReplSetGetStatus = assert.commandWorked(testNode.adminCommand({replSetGetStatus: 1}));
|
|
testNodeElectionParticipantMetrics = testNodeReplSetGetStatus.electionParticipantMetrics;
|
|
|
|
// Since the election succeeded in the dry run, a new term was encountered by the secondary.
|
|
// However, because the real election failed, there was no new term oplog entry, so these fields
|
|
// should not be set.
|
|
assert(!testNodeElectionParticipantMetrics.newTermStartDate,
|
|
() => "Response should not have an 'electionParticipantMetrics.newTermStartDate' field: " +
|
|
tojson(testNodeElectionParticipantMetrics));
|
|
assert(!testNodeElectionParticipantMetrics.newTermAppliedDate,
|
|
() => "Response should not have an 'electionParticipantMetrics.newTermAppliedDate' field: " +
|
|
tojson(testNodeElectionParticipantMetrics));
|
|
|
|
rst.stopSet();
|