summaryrefslogtreecommitdiff
path: root/jstests/multiVersion/w_majority_change.js
blob: 739bc8e5f21b699c6e9e076ff2891e7bf109bec0 (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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
// exemplify and test the difference in meaning of w: "majority" between 2.6 and 2.8

load("jstests/replsets/rslib.js");

(function() {
    "use strict";
    var newVersion = "latest";
    var oldVersion = "2.6";

    // this first 7-node configuration will consist of 4 arbiters, 2 voting, non-arbiter nodes,
    // and 1 non-voting, non-arbiter node
    var name = "write_concern_many_arbiters";
    var nodes = {n0: {binVersion: newVersion},
                 n1: {binVersion: newVersion},
                 n2: {binVersion: oldVersion},
                 n3: {binVersion: oldVersion},
                 n4: {binVersion: oldVersion},
                 n5: {binVersion: newVersion},
                 n6: {binVersion: newVersion}};

    var replTest = new ReplSetTest({name: name, nodes: nodes});
    nodes = replTest.startSet();
    var config = {_id: name,
                  version: 1,
                  members: [{_id:0, host: nodes[0].host, priority: 3, votes: 1},
                            {_id:1, host: nodes[1].host, priority: 0, votes: 0},
                            {_id:2, host: nodes[2].host, priority: 0, votes: 1},
                            {_id:3, host: nodes[3].host, votes: 1, arbiterOnly: true},
                            {_id:4, host: nodes[4].host, votes: 1, arbiterOnly: true},
                            {_id:5, host: nodes[5].host, votes: 1, arbiterOnly: true},
                            {_id:6, host: nodes[6].host, votes: 1, arbiterOnly: true},
                           ],
                  };
    replTest.initiate(config);

    var writeConcern = {writeConcern: {w: "majority", wtimeout: 9*1000}};
    var primary = replTest.getPrimary();
    primary.forceWriteMode("commands");
    assert.eq(primary.host, nodes[0].host, "2.8 node failed to become primary");

    // w: majority on node 0 (2.8) will need both voting, non-arbiter nodes in this configuration
    // take down one voting, non-arbiter node. fails because we are missing a voter
    replTest.stop(2);
    assert.writeError(primary.getDB(name).foo.insert({x: 1}, writeConcern));
    // bring it back
    replTest.restart(2);
    assert.writeOK(primary.getDB(name).foo.insert({x: 2}, writeConcern));
    // take down one non-voting, non-arbiter node. passes because the non-voter does not matter
    replTest.stop(1);
    assert.writeOK(primary.getDB(name).foo.insert({x: 3}, writeConcern));
    replTest.restart(1);

    // reconfig such that a 2.6 node (node 2) will be primary
    config.version++;
    config.members[0].priority = 0;
    config.members[2].priority = 3;

    reconfig(replTest, config, true);
    primary = replTest.getPrimary();
    assert.eq(primary.host, nodes[2].host, "2.6 node failed to become primary");
    primary.forceWriteMode("commands");

    // w: majority on 2.6 will need all non-arbiter nodes in this configuration
    // take down one voting, non-arbiter node. fails because all nodes are needed
    replTest.stop(0);
    assert.writeError(primary.getDB(name).foo.insert({x: 4}, writeConcern));
    // bring it back
    replTest.restart(0);
    assert.writeOK(primary.getDB(name).foo.insert({x: 5}, writeConcern));
    // take down one non-voting, non-arbiter node. fails because all nodes are needed
    replTest.stop(1);
    assert.writeError(primary.getDB(name).foo.insert({x: 6}, writeConcern));

    replTest.stopSet();

    // this second 7-node configuration will consist of 1 arbiter, 4 voting, non-arbiter nodes, and
    // 2 non-voting, non-arbiter nodes
    name = "write_concern_few_arbiters";
    nodes = {n0: {binVersion: newVersion},
             n1: {binVersion: newVersion},
             n2: {binVersion: oldVersion},
             n3: {binVersion: oldVersion},
             n4: {binVersion: oldVersion},
             n5: {binVersion: newVersion},
             n6: {binVersion: newVersion}};

    replTest = new ReplSetTest({name: name, nodes: nodes});
    nodes = replTest.startSet();
    config = {_id: name,
              version: 1,
              members: [{_id:0, host: nodes[0].host, priority: 3, votes: 1},
                        {_id:1, host: nodes[1].host, priority: 0, votes: 1},
                        {_id:2, host: nodes[2].host, priority: 0, votes: 1},
                        {_id:3, host: nodes[3].host, priority: 0, votes: 1},
                        {_id:4, host: nodes[4].host, priority: 0, votes: 0},
                        {_id:5, host: nodes[5].host, priority: 0, votes: 0},
                        {_id:6, host: nodes[6].host, votes: 1, arbiterOnly: true},
                       ],
              };
    replTest.initiate(config);

    var primary = replTest.getPrimary();
    primary.forceWriteMode("commands");
    assert.eq(primary.host, nodes[0].host, "2.8 node failed to become primary");

    // w: majority on node 0 (2.8) will need 3 voting, non-arbiter nodes in this configuration
    // take down both non-voting nodes. passes because non-voting nodes do not matter
    replTest.stop(5);
    replTest.stop(4);
    assert.writeOK(primary.getDB(name).foo.insert({x: 7}, writeConcern));
    // take down one voting node. passes because we still have sufficient voting nodes
    replTest.stop(3);
    assert.writeOK(primary.getDB(name).foo.insert({x: 8}, writeConcern));
    // take down another voting node. fails because we have insufficient voting nodes
    replTest.stop(2);
    assert.writeError(primary.getDB(name).foo.insert({x: 9}, writeConcern));
    // bring back both non-voting nodes. fails because non-voters still do not matter
    replTest.restart(5);
    replTest.restart(4);
    assert.writeError(primary.getDB(name).foo.insert({x: 10}, writeConcern));
    // bring back a voting node. passes because we have sufficient voting nodes
    replTest.restart(3);
    assert.writeOK(primary.getDB(name).foo.insert({x: 11}, writeConcern));
    replTest.restart(2);


    // reconfig such that a 2.6 node (node 2) will be primary
    config.version++;
    config.members[0].priority = 0;
    config.members[2].priority = 3;

    reconfig(replTest, config, true);
    primary = replTest.getPrimary();
    assert.eq(primary.host, nodes[2].host, "2.6 node failed to become primary");
    primary.forceWriteMode("commands");

    // w: majority on 2.6 will need 4 non-arbiter nodes in this configuration
    // take down both non-voting nodes. passes because there are still sufficient nodes
    replTest.stop(5);
    replTest.stop(4);
    assert.writeOK(primary.getDB(name).foo.insert({x: 12}, writeConcern));
    // take down one voting node. fails because there are insufficient nodes
    replTest.stop(3);
    assert.writeError(primary.getDB(name).foo.insert({x: 13}, writeConcern));
    // bring up both non-voting nodes and take down a voting one
    // passes because only number of nodes matters in 2.6, not voting like in 2.8
    replTest.restart(5);
    replTest.restart(4);
    replTest.stop(1);
    assert.writeOK(primary.getDB(name).foo.insert({x: 15}, writeConcern));

    replTest.stopSet();
}());