summaryrefslogtreecommitdiff
path: root/jstests/replsets/opcounters_repl.js
blob: 5bf31a1f5ee4935e999c08d112ac2b751135e28f (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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
/**
 * This test verifies that the "serverStatus.opcountersRepl" is incremented correctly on
 * secondary during steady-state replication. Additionally, it also verifies the
 * "serverStatus.opcounters" on primary to check if it exhibits the same behavior as
 * secondary.
 */

(function() {
"use strict";

const testName = "opcounters_repl";
const dbName = testName;
const rst = new ReplSetTest({name: testName, nodes: 2});
rst.startSet();
rst.initiate();

const primary = rst.getPrimary();
const primaryDB = primary.getDB(dbName);
const secondary = rst.getSecondary();

const collName = "coll";
const collNs = dbName + '.' + collName;
const primaryColl = primaryDB[collName];

function getOpCounters(node) {
    return assert.commandWorked(node.adminCommand({serverStatus: 1})).opcounters;
}

function getOpCountersRepl(node) {
    return assert.commandWorked(node.adminCommand({serverStatus: 1})).opcountersRepl;
}

function getOpCountersDiff(cmdFn) {
    // Get the counters before running cmdFn().
    const primaryOpCountersBefore = getOpCounters(primary);
    const secondaryOpCountersReplBefore = getOpCountersRepl(secondary);

    // Run the cmd.
    cmdFn();

    // Get the counters after running cmdFn().
    const primaryOpCountersAfter = getOpCounters(primary);
    const secondaryOpCountersReplAfter = getOpCountersRepl(secondary);

    // Calculate the diff
    let primaryDiff = {};
    let secondaryDiff = {};
    for (let key in primaryOpCountersBefore) {
        primaryDiff[key] = primaryOpCountersAfter[key] - primaryOpCountersBefore[key];
    }

    for (let key in secondaryOpCountersReplBefore) {
        secondaryDiff[key] = secondaryOpCountersReplAfter[key] - secondaryOpCountersReplBefore[key];
    }
    return {primary: primaryDiff, secondary: secondaryDiff};
}

// 1. Create collection.
let diff = getOpCountersDiff(() => {
    assert.commandWorked(primaryDB.createCollection(collName, {writeConcern: {w: 2}}));
});
// On primary, the command counter accounts for create command and for other internal
// commands like replSetUpdatePosition, replSetHeartbeat, serverStatus, etc.
assert.gte(diff.primary.command, 1);
assert.eq(diff.secondary.command, 1);

// 2. Insert a document.
diff = getOpCountersDiff(() => {
    assert.writeOK(primaryColl.insert({_id: 0}, {writeConcern: {w: 2}}));
});
assert.eq(diff.primary.insert, 1);
assert.eq(diff.secondary.insert, 1);

// 3. Update a document.
diff = getOpCountersDiff(() => {
    assert.writeOK(primaryColl.update({_id: 0}, {$set: {a: 1}}, {writeConcern: {w: 2}}));
});
assert.eq(diff.primary.update, 1);
assert.eq(diff.secondary.update, 1);

// 4. Delete a document.
diff = getOpCountersDiff(() => {
    assert.writeOK(primaryColl.remove({_id: 0}, {writeConcern: {w: 2}}));
});
assert.eq(diff.primary.delete, 1);
assert.eq(diff.secondary.delete, 1);

// 5. Atomic insert operation via applyOps cmd.
diff = getOpCountersDiff(() => {
    assert.commandWorked(primaryColl.runCommand(
        {applyOps: [{op: "i", ns: collNs, o: {_id: 1}}], writeConcern: {w: 2}}));
});
// On primary, the command counter accounts for applyOps command and for other internal
// commands like replSetUpdatePosition, replSetHeartbeat, serverStatus, etc.
assert.gte(diff.primary.command, 1);
assert.eq(diff.secondary.command, 0);
assert.eq(diff.primary.insert, 1);
assert.eq(diff.secondary.insert, 1);

rst.stopSet();
})();