summaryrefslogtreecommitdiff
path: root/jstests/sharding/transactions_snapshot_errors_subsequent_statements.js
diff options
context:
space:
mode:
Diffstat (limited to 'jstests/sharding/transactions_snapshot_errors_subsequent_statements.js')
-rw-r--r--jstests/sharding/transactions_snapshot_errors_subsequent_statements.js188
1 files changed, 93 insertions, 95 deletions
diff --git a/jstests/sharding/transactions_snapshot_errors_subsequent_statements.js b/jstests/sharding/transactions_snapshot_errors_subsequent_statements.js
index 27855d9bc1a..e83ef670708 100644
--- a/jstests/sharding/transactions_snapshot_errors_subsequent_statements.js
+++ b/jstests/sharding/transactions_snapshot_errors_subsequent_statements.js
@@ -7,116 +7,114 @@
//
// @tags: [requires_sharding, uses_transactions, uses_multi_shard_transaction]
(function() {
- "use strict";
-
- load("jstests/sharding/libs/sharded_transactions_helpers.js");
-
- const dbName = "test";
- const collName = "foo";
- const ns = dbName + '.' + collName;
-
- const kCommandTestCases = [
- {name: "aggregate", command: {aggregate: collName, pipeline: [], cursor: {}}},
- {name: "distinct", command: {distinct: collName, query: {}, key: "_id"}},
- {name: "find", command: {find: collName}},
- {
- // findAndModify can only target one shard, even in the two shard case.
- name: "findAndModify",
- command: {findAndModify: collName, query: {_id: 1}, update: {$set: {x: 1}}}
- },
- {name: "insert", command: {insert: collName, documents: [{_id: 1}, {_id: 11}]}},
- {
- name: "update",
- command: {
- update: collName,
- updates: [{q: {_id: 1}, u: {$set: {_id: 2}}}, {q: {_id: 11}, u: {$set: {_id: 12}}}]
- }
- },
- {
- name: "delete",
- command:
- {delete: collName, deletes: [{q: {_id: 2}, limit: 1}, {q: {_id: 12}, limit: 1}]}
- },
- // We cannot test killCursors because mongos discards the response from any killCursors
- // requests that may be sent to shards.
- ];
-
- function runTest(st, collName, errorCode, isSharded) {
- const session = st.s.startSession();
- const sessionDB = session.getDatabase(dbName);
-
- for (let commandTestCase of kCommandTestCases) {
- const commandName = commandTestCase.name;
- const commandBody = commandTestCase.command;
-
- if (isSharded && commandName === "distinct") {
- // Distinct isn't allowed on sharded collections in a multi-document transaction.
- print("Skipping distinct test case for sharded collections");
- continue;
- }
-
- // Successfully start a transaction on one shard.
- session.startTransaction({readConcern: {level: "snapshot"}});
- assert.commandWorked(sessionDB.runCommand({find: collName, filter: {_id: 15}}));
-
- // Verify the command must fail on a snapshot error from a subsequent statement.
- setFailCommandOnShards(st, {times: 1}, [commandName], errorCode, 1);
- const res = assert.commandFailedWithCode(sessionDB.runCommand(commandBody), errorCode);
- assert.eq(res.errorLabels, ["TransientTransactionError"]);
-
- assertNoSuchTransactionOnAllShards(
- st, session.getSessionId(), session.getTxnNumber_forTesting());
- assert.commandFailedWithCode(session.abortTransaction_forTesting(),
- ErrorCodes.NoSuchTransaction);
+"use strict";
+
+load("jstests/sharding/libs/sharded_transactions_helpers.js");
+
+const dbName = "test";
+const collName = "foo";
+const ns = dbName + '.' + collName;
+
+const kCommandTestCases = [
+ {name: "aggregate", command: {aggregate: collName, pipeline: [], cursor: {}}},
+ {name: "distinct", command: {distinct: collName, query: {}, key: "_id"}},
+ {name: "find", command: {find: collName}},
+ {
+ // findAndModify can only target one shard, even in the two shard case.
+ name: "findAndModify",
+ command: {findAndModify: collName, query: {_id: 1}, update: {$set: {x: 1}}}
+ },
+ {name: "insert", command: {insert: collName, documents: [{_id: 1}, {_id: 11}]}},
+ {
+ name: "update",
+ command: {
+ update: collName,
+ updates: [{q: {_id: 1}, u: {$set: {_id: 2}}}, {q: {_id: 11}, u: {$set: {_id: 12}}}]
}
+ },
+ {
+ name: "delete",
+ command: {delete: collName, deletes: [{q: {_id: 2}, limit: 1}, {q: {_id: 12}, limit: 1}]}
+ },
+ // We cannot test killCursors because mongos discards the response from any killCursors
+ // requests that may be sent to shards.
+];
+
+function runTest(st, collName, errorCode, isSharded) {
+ const session = st.s.startSession();
+ const sessionDB = session.getDatabase(dbName);
+
+ for (let commandTestCase of kCommandTestCases) {
+ const commandName = commandTestCase.name;
+ const commandBody = commandTestCase.command;
+
+ if (isSharded && commandName === "distinct") {
+ // Distinct isn't allowed on sharded collections in a multi-document transaction.
+ print("Skipping distinct test case for sharded collections");
+ continue;
+ }
+
+ // Successfully start a transaction on one shard.
+ session.startTransaction({readConcern: {level: "snapshot"}});
+ assert.commandWorked(sessionDB.runCommand({find: collName, filter: {_id: 15}}));
+
+ // Verify the command must fail on a snapshot error from a subsequent statement.
+ setFailCommandOnShards(st, {times: 1}, [commandName], errorCode, 1);
+ const res = assert.commandFailedWithCode(sessionDB.runCommand(commandBody), errorCode);
+ assert.eq(res.errorLabels, ["TransientTransactionError"]);
+
+ assertNoSuchTransactionOnAllShards(
+ st, session.getSessionId(), session.getTxnNumber_forTesting());
+ assert.commandFailedWithCode(session.abortTransaction_forTesting(),
+ ErrorCodes.NoSuchTransaction);
}
+}
- const st = new ShardingTest({shards: 2, mongos: 1, config: 1});
+const st = new ShardingTest({shards: 2, mongos: 1, config: 1});
- enableStaleVersionAndSnapshotRetriesWithinTransactions(st);
+enableStaleVersionAndSnapshotRetriesWithinTransactions(st);
- jsTestLog("Unsharded transaction");
+jsTestLog("Unsharded transaction");
- assert.writeOK(st.s.getDB(dbName)[collName].insert({_id: 5}, {writeConcern: {w: "majority"}}));
- st.ensurePrimaryShard(dbName, st.shard0.shardName);
+assert.writeOK(st.s.getDB(dbName)[collName].insert({_id: 5}, {writeConcern: {w: "majority"}}));
+st.ensurePrimaryShard(dbName, st.shard0.shardName);
- // Single shard case simulates the storage engine discarding an in-use snapshot.
- for (let errorCode of kSnapshotErrors) {
- runTest(st, collName, errorCode, false /* isSharded */);
- }
+// Single shard case simulates the storage engine discarding an in-use snapshot.
+for (let errorCode of kSnapshotErrors) {
+ runTest(st, collName, errorCode, false /* isSharded */);
+}
- assert.commandWorked(st.s.adminCommand({enableSharding: dbName}));
- st.ensurePrimaryShard(dbName, st.shard0.shardName);
- assert.commandWorked(st.s.adminCommand({shardCollection: ns, key: {_id: 1}}));
+assert.commandWorked(st.s.adminCommand({enableSharding: dbName}));
+st.ensurePrimaryShard(dbName, st.shard0.shardName);
+assert.commandWorked(st.s.adminCommand({shardCollection: ns, key: {_id: 1}}));
- // Set up 2 chunks, [minKey, 10), [10, maxKey), each with one document (includes the document
- // already inserted).
- assert.commandWorked(st.s.adminCommand({split: ns, middle: {_id: 10}}));
- assert.writeOK(st.s.getDB(dbName)[collName].insert({_id: 15}, {writeConcern: {w: "majority"}}));
+// Set up 2 chunks, [minKey, 10), [10, maxKey), each with one document (includes the document
+// already inserted).
+assert.commandWorked(st.s.adminCommand({split: ns, middle: {_id: 10}}));
+assert.writeOK(st.s.getDB(dbName)[collName].insert({_id: 15}, {writeConcern: {w: "majority"}}));
- jsTestLog("One shard transaction");
+jsTestLog("One shard transaction");
- assert.eq(2, st.s.getDB('config').chunks.count({ns: ns, shard: st.shard0.shardName}));
- assert.eq(0, st.s.getDB('config').chunks.count({ns: ns, shard: st.shard1.shardName}));
+assert.eq(2, st.s.getDB('config').chunks.count({ns: ns, shard: st.shard0.shardName}));
+assert.eq(0, st.s.getDB('config').chunks.count({ns: ns, shard: st.shard1.shardName}));
- for (let errorCode of kSnapshotErrors) {
- runTest(st, collName, errorCode, true /* isSharded */);
- }
+for (let errorCode of kSnapshotErrors) {
+ runTest(st, collName, errorCode, true /* isSharded */);
+}
- jsTestLog("Two shard transaction");
+jsTestLog("Two shard transaction");
- assert.commandWorked(
- st.s.adminCommand({moveChunk: ns, find: {_id: 15}, to: st.shard1.shardName}));
- assert.eq(1, st.s.getDB('config').chunks.count({ns: ns, shard: st.shard0.shardName}));
- assert.eq(1, st.s.getDB('config').chunks.count({ns: ns, shard: st.shard1.shardName}));
+assert.commandWorked(st.s.adminCommand({moveChunk: ns, find: {_id: 15}, to: st.shard1.shardName}));
+assert.eq(1, st.s.getDB('config').chunks.count({ns: ns, shard: st.shard0.shardName}));
+assert.eq(1, st.s.getDB('config').chunks.count({ns: ns, shard: st.shard1.shardName}));
- // Multi shard case simulates adding a new participant that can no longer support the already
- // chosen read timestamp.
- for (let errorCode of kSnapshotErrors) {
- runTest(st, collName, errorCode, true /* isSharded */);
- }
+// Multi shard case simulates adding a new participant that can no longer support the already
+// chosen read timestamp.
+for (let errorCode of kSnapshotErrors) {
+ runTest(st, collName, errorCode, true /* isSharded */);
+}
- disableStaleVersionAndSnapshotRetriesWithinTransactions(st);
+disableStaleVersionAndSnapshotRetriesWithinTransactions(st);
- st.stop();
+st.stop();
})();