summaryrefslogtreecommitdiff
path: root/jstests
diff options
context:
space:
mode:
authormatt dannenberg <matt.dannenberg@10gen.com>2014-12-04 10:43:28 -0500
committermatt dannenberg <matt.dannenberg@10gen.com>2014-12-05 11:07:52 -0500
commitc86ef5ad3af94413e7702bd8f294a7ee89c38f80 (patch)
tree63860804d03ec2a6c6b96a0a08955a05c723904c /jstests
parent36778ab33fbbbfc155ed607cb2039efc51400dad (diff)
downloadmongo-c86ef5ad3af94413e7702bd8f294a7ee89c38f80.tar.gz
SERVER-16442 test difference in meaning of w: majority in mixed mode replicasets
Diffstat (limited to 'jstests')
-rw-r--r--jstests/multiVersion/w_majority_change.js153
-rw-r--r--jstests/replsets/rslib.js4
2 files changed, 155 insertions, 2 deletions
diff --git a/jstests/multiVersion/w_majority_change.js b/jstests/multiVersion/w_majority_change.js
new file mode 100644
index 00000000000..739bc8e5f21
--- /dev/null
+++ b/jstests/multiVersion/w_majority_change.js
@@ -0,0 +1,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();
+}());
diff --git a/jstests/replsets/rslib.js b/jstests/replsets/rslib.js
index f926640e2c5..bb3b8374738 100644
--- a/jstests/replsets/rslib.js
+++ b/jstests/replsets/rslib.js
@@ -100,13 +100,13 @@ waitForAllMembers = function(master, timeout) {
print( "All members are now in state PRIMARY, SECONDARY, or ARBITER" );
};
-reconfig = function(rs, config) {
+reconfig = function(rs, config, force) {
"use strict";
var admin = rs.getMaster().getDB("admin");
var e;
var master;
try {
- assert.commandWorked(admin.runCommand({replSetReconfig : config}));
+ assert.commandWorked(admin.runCommand({replSetReconfig: config, force: force}));
}
catch (e) {
if (tojson(e).indexOf( "error doing query: failed" ) < 0) {