summaryrefslogtreecommitdiff
path: root/jstests/replsets/replset1.js
blob: 7ce4610495e0460d2a284b461285e2e77a79b422 (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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
var ssl_options1;
var ssl_options2;
var ssl_name;
load("jstests/replsets/rslib.js");
load('jstests/replsets/libs/election_metrics.js');
var doTest = function(signal) {
    // Test basic replica set functionality.
    // -- Replication
    // -- Failover

    // Choose a name that is unique to the options specified.
    // This is important because we are depending on a fresh replicaSetMonitor for each run;
    // each differently-named replica set gets its own monitor.
    // n0 and n1 get the same SSL config since there are 3 nodes but only 2 different configs
    var replTest = new ReplSetTest({
        name: 'testSet' + ssl_name,
        nodes: {n0: ssl_options1, n1: ssl_options1, n2: ssl_options2}
    });

    // call startSet() to start each mongod in the replica set
    // this returns a list of nodes
    var nodes = replTest.startSet();

    // Call initiate() to send the replSetInitiate command
    // This will wait for initiation
    replTest.initiate();

    // Call getPrimary to return a reference to the node that's been
    // elected primary.
    var primary = replTest.getPrimary();

    // Check that both the 'called' and 'successful' fields of the 'electionTimeout' election reason
    // counter have been incremented in serverStatus.
    const primaryStatus = assert.commandWorked(primary.adminCommand({serverStatus: 1}));
    verifyServerStatusElectionReasonCounterValue(
        primaryStatus.electionMetrics, "electionTimeout", 1);

    // Ensure the primary logs an n-op to the oplog upon transitioning to primary.
    assert.gt(primary.getDB("local").oplog.rs.count({op: 'n', o: {msg: 'new primary'}}), 0);

    // Here's how you save something to primary
    primary.getDB("foo").foo.save({a: 1000});

    // This method will check the oplogs of the primary
    // and secondaries in the set and wait until the change has replicated.
    replTest.awaitReplication();

    var cppconn = new Mongo(replTest.getURL()).getDB("foo");
    assert.eq(1000, cppconn.foo.findOne().a, "cppconn 1");

    {
        // check c++ finding other servers
        var temp = replTest.getURL();
        temp = temp.substring(0, temp.lastIndexOf(","));
        temp = new Mongo(temp).getDB("foo");
        assert.eq(1000, temp.foo.findOne().a, "cppconn 1");
    }

    // Here's how to stop the primary node
    var primaryId = replTest.getNodeId(primary);
    replTest.stop(primaryId);

    // Now let's see who the new primary is:
    var newPrimary = replTest.getPrimary();

    // Is the new primary the same as the old primary?
    var newPrimaryId = replTest.getNodeId(newPrimary);

    assert(primaryId != newPrimaryId, "Old primary shouldn't be equal to new primary.");

    reconnect(cppconn);
    assert.eq(1000, cppconn.foo.findOne().a, "cppconn 2");

    // Now let's write some documents to the new primary
    var bulk = newPrimary.getDB("bar").bar.initializeUnorderedBulkOp();
    for (var i = 0; i < 1000; i++) {
        bulk.insert({a: i});
    }
    bulk.execute();

    // Here's how to restart the old primary node:
    var secondary = replTest.restart(primaryId);

    // Now, let's make sure that the old primary comes up as a secondary
    assert.soon(function() {
        var res = secondary.getDB("admin").runCommand({hello: 1});
        printjson(res);
        return res['ok'] == 1 && res['isWritablePrimary'] == false;
    });

    // And we need to make sure that the replset comes back up
    assert.soon(function() {
        var res = newPrimary.getDB("admin").runCommand({replSetGetStatus: 1});
        printjson(res);
        return res.myState == 1;
    });

    // And that both secondary nodes have all the updates
    newPrimary = replTest.getPrimary();
    assert.eq(1000, newPrimary.getDB("bar").runCommand({count: "bar"}).n, "assumption 2");
    replTest.awaitSecondaryNodes();
    replTest.awaitReplication();

    var secondaries = replTest.getSecondaries();
    assert(secondaries.length == 2, "Expected 2 secondaries but length was " + secondaries.length);
    secondaries.forEach(function(secondary) {
        secondary.setSecondaryOk();
        var count = secondary.getDB("bar").runCommand({count: "bar"});
        printjson(count);
        assert.eq(1000, count.n, "secondary count wrong: " + secondary);
    });

    // last error
    primary = replTest.getPrimary();
    secondaries = replTest.getSecondaries();

    var db = primary.getDB("foo");
    var t = db.foo;

    var ts = secondaries.map(function(z) {
        z.setSecondaryOk();
        return z.getDB("foo").foo;
    });

    t.save({a: 1000});
    t.createIndex({a: 1});
    replTest.awaitReplication();

    ts.forEach(function(z) {
        assert.eq(2, z.getIndexKeys().length, "A " + z.getMongo());
    });

    // Shut down the set and finish the test.
    replTest.stopSet(signal);
};

doTest(15);
print("replset1.js SUCCESS");