summaryrefslogtreecommitdiff
path: root/jstests
diff options
context:
space:
mode:
Diffstat (limited to 'jstests')
-rw-r--r--jstests/auth/lib/commands_lib.js13
-rw-r--r--jstests/core/views/views_all_commands.js1
-rw-r--r--jstests/sharding/move_chunk_find_and_modify_with_write_retryability.js119
-rw-r--r--jstests/sharding/move_chunk_insert_with_write_retryability.js34
-rw-r--r--jstests/sharding/move_chunk_remove_with_write_retryability.js41
-rw-r--r--jstests/sharding/move_chunk_update_with_write_retryability.js44
-rw-r--r--jstests/sharding/move_chunk_with_session_helper.js49
-rw-r--r--jstests/sharding/write_transactions_during_migration.js84
8 files changed, 385 insertions, 0 deletions
diff --git a/jstests/auth/lib/commands_lib.js b/jstests/auth/lib/commands_lib.js
index 6717e17e64d..7cde9677e96 100644
--- a/jstests/auth/lib/commands_lib.js
+++ b/jstests/auth/lib/commands_lib.js
@@ -4454,6 +4454,19 @@ var authCommandsLib = {
command: {refreshSessionsInternal: []},
testcases: [{runOnDb: adminDbName, roles: {__system: 1}}],
},
+ {
+ testname: "_getNextSessionMods",
+ command: {_getNextSessionMods: "a-b"},
+ skipSharded: true,
+ testcases: [
+ {
+ runOnDb: adminDbName,
+ roles: {__system: 1},
+ privileges: [{resource: {cluster: true}, actions: ["internal"]}],
+ expectFail: true
+ },
+ ]
+ },
],
/************* SHARED TEST LOGIC ****************/
diff --git a/jstests/core/views/views_all_commands.js b/jstests/core/views/views_all_commands.js
index b9c2474bf69..02d68beabda 100644
--- a/jstests/core/views/views_all_commands.js
+++ b/jstests/core/views/views_all_commands.js
@@ -76,6 +76,7 @@
_configsvrShardCollection: {skip: isAnInternalCommand},
_configsvrSetFeatureCompatibilityVersion: {skip: isAnInternalCommand},
_configsvrUpdateZoneKeyRange: {skip: isAnInternalCommand},
+ _getNextSessionMods: {skip: isAnInternalCommand},
_getUserCacheGeneration: {skip: isAnInternalCommand},
_hashBSONElement: {skip: isAnInternalCommand},
_isSelf: {skip: isAnInternalCommand},
diff --git a/jstests/sharding/move_chunk_find_and_modify_with_write_retryability.js b/jstests/sharding/move_chunk_find_and_modify_with_write_retryability.js
new file mode 100644
index 00000000000..c06a4cfdc9c
--- /dev/null
+++ b/jstests/sharding/move_chunk_find_and_modify_with_write_retryability.js
@@ -0,0 +1,119 @@
+load("jstests/sharding/move_chunk_with_session_helper.js");
+
+(function() {
+
+ "use strict";
+
+ var checkFindAndModifyResult = function(expected, toCheck) {
+ assert.eq(expected.ok, toCheck.ok);
+ assert.eq(expected.value, toCheck.value);
+
+ // TODO: SERVER-30532: after adding upserted, just compare the entire lastErrorObject
+ var expectedLE = expected.lastErrorObject;
+ var toCheckLE = toCheck.lastErrorObject;
+
+ assert.neq(null, toCheckLE);
+ assert.eq(expected.updatedExisting, toCheck.updatedExisting);
+ assert.eq(expected.n, toCheck.n);
+ };
+
+ var lsid = UUID();
+ var tests = [
+ {
+ coll: 'findAndMod-upsert',
+ cmd: {
+ findAndModify: 'findAndMod-upsert',
+ query: {x: 60},
+ update: {$inc: {y: 1}},
+ new: true,
+ upsert: true,
+ lsid: {id: lsid},
+ txnNumber: NumberLong(37),
+ },
+ setup: function(coll) {},
+ checkRetryResult: function(result, retryResult) {
+ checkFindAndModifyResult(result, retryResult);
+ },
+ checkDocuments: function(coll) {
+ assert.eq(1, coll.findOne({x: 60}).y);
+ },
+ },
+ {
+ coll: 'findAndMod-update-preImage',
+ cmd: {
+ findAndModify: 'findAndMod-update-preImage',
+ query: {x: 60},
+ update: {$inc: {y: 1}},
+ new: false,
+ upsert: false,
+ lsid: {id: lsid},
+ txnNumber: NumberLong(38),
+ },
+ setup: function(coll) {
+ coll.insert({x: 60});
+ },
+ checkRetryResult: function(result, retryResult) {
+ checkFindAndModifyResult(result, retryResult);
+ },
+ checkDocuments: function(coll) {
+ assert.eq(1, coll.findOne({x: 60}).y);
+ },
+ },
+ {
+ coll: 'findAndMod-update-postImage',
+ cmd: {
+ findAndModify: 'findAndMod-update-postImage',
+ query: {x: 60},
+ update: {$inc: {y: 1}},
+ new: true,
+ upsert: false,
+ lsid: {id: lsid},
+ txnNumber: NumberLong(39),
+ },
+ setup: function(coll) {
+ coll.insert({x: 60});
+ },
+ checkRetryResult: function(result, retryResult) {
+ checkFindAndModifyResult(result, retryResult);
+ },
+ checkDocuments: function(coll) {
+ assert.eq(1, coll.findOne({x: 60}).y);
+ },
+ },
+ {
+ coll: 'findAndMod-delete',
+ cmd: {
+ findAndModify: 'findAndMod-delete',
+ query: {x: 10},
+ remove: true,
+ lsid: {id: lsid},
+ txnNumber: NumberLong(40),
+ },
+ setup: function(coll) {
+ var bulk = coll.initializeUnorderedBulkOp();
+ for (let i = 0; i < 10; i++) {
+ bulk.insert({x: 10});
+ }
+ assert.writeOK(bulk.execute());
+
+ },
+ checkRetryResult: function(result, retryResult) {
+ checkFindAndModifyResult(result, retryResult);
+ },
+ checkDocuments: function(coll) {
+ assert.eq(9, coll.find({x: 10}).itcount());
+ },
+ },
+ ];
+
+ var st = new ShardingTest({shards: {rs0: {nodes: 2}, rs1: {nodes: 2}}});
+ assert.commandWorked(st.s.adminCommand({enableSharding: 'test'}));
+ st.ensurePrimaryShard('test', st.shard0.shardName);
+
+ tests.forEach(function(test) {
+ testMoveChunkWithSession(
+ st, test.coll, test.cmd, test.setup, test.checkRetryResult, test.checkDocuments);
+ });
+
+ st.stop();
+})();
diff --git a/jstests/sharding/move_chunk_insert_with_write_retryability.js b/jstests/sharding/move_chunk_insert_with_write_retryability.js
new file mode 100644
index 00000000000..bdbdef47000
--- /dev/null
+++ b/jstests/sharding/move_chunk_insert_with_write_retryability.js
@@ -0,0 +1,34 @@
+load("jstests/sharding/move_chunk_with_session_helper.js");
+
+(function() {
+
+ "use strict";
+
+ var st = new ShardingTest({shards: {rs0: {nodes: 2}, rs1: {nodes: 2}}});
+ assert.commandWorked(st.s.adminCommand({enableSharding: 'test'}));
+ st.ensurePrimaryShard('test', st.shard0.shardName);
+
+ var coll = 'insert';
+ var cmd = {
+ insert: coll,
+ documents: [{x: 10}, {x: 30}],
+ ordered: false,
+ lsid: {id: UUID()},
+ txnNumber: NumberLong(34),
+ };
+ var setup = function() {};
+ var checkRetryResult = function(result, retryResult) {
+ assert.eq(result.ok, retryResult.ok);
+ assert.eq(result.n, retryResult.n);
+ assert.eq(result.writeErrors, retryResult.writeErrors);
+ assert.eq(result.writeConcernErrors, retryResult.writeConcernErrors);
+ };
+ var checkDocuments = function(coll) {
+ assert.eq(1, coll.find({x: 10}).itcount());
+ assert.eq(1, coll.find({x: 30}).itcount());
+ };
+
+ testMoveChunkWithSession(st, coll, cmd, setup, checkRetryResult, checkDocuments);
+
+ st.stop();
+})();
diff --git a/jstests/sharding/move_chunk_remove_with_write_retryability.js b/jstests/sharding/move_chunk_remove_with_write_retryability.js
new file mode 100644
index 00000000000..64d1f5d2dee
--- /dev/null
+++ b/jstests/sharding/move_chunk_remove_with_write_retryability.js
@@ -0,0 +1,41 @@
+load("jstests/sharding/move_chunk_with_session_helper.js");
+
+(function() {
+
+ "use strict";
+
+ var st = new ShardingTest({shards: {rs0: {nodes: 2}, rs1: {nodes: 2}}});
+ assert.commandWorked(st.s.adminCommand({enableSharding: 'test'}));
+ st.ensurePrimaryShard('test', st.shard0.shardName);
+
+ var coll = 'delete';
+ var cmd = {
+ delete: coll,
+ deletes: [{q: {x: 10}, limit: 1}, {q: {x: 20}, limit: 1}],
+ ordered: false,
+ lsid: {id: UUID()},
+ txnNumber: NumberLong(36),
+ };
+ var setup = function(coll) {
+ var bulk = coll.initializeUnorderedBulkOp();
+ for (let i = 0; i < 10; i++) {
+ bulk.insert({x: 10});
+ bulk.insert({x: 20});
+ }
+ assert.writeOK(bulk.execute());
+ };
+ var checkRetryResult = function(result, retryResult) {
+ assert.eq(result.ok, retryResult.ok);
+ assert.eq(result.n, retryResult.n);
+ assert.eq(result.writeErrors, retryResult.writeErrors);
+ assert.eq(result.writeConcernErrors, retryResult.writeConcernErrors);
+ };
+ var checkDocuments = function(coll) {
+ assert.eq(9, coll.find({x: 10}).itcount());
+ assert.eq(9, coll.find({x: 20}).itcount());
+ };
+
+ testMoveChunkWithSession(st, coll, cmd, setup, checkRetryResult, checkDocuments);
+
+ st.stop();
+})();
diff --git a/jstests/sharding/move_chunk_update_with_write_retryability.js b/jstests/sharding/move_chunk_update_with_write_retryability.js
new file mode 100644
index 00000000000..1f23db58782
--- /dev/null
+++ b/jstests/sharding/move_chunk_update_with_write_retryability.js
@@ -0,0 +1,44 @@
+load("jstests/sharding/move_chunk_with_session_helper.js");
+
+(function() {
+
+ "use strict";
+
+ var st = new ShardingTest({shards: {rs0: {nodes: 2}, rs1: {nodes: 2}}});
+ assert.commandWorked(st.s.adminCommand({enableSharding: 'test'}));
+ st.ensurePrimaryShard('test', st.shard0.shardName);
+
+ var coll = 'update';
+ var cmd = {
+ update: 'update',
+ updates: [
+ {q: {x: 10}, u: {$inc: {a: 1}}}, // in place
+ {q: {x: 20}, u: {$inc: {b: 1}}, upsert: true},
+ {q: {x: 30}, u: {x: 30, z: 1}} // replacement
+ ],
+ ordered: false,
+ lsid: {id: UUID()},
+ txnNumber: NumberLong(35),
+ };
+ var setup = function(coll) {
+ coll.insert({x: 10});
+ coll.insert({x: 30});
+ };
+ var checkRetryResult = function(result, retryResult) {
+ assert.eq(result.ok, retryResult.ok);
+ assert.eq(result.n, retryResult.n);
+ assert.eq(result.nModified, retryResult.nModified);
+ assert.eq(result.upserted, retryResult.upserted);
+ assert.eq(result.writeErrors, retryResult.writeErrors);
+ assert.eq(result.writeConcernErrors, retryResult.writeConcernErrors);
+ };
+ var checkDocuments = function(coll) {
+ assert.eq(1, coll.findOne({x: 10}).a);
+ assert.eq(1, coll.findOne({x: 20}).b);
+ assert.eq(1, coll.findOne({x: 30}).z);
+ };
+
+ testMoveChunkWithSession(st, coll, cmd, setup, checkRetryResult, checkDocuments);
+
+ st.stop();
+})();
diff --git a/jstests/sharding/move_chunk_with_session_helper.js b/jstests/sharding/move_chunk_with_session_helper.js
new file mode 100644
index 00000000000..a320af844ca
--- /dev/null
+++ b/jstests/sharding/move_chunk_with_session_helper.js
@@ -0,0 +1,49 @@
+load("jstests/replsets/rslib.js");
+
+/**
+ * High level test scenario:
+ * 1. Shard collection.
+ * 2. Perform writes.
+ * 3. Migrate only chunk to other shard.
+ * 4. Retry writes.
+ * 5. Step down primary and wait for new primary.
+ * 6. Retry writes.
+ * 7. Migrate only chunk back to original shard.
+ * 8. Retry writes.
+ */
+var testMoveChunkWithSession = function(
+ st, collName, cmdObj, setupFunc, checkRetryResultFunc, checkDocumentsFunc) {
+ var ns = 'test.' + collName;
+ var testDB = st.s.getDB('test');
+ var coll = testDB.getCollection(collName);
+
+ assert.commandWorked(st.s.adminCommand({shardCollection: ns, key: {x: 1}}));
+
+ setupFunc(coll);
+ var result = assert.commandWorked(testDB.runCommand(cmdObj));
+
+ assert.commandWorked(st.s.adminCommand({moveChunk: ns, find: {x: 0}, to: st.shard1.shardName}));
+
+ checkRetryResultFunc(result, assert.commandWorked(testDB.runCommand(cmdObj)));
+ checkDocumentsFunc(coll);
+
+ try {
+ st.rs1.getPrimary().adminCommand({replSetStepDown: 60, secondaryCatchUpPeriodSecs: 30});
+ } catch (excep) {
+ print('Expected exception due to step down: ' + tojson(excep));
+ }
+
+ st.rs1.awaitNodesAgreeOnPrimary();
+ awaitRSClientHosts(st.s, {host: st.rs1.getPrimary().host}, {ok: true, ismaster: true});
+
+ checkRetryResultFunc(result, assert.commandWorked(testDB.runCommand(cmdObj)));
+ checkDocumentsFunc(coll);
+
+ // Make sure that the other shard knows about the latest primary.
+ awaitRSClientHosts(
+ st.rs0.getPrimary(), {host: st.rs1.getPrimary().host}, {ok: true, ismaster: true});
+ assert.commandWorked(st.s.adminCommand({moveChunk: ns, find: {x: 0}, to: st.shard0.shardName}));
+
+ checkRetryResultFunc(result, assert.commandWorked(testDB.runCommand(cmdObj)));
+ checkDocumentsFunc(coll);
+};
diff --git a/jstests/sharding/write_transactions_during_migration.js b/jstests/sharding/write_transactions_during_migration.js
new file mode 100644
index 00000000000..7c52628e05e
--- /dev/null
+++ b/jstests/sharding/write_transactions_during_migration.js
@@ -0,0 +1,84 @@
+/**
+ * Tests that session information are properly transferred to the destination shard while
+ * new writes are being sent to the source shard.
+ */
+
+load('./jstests/libs/chunk_manipulation_util.js');
+
+/**
+ * Test outline:
+ * 1. Pause migration.
+ * 2. Perform writes and allow it to be capture via OpObserver
+ * 3. Unpause migration.
+ * 4. Retry writes and confirm that writes are not duplicated.
+ */
+(function() {
+
+ "use strict";
+
+ var staticMongod = MongoRunner.runMongod({}); // For startParallelOps.
+
+ var st = new ShardingTest({shards: {rs0: {nodes: 1}, rs1: {nodes: 1}}});
+ st.adminCommand({enableSharding: 'test'});
+ st.ensurePrimaryShard('test', st.shard0.shardName);
+ st.adminCommand({shardCollection: 'test.user', key: {x: 1}});
+
+ pauseMoveChunkAtStep(st.shard0, moveChunkStepNames.reachedSteadyState);
+ var joinMoveChunk =
+ moveChunkParallel(staticMongod, st.s.host, {x: 0}, null, 'test.user', st.shard1.shardName);
+
+ var insertCmd = {
+ insert: 'user',
+ documents: [{x: 10}, {x: 30}],
+ ordered: false,
+ lsid: {id: UUID()},
+ txnNumber: NumberLong(34),
+ };
+
+ var testDB = st.getDB('test');
+ var insertResult = assert.commandWorked(testDB.runCommand(insertCmd));
+
+ var findAndModCmd = {
+ findAndModify: 'user',
+ query: {x: 30},
+ update: {$inc: {y: 1}},
+ new: true,
+ upsert: true,
+ lsid: {id: UUID()},
+ txnNumber: NumberLong(37),
+ };
+
+ var findAndModifyResult = assert.commandWorked(testDB.runCommand(findAndModCmd));
+
+ unpauseMoveChunkAtStep(st.shard0, moveChunkStepNames.reachedSteadyState);
+ joinMoveChunk();
+
+ var insertRetryResult = assert.commandWorked(testDB.runCommand(insertCmd));
+
+ assert.eq(insertResult.ok, insertRetryResult.ok);
+ assert.eq(insertResult.n, insertRetryResult.n);
+ assert.eq(insertResult.writeErrors, insertRetryResult.writeErrors);
+ assert.eq(insertResult.writeConcernErrors, insertRetryResult.writeConcernErrors);
+
+ assert.eq(1, testDB.user.find({x: 10}).itcount());
+ assert.eq(1, testDB.user.find({x: 30}).itcount());
+
+ var findAndModifyRetryResult = assert.commandWorked(testDB.runCommand(findAndModCmd));
+
+ assert.eq(findAndModifyResult.ok, findAndModifyRetryResult.ok);
+ assert.eq(findAndModifyResult.value, findAndModifyRetryResult.value);
+
+ // TODO: SERVER-30532: after adding upserted, just compare the entire lastErrorObject
+ var expectedLE = findAndModifyResult.lastErrorObject;
+ var toCheckLE = findAndModifyRetryResult.lastErrorObject;
+
+ assert.neq(null, toCheckLE);
+ assert.eq(findAndModifyResult.updatedExisting, findAndModifyRetryResult.updatedExisting);
+ assert.eq(findAndModifyResult.n, findAndModifyRetryResult.n);
+
+ assert.eq(1, testDB.user.findOne({x: 30}).y);
+
+ st.stop();
+
+ MongoRunner.stopMongod(staticMongod);
+})();