summaryrefslogtreecommitdiff
path: root/jstests/replsets/restore_term.js
blob: 1eabd276c83a1ab082c1133de2fba2ae37d802e1 (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
load("jstests/replsets/rslib.js");

// Tests that the replica set's term increases once per election, and persists across a restart of
// the entire set.
//
// If all data-bearing nodes in a replica set are using an ephemeral storage engine, the set will
// not be able to survive a scenario where all data-bearing nodes are down simultaneously. In such a
// scenario, none of the members will have any replica set configuration document after a restart,
// so cannot elect a primary. This test induces such a scenario, so cannot be run on ephemeral
// storage engines.
// @tags: [requires_persistence]
(function() {
    "use strict";

    function getCurrentTerm(primary) {
        var res = primary.adminCommand({replSetGetStatus: 1});
        assert.commandWorked(res);
        return res.term;
    }

    var name = "restore_term";
    var rst = new ReplSetTest({name: name, nodes: 2});

    rst.startSet();
    rst.initiate();
    rst.awaitSecondaryNodes();

    var primary = rst.getPrimary();
    var primaryColl = primary.getDB("test").coll;

    // Current term may be greater than 1 if election race happens.
    var firstSuccessfulTerm = getCurrentTerm(primary);
    assert.gte(firstSuccessfulTerm, 1);
    assert.writeOK(primaryColl.insert({x: 1}, {writeConcern: {w: "majority"}}));
    assert.eq(getCurrentTerm(primary), firstSuccessfulTerm);

    // Check that the insert op has the initial term.
    var latestOp = getLatestOp(primary);
    assert.eq(latestOp.op, "i");
    assert.eq(latestOp.t, firstSuccessfulTerm);

    // Step down to increase the term.
    try {
        var res = primary.adminCommand({replSetStepDown: 0});
    } catch (err) {
        print("caught: " + err + " on stepdown");
    }
    rst.awaitSecondaryNodes();
    // The secondary became the new primary now with a higher term.
    // Since there's only one secondary who may run for election, the new term is higher by 1.
    assert.eq(getCurrentTerm(rst.getPrimary()), firstSuccessfulTerm + 1);

    // Restart the replset and verify the term is the same.
    rst.stopSet(null /* signal */, true /* forRestart */);
    rst.startSet({restart: true});
    rst.awaitSecondaryNodes();
    primary = rst.getPrimary();

    assert.eq(primary.getDB("test").coll.find().itcount(), 1);
    // After restart, the new primary stands up with the newer term.
    assert.gte(getCurrentTerm(primary), firstSuccessfulTerm + 1);

    rst.stopSet();
})();