summaryrefslogtreecommitdiff
path: root/jstests
diff options
context:
space:
mode:
authorA. Jesse Jiryu Davis <jesse@mongodb.com>2021-05-04 15:21:10 -0400
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-05-04 21:50:07 +0000
commit4aa27885874b90e098c1225fccb10f4daa3b3d38 (patch)
tree6bc40bf2aaa6e275c1644114c2c80c7b09c7d257 /jstests
parent882fa82e21f412e6c5743e99d2d97861b28bd935 (diff)
downloadmongo-4aa27885874b90e098c1225fccb10f4daa3b3d38.tar.gz
SERVER-55614 Make API params optional for cmds in txns
Diffstat (limited to 'jstests')
-rw-r--r--jstests/core/txns/api_params_transaction.js88
-rw-r--r--jstests/core/txns/transaction_continuing_cmds_refuse_api_params.js68
-rw-r--r--jstests/noPassthrough/require_api_version.js25
-rw-r--r--jstests/sharding/libs/mongos_api_params_util.js78
4 files changed, 167 insertions, 92 deletions
diff --git a/jstests/core/txns/api_params_transaction.js b/jstests/core/txns/api_params_transaction.js
new file mode 100644
index 00000000000..a809f8a701c
--- /dev/null
+++ b/jstests/core/txns/api_params_transaction.js
@@ -0,0 +1,88 @@
+/**
+ * Tests passing API parameters into transaction-continuing commands.
+ * @tags: [uses_transactions, requires_fcv_47]
+ */
+
+(function() {
+"use strict";
+
+load("jstests/libs/fixture_helpers.js"); // For FixtureHelpers.isMongos().
+
+const dbName = jsTestName();
+const collName = "test";
+
+const testDB = db.getSiblingDB(dbName);
+const testColl = testDB.getCollection(collName);
+
+testColl.drop({writeConcern: {w: "majority"}});
+assert.commandWorked(
+ testDB.runCommand({create: testColl.getName(), writeConcern: {w: "majority"}}));
+
+const apiParamCombos = [
+ {},
+ {apiVersion: "1"},
+ {apiVersion: "1", apiDeprecationErrors: true},
+ {apiVersion: "1", apiDeprecationErrors: false},
+ {apiVersion: "1", apiStrict: true},
+ {apiVersion: "1", apiStrict: true, apiDeprecationErrors: true},
+ {apiVersion: "1", apiStrict: true, apiDeprecationErrors: false},
+ {apiVersion: "1", apiStrict: false},
+ {apiVersion: "1", apiStrict: false, apiDeprecationErrors: true},
+ {apiVersion: "1", apiStrict: false, apiDeprecationErrors: false}
+];
+
+function addApiParams(obj, params) {
+ return Object.assign(Object.assign({}, obj), params);
+}
+
+for (const txnInitiatingParams of apiParamCombos) {
+ for (const txnContinuingParams of apiParamCombos) {
+ for (const txnEndingCmdName of ["commitTransaction", "abortTransaction"]) {
+ // TODO (SERVER-56550): Remove "!txnContinuingParams.apiVersion".
+ const compatibleParams =
+ !txnContinuingParams.apiVersion || txnContinuingParams === txnInitiatingParams;
+ const session = db.getMongo().startSession();
+ const sessionDb = session.getDatabase(dbName);
+
+ session.startTransaction();
+ assert.commandWorked(sessionDb.runCommand(
+ addApiParams({insert: collName, documents: [{}, {}, {}]}, txnInitiatingParams)));
+
+ function checkCommand(db, command) {
+ const commandWithParams = addApiParams(command, txnContinuingParams);
+ jsTestLog(`Session ${session.getSessionId().id}, ` +
+ `initial params: ${tojson(txnInitiatingParams)}, ` +
+ `continuing params: ${tojson(txnContinuingParams)}, ` +
+ `compatible: ${tojson(compatibleParams)}`);
+ jsTestLog(`Command: ${tojson(commandWithParams)}`);
+ const reply = db.runCommand(commandWithParams);
+ jsTestLog(`Reply: ${tojson(reply)}`);
+
+ if (compatibleParams) {
+ assert.commandWorked(reply);
+ } else {
+ assert.commandFailedWithCode(reply, ErrorCodes.APIMismatchError);
+ }
+ }
+
+ /*
+ * Check "insert" with API params in a transaction.
+ */
+ checkCommand(sessionDb, {insert: collName, documents: [{}]});
+
+ /*
+ * Check "commitTransaction" or "abortTransaction".
+ */
+ let txnEndingCmd = {};
+ txnEndingCmd[txnEndingCmdName] = 1;
+ Object.assign(txnEndingCmd,
+ {txnNumber: session.getTxnNumber_forTesting(), autocommit: false});
+
+ checkCommand(session.getDatabase("admin"), txnEndingCmd);
+
+ // Clean up.
+ session.abortTransaction();
+ }
+ }
+}
+})();
diff --git a/jstests/core/txns/transaction_continuing_cmds_refuse_api_params.js b/jstests/core/txns/transaction_continuing_cmds_refuse_api_params.js
deleted file mode 100644
index 2eb11d1f4c3..00000000000
--- a/jstests/core/txns/transaction_continuing_cmds_refuse_api_params.js
+++ /dev/null
@@ -1,68 +0,0 @@
-/**
- * Tests that passing API parameters into transaction-continuing commands should fail.
- * @tags: [uses_transactions, requires_fcv_47]
- */
-
-(function() {
-"use strict";
-
-load("jstests/libs/fixture_helpers.js"); // For FixtureHelpers.isMongos().
-
-const errorCode = FixtureHelpers.isMongos(db) ? 4937701 : 4937700;
-const commitTxnWithApiVersionErrorCode = FixtureHelpers.isMongos(db) ? 4937702 : 4937700;
-
-const dbName = jsTestName();
-const collName = "test";
-
-const testDB = db.getSiblingDB(dbName);
-const testColl = testDB.getCollection(collName);
-
-testColl.drop({writeConcern: {w: "majority"}});
-assert.commandWorked(
- testDB.runCommand({create: testColl.getName(), writeConcern: {w: "majority"}}));
-
-const session = db.getMongo().startSession();
-const sessionAdminDB = session.getDatabase("admin");
-const sessionDB = session.getDatabase(dbName);
-const sessionColl = sessionDB.getCollection(collName);
-
-const doc = {
- x: 1
-};
-
-session.startTransaction();
-
-// Verify that the transaction-initiating command is allowed to specify an apiVersion.
-assert.commandWorked(sessionColl.runCommand({insert: collName, documents: [doc], apiVersion: "1"}));
-
-// Verify that any transaction-continuing commands cannot specify API parameters.
-assert.commandFailedWithCode(
- sessionColl.runCommand({insert: collName, documents: [doc], apiVersion: "1"}), errorCode);
-assert.commandFailedWithCode(
- sessionColl.runCommand({insert: collName, documents: [doc], apiVersion: "1", apiStrict: false}),
- errorCode);
-assert.commandFailedWithCode(
- sessionColl.runCommand(
- {insert: collName, documents: [doc], apiVersion: "1", apiDeprecationErrors: false}),
- errorCode);
-let reply = sessionAdminDB.runCommand({
- commitTransaction: 1,
- txnNumber: session.getTxnNumber_forTesting(),
- autocommit: false,
- apiVersion: "1"
-});
-assert.commandFailedWithCode(reply, commitTxnWithApiVersionErrorCode);
-reply = sessionAdminDB.runCommand({
- abortTransaction: 1,
- txnNumber: session.getTxnNumber_forTesting(),
- autocommit: false,
- apiVersion: "1"
-});
-assert.commandFailedWithCode(reply, errorCode);
-
-// Transaction-continuing commands without API parameters are allowed.
-assert.commandWorked(sessionColl.runCommand({insert: collName, documents: [doc]}));
-
-assert.commandWorked(session.abortTransaction_forTesting());
-session.endSession();
-})();
diff --git a/jstests/noPassthrough/require_api_version.js b/jstests/noPassthrough/require_api_version.js
index eefd34f21e0..2f496256897 100644
--- a/jstests/noPassthrough/require_api_version.js
+++ b/jstests/noPassthrough/require_api_version.js
@@ -47,8 +47,9 @@ function runTest(db, supportsTransctions, isMongos, writeConcern = {}, secondari
if (supportsTransctions) {
/*
- * Transaction-starting commands must have apiVersion, transaction-continuing commands must
- * not.
+ * Transaction-starting commands must have apiVersion, transaction-continuing commands may.
+ *
+ * TODO (SERVER-56550): Test that transaction-continuing commands fail *without* API params.
*/
const session = db.getMongo().startSession({causalConsistency: false});
const sessionDb = session.getDatabase(db.getName());
@@ -76,16 +77,8 @@ function runTest(db, supportsTransctions, isMongos, writeConcern = {}, secondari
stmtId: NumberInt(2),
autocommit: false
}));
- const commitTxnWithApiVersionErrorCode = isMongos ? 4937702 : 4937700;
- assert.commandFailedWithCode(sessionDb.runCommand({
- commitTransaction: 1,
- apiVersion: "1",
- txnNumber: NumberLong(0),
- autocommit: false
- }),
- commitTxnWithApiVersionErrorCode);
assert.commandWorked(sessionDb.runCommand(
- {commitTransaction: 1, txnNumber: NumberLong(0), autocommit: false}));
+ {commitTransaction: 1, apiVersion: "1", txnNumber: NumberLong(0), autocommit: false}));
// Start a new txn so we can test abortTransaction.
reply = sessionDb.runCommand({
@@ -97,16 +90,8 @@ function runTest(db, supportsTransctions, isMongos, writeConcern = {}, secondari
autocommit: false
});
assert.commandWorked(reply);
- const abortTxnWithApiVersionErrorCode = isMongos ? 4937701 : 4937700;
- assert.commandFailedWithCode(sessionDb.runCommand({
- abortTransaction: 1,
- apiVersion: "1",
- txnNumber: NumberLong(1),
- autocommit: false
- }),
- abortTxnWithApiVersionErrorCode);
assert.commandWorked(sessionDb.runCommand(
- {abortTransaction: 1, txnNumber: NumberLong(1), autocommit: false}));
+ {abortTransaction: 1, apiVersion: "1", txnNumber: NumberLong(1), autocommit: false}));
}
assert.commandWorked(
diff --git a/jstests/sharding/libs/mongos_api_params_util.js b/jstests/sharding/libs/mongos_api_params_util.js
index 8d396fae984..34e28f34d8b 100644
--- a/jstests/sharding/libs/mongos_api_params_util.js
+++ b/jstests/sharding/libs/mongos_api_params_util.js
@@ -97,7 +97,38 @@ let MongosAPIParametersUtil = (function() {
skip: "executes locally on mongos (not sent to any remote node)"
},
{commandName: "_mergeAuthzCollections", skip: "internal API"},
- {commandName: "abortTransaction", skip: "prohibits API parameters"},
+ {
+ commandName: "abortTransaction",
+ run: {
+ inAPIVersion1: true,
+ runsAgainstAdminDb: true,
+ shardCommandName: "abortTransaction",
+ permittedInTxn: false, // We handle the transaction manually in this test.
+ setUp: (context) => {
+ // Start a session and transaction.
+ const session = st.s0.startSession();
+ context.lsid = session.getSessionId();
+ const cmd = {
+ insert: "collection",
+ // A doc on each shard in the 2-shard configuration.
+ documents: [{_id: 1}, {_id: 21}],
+ lsid: context.lsid,
+ txnNumber: NumberLong(1),
+ autocommit: false,
+ startTransaction: true
+ };
+
+ assert.commandWorked(
+ st.s0.getDB("db").runCommand(Object.assign(cmd, context.apiParameters)));
+ },
+ command: (context) => ({
+ abortTransaction: 1,
+ lsid: context.lsid,
+ txnNumber: NumberLong(1),
+ autocommit: false
+ })
+ }
+ },
{
commandName: "addShard",
run: {
@@ -191,7 +222,38 @@ let MongosAPIParametersUtil = (function() {
command: () => ({collStats: "collection"}),
}
},
- {commandName: "commitTransaction", skip: "prohibits API parameters"},
+ {
+ commandName: "commitTransaction",
+ run: {
+ inAPIVersion1: true,
+ runsAgainstAdminDb: true,
+ shardCommandName: "commitTransaction",
+ permittedInTxn: false, // We handle the transaction manually in this test.
+ setUp: (context) => {
+ // Start a session and transaction.
+ const session = st.s0.startSession();
+ context.lsid = session.getSessionId();
+ const cmd = {
+ insert: "collection",
+ // A doc on each shard in the 2-shard configuration.
+ documents: [{_id: 1}, {_id: 21}],
+ lsid: context.lsid,
+ txnNumber: NumberLong(1),
+ autocommit: false,
+ startTransaction: true
+ };
+
+ assert.commandWorked(
+ st.s0.getDB("db").runCommand(Object.assign(cmd, context.apiParameters)));
+ },
+ command: (context) => ({
+ commitTransaction: 1,
+ lsid: context.lsid,
+ txnNumber: NumberLong(1),
+ autocommit: false
+ })
+ }
+ },
{commandName: "compact", skip: "not allowed through mongos"},
{
commandName: "configureFailPoint",
@@ -1338,7 +1400,9 @@ let MongosAPIParametersUtil = (function() {
}
if (lastCommandInvocation === undefined) {
- msg = `Primary didn't log ${commandName}`;
+ msg = `Primary didn't log ${commandName} with apiVersion ${apiVersion},` +
+ ` apiStrict ${apiStrict},` +
+ ` apiDeprecationErrors ${apiDeprecationErrors}.`;
return false;
}
@@ -1441,7 +1505,13 @@ let MongosAPIParametersUtil = (function() {
const configPrimary = st.configRS.getPrimary();
const shardZeroPrimary = st.rs0.getPrimary();
- const context = {};
+ const context = {
+ apiParameters: {
+ apiVersion: apiVersion,
+ apiStrict: apiStrict,
+ apiDeprecationErrors: apiDeprecationErrors
+ }
+ };
if (runOrExplain.setUp) {
jsTestLog(`setUp function for ${commandName}`);