diff options
Diffstat (limited to 'jstests/replsets/election_participant_new_term_metrics.js')
-rw-r--r-- | jstests/replsets/election_participant_new_term_metrics.js | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/jstests/replsets/election_participant_new_term_metrics.js b/jstests/replsets/election_participant_new_term_metrics.js new file mode 100644 index 00000000000..aa76bdf4546 --- /dev/null +++ b/jstests/replsets/election_participant_new_term_metrics.js @@ -0,0 +1,109 @@ +/** + * 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. + */ + +(function() { +"use strict"; + +const testName = jsTestName(); +const rst = 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.initiateWithHighElectionTimeout(); + +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. +assert.commandWorked(newPrimary.adminCommand({replSetStepUp: 1})); +rst.awaitNodesAgreeOnPrimary(); +assert.eq(newPrimary, rst.getPrimary()); + +// 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(); +})();
\ No newline at end of file |