diff options
Diffstat (limited to 'jstests/sharding/move_primary_clone_test.js')
-rw-r--r-- | jstests/sharding/move_primary_clone_test.js | 404 |
1 files changed, 199 insertions, 205 deletions
diff --git a/jstests/sharding/move_primary_clone_test.js b/jstests/sharding/move_primary_clone_test.js index 16401c2316b..81811e2e993 100644 --- a/jstests/sharding/move_primary_clone_test.js +++ b/jstests/sharding/move_primary_clone_test.js @@ -1,242 +1,236 @@ (function() { - 'use strict'; - - function sortByName(a, b) { - if (a.name < b.name) - return -1; - if (a.name > b.name) - return 1; - return 0; - } +'use strict'; - function getCollections(shard) { - var res = shard.getDB("test1").runCommand({listCollections: 1}); - assert.commandWorked(res); +function sortByName(a, b) { + if (a.name < b.name) + return -1; + if (a.name > b.name) + return 1; + return 0; +} + +function getCollections(shard) { + var res = shard.getDB("test1").runCommand({listCollections: 1}); + assert.commandWorked(res); + + var collections = res.cursor.firstBatch; - var collections = res.cursor.firstBatch; + // Sort collections by name. + collections.sort(sortByName); + assert.eq(collections.length, 2); - // Sort collections by name. - collections.sort(sortByName); - assert.eq(collections.length, 2); + return collections; +} + +function checkOptions(c, expectedOptions) { + assert.hasFields(c, ['options'], 'Missing options field for collection ' + c.name); + assert.hasFields( + c.options, expectedOptions, 'Missing expected option(s) for collection ' + c.name); +} + +function checkCollectionsCopiedCorrectly(fromShard, toShard, sharded, barUUID, fooUUID) { + var c1, c2; + [c1, c2] = getCollections(toShard); + + function checkName(c, expectedName) { + assert.eq( + c.name, expectedName, 'Expected collection to be ' + expectedName + ', got ' + c.name); + } - return collections; + function checkUUIDsEqual(c, expectedUUID) { + assert.hasFields(c, ['info'], 'Missing info field for collection ' + c.name); + assert.hasFields(c.info, ['uuid'], 'Missing uuid field for collection ' + c.name); + assert.eq(c.info.uuid, expectedUUID, 'Incorrect uuid for collection ' + c.name); } - function checkOptions(c, expectedOptions) { - assert.hasFields(c, ['options'], 'Missing options field for collection ' + c.name); - assert.hasFields( - c.options, expectedOptions, 'Missing expected option(s) for collection ' + c.name); + function checkUUIDsNotEqual(c, originalUUID) { + assert.hasFields(c, ['info'], 'Missing info field for collection ' + c.name); + assert.hasFields(c.info, ['uuid'], 'Missing uuid field for collection ' + c.name); + assert.neq(c.info.uuid, + originalUUID, + 'UUID for ' + c.name + + ' should be different than the original collection but is the same'); } - function checkCollectionsCopiedCorrectly(fromShard, toShard, sharded, barUUID, fooUUID) { - var c1, c2; - [c1, c2] = getCollections(toShard); - - function checkName(c, expectedName) { - assert.eq(c.name, - expectedName, - 'Expected collection to be ' + expectedName + ', got ' + c.name); - } - - function checkUUIDsEqual(c, expectedUUID) { - assert.hasFields(c, ['info'], 'Missing info field for collection ' + c.name); - assert.hasFields(c.info, ['uuid'], 'Missing uuid field for collection ' + c.name); - assert.eq(c.info.uuid, expectedUUID, 'Incorrect uuid for collection ' + c.name); - } - - function checkUUIDsNotEqual(c, originalUUID) { - assert.hasFields(c, ['info'], 'Missing info field for collection ' + c.name); - assert.hasFields(c.info, ['uuid'], 'Missing uuid field for collection ' + c.name); - assert.neq(c.info.uuid, - originalUUID, - 'UUID for ' + c.name + - ' should be different than the original collection but is the same'); - } - - function checkIndexes(collName, expectedIndexes) { - var res = toShard.getDB('test1').runCommand({listIndexes: collName}); - assert.commandWorked(res, 'Failed to get indexes for collection ' + collName); - var indexes = res.cursor.firstBatch; - indexes.sort(sortByName); - - assert.eq(indexes.length, 2); - - indexes.forEach((index, i) => { - var expected; - if (i == 0) { - expected = {name: "_id_", key: {_id: 1}}; - } else { - expected = expectedIndexes[i - 1]; - } - Object.keys(expected).forEach(k => { - assert.eq(index[k], expected[k]); - }); + function checkIndexes(collName, expectedIndexes) { + var res = toShard.getDB('test1').runCommand({listIndexes: collName}); + assert.commandWorked(res, 'Failed to get indexes for collection ' + collName); + var indexes = res.cursor.firstBatch; + indexes.sort(sortByName); + + assert.eq(indexes.length, 2); + + indexes.forEach((index, i) => { + var expected; + if (i == 0) { + expected = {name: "_id_", key: {_id: 1}}; + } else { + expected = expectedIndexes[i - 1]; + } + Object.keys(expected).forEach(k => { + assert.eq(index[k], expected[k]); }); - } - - function checkCount(shard, collName, count) { - var res = shard.getDB('test1').runCommand({count: collName}); - assert.commandWorked(res); - assert.eq(res.n, count); - } - - checkName(c1, 'bar'); - checkName(c2, 'foo'); - checkOptions(c1, Object.keys(barOptions)); - checkIndexes('bar', barIndexes); - checkOptions(c2, Object.keys(fooOptions)); - checkIndexes('foo', fooIndexes); - - if (sharded) { - checkCount(fromShard, 'foo', 3); - checkCount(fromShard, 'bar', 3); - checkCount(toShard, 'foo', 0); - checkCount(toShard, 'bar', 0); - - // UUIDs should be the same as the original - checkUUIDsEqual(c1, barUUID); - checkUUIDsEqual(c2, fooUUID); - } else { - checkCount(toShard, 'foo', 3); - checkCount(toShard, 'bar', 3); - checkCount(fromShard, 'foo', 0); - checkCount(fromShard, 'bar', 0); - - // UUIDs should not be the same as the original - checkUUIDsNotEqual(c1, barUUID); - checkUUIDsNotEqual(c2, fooUUID); - } + }); } - function createCollections(sharded) { - assert.commandWorked(st.getDB('test1').runCommand({dropDatabase: 1})); - var db = st.getDB('test1'); + function checkCount(shard, collName, count) { + var res = shard.getDB('test1').runCommand({count: collName}); + assert.commandWorked(res); + assert.eq(res.n, count); + } - assert.commandWorked(db.createCollection('foo', fooOptions)); - assert.commandWorked(db.createCollection('bar', barOptions)); + checkName(c1, 'bar'); + checkName(c2, 'foo'); + checkOptions(c1, Object.keys(barOptions)); + checkIndexes('bar', barIndexes); + checkOptions(c2, Object.keys(fooOptions)); + checkIndexes('foo', fooIndexes); + + if (sharded) { + checkCount(fromShard, 'foo', 3); + checkCount(fromShard, 'bar', 3); + checkCount(toShard, 'foo', 0); + checkCount(toShard, 'bar', 0); + + // UUIDs should be the same as the original + checkUUIDsEqual(c1, barUUID); + checkUUIDsEqual(c2, fooUUID); + } else { + checkCount(toShard, 'foo', 3); + checkCount(toShard, 'bar', 3); + checkCount(fromShard, 'foo', 0); + checkCount(fromShard, 'bar', 0); + + // UUIDs should not be the same as the original + checkUUIDsNotEqual(c1, barUUID); + checkUUIDsNotEqual(c2, fooUUID); + } +} - for (let i = 0; i < 3; i++) { - assert.writeOK(db.foo.insert({a: i})); - assert.writeOK(db.bar.insert({a: i})); - } - assert.eq(3, db.foo.count()); - assert.eq(3, db.bar.count()); +function createCollections(sharded) { + assert.commandWorked(st.getDB('test1').runCommand({dropDatabase: 1})); + var db = st.getDB('test1'); - assert.commandWorked(db.runCommand({createIndexes: 'foo', indexes: fooIndexes})); - assert.commandWorked(db.runCommand({createIndexes: 'bar', indexes: barIndexes})); + assert.commandWorked(db.createCollection('foo', fooOptions)); + assert.commandWorked(db.createCollection('bar', barOptions)); - if (sharded) { - assert.commandWorked(db.adminCommand({enableSharding: 'test1'})); - assert.commandWorked(db.adminCommand({shardCollection: 'test1.foo', key: {_id: 1}})); - assert.commandWorked(db.adminCommand({shardCollection: 'test1.bar', key: {_id: 1}})); - } + for (let i = 0; i < 3; i++) { + assert.writeOK(db.foo.insert({a: i})); + assert.writeOK(db.bar.insert({a: i})); } + assert.eq(3, db.foo.count()); + assert.eq(3, db.bar.count()); - function movePrimaryWithFailpoint(sharded) { - var db = st.getDB('test1'); - createCollections(sharded); - - var fromShard = st.getPrimaryShard('test1'); - var toShard = st.getOther(fromShard); - - assert.eq( - 3, fromShard.getDB("test1").foo.count(), "from shard doesn't have data before move"); - assert.eq(0, toShard.getDB("test1").foo.count(), "to shard has data before move"); - assert.eq( - 3, fromShard.getDB("test1").bar.count(), "from shard doesn't have data before move"); - assert.eq(0, toShard.getDB("test1").bar.count(), "to shard has data before move"); + assert.commandWorked(db.runCommand({createIndexes: 'foo', indexes: fooIndexes})); + assert.commandWorked(db.runCommand({createIndexes: 'bar', indexes: barIndexes})); - var listCollsFrom = fromShard.getDB("test1").runCommand({listCollections: 1}); - var fromColls = listCollsFrom.cursor.firstBatch; - fromColls.sort(sortByName); - var baruuid = fromColls[0].info.uuid; - var foouuid = fromColls[1].info.uuid; + if (sharded) { + assert.commandWorked(db.adminCommand({enableSharding: 'test1'})); + assert.commandWorked(db.adminCommand({shardCollection: 'test1.foo', key: {_id: 1}})); + assert.commandWorked(db.adminCommand({shardCollection: 'test1.bar', key: {_id: 1}})); + } +} - assert.commandWorked(toShard.getDB("admin").runCommand( - {configureFailPoint: 'movePrimaryFailPoint', mode: 'alwaysOn'})); +function movePrimaryWithFailpoint(sharded) { + var db = st.getDB('test1'); + createCollections(sharded); - // Failpoint will cause movePrimary to fail after the first collection has been copied over - assert.commandFailed(st.s0.adminCommand({movePrimary: "test1", to: toShard.name})); + var fromShard = st.getPrimaryShard('test1'); + var toShard = st.getOther(fromShard); - assert.commandWorked(toShard.getDB("admin").runCommand( - {configureFailPoint: 'movePrimaryFailPoint', mode: 'off'})); - - if (sharded) { - // If the collections are sharded, the UUID of the collection on the donor should be - // copied over and the options should be the same so retrying the move should succeed. - assert.commandWorked(st.s0.adminCommand({movePrimary: "test1", to: toShard.name})); - checkCollectionsCopiedCorrectly(fromShard, toShard, sharded, baruuid, foouuid); - - // Now change an option on the toShard, and verify that calling clone again succeeds - // when the options don't match. - assert.commandWorked( - toShard.getDB('test1').runCommand({collMod: 'bar', validationLevel: 'moderate'})); - assert.commandWorked(st.s0.adminCommand({movePrimary: "test1", to: fromShard.name})); - - // Assert that the fromShard does not have the new options, but the toShard does - let barOnToShard = getCollections(toShard)[0]; - checkOptions( - barOnToShard, - Object.keys( - {validator: {$jsonSchema: {required: ['a']}}, validationLevel: "moderate"})); - let barOnFromShard = getCollections(fromShard)[0]; - checkOptions(barOnFromShard, Object.keys(barOptions)); - - // The docs should still be on the original primary shard (fromShard). - checkCollectionsCopiedCorrectly(fromShard, toShard, sharded, baruuid, foouuid); - - // Now drop and recreate the collection on the toShard. The collection should now have - // a different UUID, so we should fail on movePrimary. - assert.commandWorked(toShard.getDB("test1").runCommand({drop: "bar"})); - assert.commandWorked(toShard.getDB("test1").bar.insert({"x": 1})); - - assert.commandFailedWithCode( - st.s0.adminCommand({movePrimary: "test1", to: toShard.name}), - ErrorCodes.InvalidOptions); - } else { - // If the collections are unsharded, we should fail when any collections being copied - // exist on the target shard. - assert.commandFailed(st.s0.adminCommand({movePrimary: "test1", to: toShard.name})); - } - } + assert.eq(3, fromShard.getDB("test1").foo.count(), "from shard doesn't have data before move"); + assert.eq(0, toShard.getDB("test1").foo.count(), "to shard has data before move"); + assert.eq(3, fromShard.getDB("test1").bar.count(), "from shard doesn't have data before move"); + assert.eq(0, toShard.getDB("test1").bar.count(), "to shard has data before move"); - function movePrimaryNoFailpoint(sharded) { - var db = st.getDB('test1'); - createCollections(sharded); + var listCollsFrom = fromShard.getDB("test1").runCommand({listCollections: 1}); + var fromColls = listCollsFrom.cursor.firstBatch; + fromColls.sort(sortByName); + var baruuid = fromColls[0].info.uuid; + var foouuid = fromColls[1].info.uuid; - var fromShard = st.getPrimaryShard('test1'); - var toShard = st.getOther(fromShard); + assert.commandWorked(toShard.getDB("admin").runCommand( + {configureFailPoint: 'movePrimaryFailPoint', mode: 'alwaysOn'})); - assert.eq( - 3, fromShard.getDB("test1").foo.count(), "from shard doesn't have data before move"); - assert.eq(0, toShard.getDB("test1").foo.count(), "to shard has data before move"); - assert.eq( - 3, fromShard.getDB("test1").bar.count(), "from shard doesn't have data before move"); - assert.eq(0, toShard.getDB("test1").bar.count(), "to shard has data before move"); + // Failpoint will cause movePrimary to fail after the first collection has been copied over + assert.commandFailed(st.s0.adminCommand({movePrimary: "test1", to: toShard.name})); - var listCollsFrom = fromShard.getDB("test1").runCommand({listCollections: 1}); - var fromColls = listCollsFrom.cursor.firstBatch; - fromColls.sort(sortByName); - var baruuid = fromColls[0].info.uuid; - var foouuid = fromColls[1].info.uuid; + assert.commandWorked(toShard.getDB("admin").runCommand( + {configureFailPoint: 'movePrimaryFailPoint', mode: 'off'})); + if (sharded) { + // If the collections are sharded, the UUID of the collection on the donor should be + // copied over and the options should be the same so retrying the move should succeed. assert.commandWorked(st.s0.adminCommand({movePrimary: "test1", to: toShard.name})); + checkCollectionsCopiedCorrectly(fromShard, toShard, sharded, baruuid, foouuid); + // Now change an option on the toShard, and verify that calling clone again succeeds + // when the options don't match. + assert.commandWorked( + toShard.getDB('test1').runCommand({collMod: 'bar', validationLevel: 'moderate'})); + assert.commandWorked(st.s0.adminCommand({movePrimary: "test1", to: fromShard.name})); + + // Assert that the fromShard does not have the new options, but the toShard does + let barOnToShard = getCollections(toShard)[0]; + checkOptions( + barOnToShard, + Object.keys( + {validator: {$jsonSchema: {required: ['a']}}, validationLevel: "moderate"})); + let barOnFromShard = getCollections(fromShard)[0]; + checkOptions(barOnFromShard, Object.keys(barOptions)); + + // The docs should still be on the original primary shard (fromShard). checkCollectionsCopiedCorrectly(fromShard, toShard, sharded, baruuid, foouuid); + + // Now drop and recreate the collection on the toShard. The collection should now have + // a different UUID, so we should fail on movePrimary. + assert.commandWorked(toShard.getDB("test1").runCommand({drop: "bar"})); + assert.commandWorked(toShard.getDB("test1").bar.insert({"x": 1})); + + assert.commandFailedWithCode(st.s0.adminCommand({movePrimary: "test1", to: toShard.name}), + ErrorCodes.InvalidOptions); + } else { + // If the collections are unsharded, we should fail when any collections being copied + // exist on the target shard. + assert.commandFailed(st.s0.adminCommand({movePrimary: "test1", to: toShard.name})); } +} + +function movePrimaryNoFailpoint(sharded) { + var db = st.getDB('test1'); + createCollections(sharded); + + var fromShard = st.getPrimaryShard('test1'); + var toShard = st.getOther(fromShard); + + assert.eq(3, fromShard.getDB("test1").foo.count(), "from shard doesn't have data before move"); + assert.eq(0, toShard.getDB("test1").foo.count(), "to shard has data before move"); + assert.eq(3, fromShard.getDB("test1").bar.count(), "from shard doesn't have data before move"); + assert.eq(0, toShard.getDB("test1").bar.count(), "to shard has data before move"); + + var listCollsFrom = fromShard.getDB("test1").runCommand({listCollections: 1}); + var fromColls = listCollsFrom.cursor.firstBatch; + fromColls.sort(sortByName); + var baruuid = fromColls[0].info.uuid; + var foouuid = fromColls[1].info.uuid; + + assert.commandWorked(st.s0.adminCommand({movePrimary: "test1", to: toShard.name})); + + checkCollectionsCopiedCorrectly(fromShard, toShard, sharded, baruuid, foouuid); +} - var st = new ShardingTest({shards: 2}); +var st = new ShardingTest({shards: 2}); - var fooOptions = {validationLevel: "off"}; - var barOptions = {validator: {$jsonSchema: {required: ['a']}}}; +var fooOptions = {validationLevel: "off"}; +var barOptions = {validator: {$jsonSchema: {required: ['a']}}}; - var fooIndexes = [{key: {a: 1}, name: 'index1', expireAfterSeconds: 5000}]; - var barIndexes = [{key: {a: -1}, name: 'index2'}]; +var fooIndexes = [{key: {a: 1}, name: 'index1', expireAfterSeconds: 5000}]; +var barIndexes = [{key: {a: -1}, name: 'index2'}]; - movePrimaryWithFailpoint(true); - movePrimaryWithFailpoint(false); - movePrimaryNoFailpoint(true); - movePrimaryNoFailpoint(false); +movePrimaryWithFailpoint(true); +movePrimaryWithFailpoint(false); +movePrimaryNoFailpoint(true); +movePrimaryNoFailpoint(false); - st.stop(); +st.stop(); })(); |