1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
/**
* Tests that the election metric for average number of catchup ops is being set correctly. We test
* this by electing a node to be primary twice and forcing it to catch up each time.
*/
(function() {
"use strict";
load("jstests/libs/logv2_helpers.js");
load("jstests/libs/write_concern_util.js");
load("jstests/replsets/libs/election_metrics.js");
load("jstests/replsets/rslib.js");
const name = jsTestName();
const rst = new ReplSetTest(
{name: name, nodes: 3, useBridge: true, settings: {catchUpTimeoutMillis: 4 * 60 * 1000}});
rst.startSet();
rst.initiateWithHighElectionTimeout();
rst.awaitSecondaryNodes();
// The default WC is majority and this test can't satisfy majority writes.
assert.commandWorked(rst.getPrimary().adminCommand(
{setDefaultRWConcern: 1, defaultWriteConcern: {w: 1}, writeConcern: {w: "majority"}}));
rst.awaitReplication();
const testNode = rst.getSecondaries()[0];
let stepUpResults = stopReplicationAndEnforceNewPrimaryToCatchUp(rst, testNode);
restartServerReplication(stepUpResults.oldSecondaries);
// Block until the primary finishes drain mode.
assert.eq(stepUpResults.newPrimary, rst.getPrimary());
// Wait until the new primary completes the transition to primary and writes a no-op.
if (isJsonLog(stepUpResults.newPrimary)) {
checkLog.contains(stepUpResults.newPrimary, "Transition to primary complete");
} else {
checkLog.contains(stepUpResults.newPrimary, "transition to primary complete");
}
let testNodeReplSetGetStatus =
assert.commandWorked(stepUpResults.newPrimary.adminCommand({replSetGetStatus: 1}));
let testNodeServerStatus =
assert.commandWorked(stepUpResults.newPrimary.adminCommand({serverStatus: 1}));
// Check that metrics associated with catchup have been set correctly in both replSetGetStatus and
// serverStatus.
assert(testNodeReplSetGetStatus.electionCandidateMetrics.numCatchUpOps,
() => "Response should have an 'numCatchUpOps' field: " +
tojson(testNodeReplSetGetStatus.electionCandidateMetrics));
// numCatchUpOps should be 4 because the 'foo' collection is implicitly created during the 3
// inserts, and that's where the additional oplog entry comes from.
assert.eq(testNodeReplSetGetStatus.electionCandidateMetrics.numCatchUpOps, 4);
assert(testNodeServerStatus.electionMetrics.averageCatchUpOps,
() => "Response should have an 'averageCatchUpOps' field: " +
tojson(testNodeServerStatus.electionMetrics));
assert.eq(testNodeServerStatus.electionMetrics.averageCatchUpOps, 4);
// Step up another node temporarily.
const tempPrimary = rst.stepUp(rst.getSecondaries()[0]);
rst.awaitReplication();
// Step up the testNode and force it to catchup again.
stepUpResults = stopReplicationAndEnforceNewPrimaryToCatchUp(rst, testNode);
restartServerReplication(stepUpResults.oldSecondaries);
assert.eq(stepUpResults.newPrimary, rst.getPrimary());
if (isJsonLog(stepUpResults.newPrimary)) {
checkLog.contains(stepUpResults.newPrimary, "Transition to primary complete");
} else {
checkLog.contains(stepUpResults.newPrimary, "transition to primary complete");
}
rst.awaitReplication();
testNodeServerStatus =
assert.commandWorked(stepUpResults.newPrimary.adminCommand({serverStatus: 1}));
testNodeReplSetGetStatus =
assert.commandWorked(stepUpResults.newPrimary.adminCommand({replSetGetStatus: 1}));
// numCatchUpOps is now 3 due to the 'foo' collection already being created.
assert.eq(testNodeReplSetGetStatus.electionCandidateMetrics.numCatchUpOps, 3);
assert.eq(testNodeServerStatus.electionMetrics.numCatchUps, 2);
assert.eq(testNodeServerStatus.electionMetrics.averageCatchUpOps, 3.5);
rst.stopSet();
})();
|