summaryrefslogtreecommitdiff
path: root/jstests/replsets/avg_num_catchup_ops.js
blob: 13bf84da5aa52e49ea6f1c89e159bdc8de3b273b (plain)
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
/**
 * 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();
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();
})();