2015-04-30 20:01:57 -04:00
|
|
|
// Test that a rollback of collModding usePowerOf2Sizes and validator can be rolled back.
|
2015-11-19 14:01:59 -05:00
|
|
|
//
|
|
|
|
|
// 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 data, and upon restart will each look for a member to
|
|
|
|
|
// inital sync from, so no primary will be elected. This test induces such a scenario, so cannot be
|
|
|
|
|
// run on ephemeral storage engines.
|
|
|
|
|
// @tags: [requires_persistence]
|
2015-04-30 20:01:57 -04:00
|
|
|
(function() {
|
|
|
|
|
"use strict";
|
2014-05-21 10:45:56 -04:00
|
|
|
|
2015-04-30 20:01:57 -04:00
|
|
|
function getOptions(conn) {
|
|
|
|
|
return conn.getDB(name).foo.exists().options;
|
2014-05-21 10:45:56 -04:00
|
|
|
}
|
|
|
|
|
|
2015-04-30 20:01:57 -04:00
|
|
|
// Set up a set and grab things for later.
|
2014-05-21 10:45:56 -04:00
|
|
|
var name = "rollback_collMod_PowerOf2Sizes";
|
|
|
|
|
var replTest = new ReplSetTest({name: name, nodes: 3});
|
|
|
|
|
var nodes = replTest.nodeList();
|
|
|
|
|
var conns = replTest.startSet();
|
|
|
|
|
replTest.initiate({"_id": name,
|
|
|
|
|
"members": [
|
2014-12-02 15:43:13 -05:00
|
|
|
{ "_id": 0, "host": nodes[0] },
|
2014-05-21 10:45:56 -04:00
|
|
|
{ "_id": 1, "host": nodes[1] },
|
|
|
|
|
{ "_id": 2, "host": nodes[2], arbiterOnly: true}]
|
|
|
|
|
});
|
2015-04-30 20:01:57 -04:00
|
|
|
// Get master and do an initial write.
|
2015-11-25 11:20:43 -05:00
|
|
|
var master = replTest.getPrimary();
|
2014-12-02 15:43:13 -05:00
|
|
|
var a_conn = master;
|
|
|
|
|
var slaves = replTest.liveNodes.slaves;
|
|
|
|
|
var b_conn = slaves[0];
|
2014-05-21 10:45:56 -04:00
|
|
|
var AID = replTest.getNodeId(a_conn);
|
|
|
|
|
var BID = replTest.getNodeId(b_conn);
|
|
|
|
|
|
2015-05-11 11:04:31 -04:00
|
|
|
// Create collection with custom options.
|
2015-07-14 12:18:59 -04:00
|
|
|
var originalCollectionOptions = {flags: 0,
|
|
|
|
|
validator: {x: {$exists: 1}},
|
|
|
|
|
validationLevel: "moderate",
|
2015-07-28 11:31:58 -04:00
|
|
|
validationAction: "warn"};
|
2015-05-11 11:04:31 -04:00
|
|
|
assert.commandWorked(a_conn.getDB(name).createCollection('foo', originalCollectionOptions));
|
|
|
|
|
|
2014-05-21 10:45:56 -04:00
|
|
|
var options = {writeConcern: {w: 2, wtimeout: 60000}, upsert: true};
|
|
|
|
|
assert.writeOK(a_conn.getDB(name).foo.insert({x: 1}, options));
|
|
|
|
|
|
2015-05-11 11:04:31 -04:00
|
|
|
assert.eq(getOptions(a_conn), originalCollectionOptions);
|
|
|
|
|
assert.eq(getOptions(b_conn), originalCollectionOptions);
|
|
|
|
|
|
2015-04-30 20:01:57 -04:00
|
|
|
// Stop the slave so it never sees the collMod.
|
|
|
|
|
replTest.stop(BID);
|
2014-05-21 10:45:56 -04:00
|
|
|
|
2015-04-30 20:01:57 -04:00
|
|
|
// Run the collMod only on A.
|
|
|
|
|
assert.commandWorked(a_conn.getDB(name).runCommand({collMod: "foo",
|
|
|
|
|
usePowerOf2Sizes: false,
|
|
|
|
|
noPadding: true,
|
2015-07-14 12:46:19 -04:00
|
|
|
validator: {a: 1},
|
|
|
|
|
validationLevel: "moderate",
|
2015-07-28 11:31:58 -04:00
|
|
|
validationAction: "warn"}));
|
2015-07-14 12:18:59 -04:00
|
|
|
assert.eq(getOptions(a_conn), {flags: 2,
|
|
|
|
|
validator: {a: 1},
|
|
|
|
|
validationLevel: "moderate",
|
2015-07-28 11:31:58 -04:00
|
|
|
validationAction: "warn"});
|
2014-05-21 10:45:56 -04:00
|
|
|
|
2015-04-30 20:01:57 -04:00
|
|
|
// Shut down A and fail over to B.
|
|
|
|
|
replTest.stop(AID);
|
|
|
|
|
replTest.restart(BID);
|
2015-11-25 11:20:43 -05:00
|
|
|
master = replTest.getPrimary();
|
2015-04-30 20:01:57 -04:00
|
|
|
assert.eq(b_conn.host, master.host, "b_conn assumed to be master");
|
|
|
|
|
b_conn = master;
|
2014-05-21 10:45:56 -04:00
|
|
|
|
2015-04-30 20:01:57 -04:00
|
|
|
// Do a write on B so that A will have to roll back.
|
2014-05-21 10:45:56 -04:00
|
|
|
options = {writeConcern: {w: 1, wtimeout: 60000}, upsert: true};
|
2015-04-30 20:01:57 -04:00
|
|
|
assert.writeOK(b_conn.getDB(name).foo.insert({x: 2}, options));
|
2014-05-21 10:45:56 -04:00
|
|
|
|
2015-04-30 20:01:57 -04:00
|
|
|
// Restart A, which should rollback the collMod before becoming primary.
|
|
|
|
|
replTest.restart(AID);
|
|
|
|
|
try {
|
|
|
|
|
b_conn.adminCommand({replSetStepDown: 60, secondaryCatchUpPeriodSecs: 60});
|
|
|
|
|
}
|
|
|
|
|
catch (e) {
|
|
|
|
|
// Ignore network disconnect.
|
|
|
|
|
}
|
2015-12-10 10:21:51 -05:00
|
|
|
replTest.waitForState(a_conn, ReplSetTest.State.PRIMARY);
|
2015-05-11 11:04:31 -04:00
|
|
|
assert.eq(getOptions(a_conn), originalCollectionOptions);
|
2015-04-30 20:01:57 -04:00
|
|
|
}());
|