diff options
Diffstat (limited to 'jstests/multiVersion/shell_retryable_writes_downgrade.js')
-rw-r--r-- | jstests/multiVersion/shell_retryable_writes_downgrade.js | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/jstests/multiVersion/shell_retryable_writes_downgrade.js b/jstests/multiVersion/shell_retryable_writes_downgrade.js new file mode 100644 index 00000000000..652d33c0ddc --- /dev/null +++ b/jstests/multiVersion/shell_retryable_writes_downgrade.js @@ -0,0 +1,122 @@ +/** + * Tests that the mongo shell doesn't attempt to retry its write operations after downgrading from + * 3.6 to 3.4. + */ +(function() { + "use strict"; + + load("jstests/replsets/rslib.js"); + + const rst = new ReplSetTest({nodes: 1}); + rst.startSet(); + rst.initiate(); + + const primary = rst.getPrimary(); + + const db = primary.startSession({retryWrites: true}).getDatabase("test"); + const coll = db.shell_retryable_writes_downgrade; + + function testCommandCanBeRetried(func, { + expectedLogicalSessionId: expectedLogicalSessionId = true, + expectedTransactionNumber: expectedTransactionNumber = true + } = {}) { + const mongoRunCommandOriginal = Mongo.prototype.runCommand; + + const sentinel = {}; + let cmdObjSeen = sentinel; + + Mongo.prototype.runCommand = function runCommandSpy(dbName, cmdObj, options) { + cmdObjSeen = cmdObj; + return mongoRunCommandOriginal.apply(this, arguments); + }; + + try { + assert.doesNotThrow(func); + } finally { + Mongo.prototype.runCommand = mongoRunCommandOriginal; + } + + if (cmdObjSeen === sentinel) { + throw new Error("Mongo.prototype.runCommand() was never called: " + func.toString()); + } + + let cmdName = Object.keys(cmdObjSeen)[0]; + + // If the command is in a wrapped form, then we look for the actual command object inside + // the query/$query object. + if (cmdName === "query" || cmdName === "$query") { + cmdObjSeen = cmdObjSeen[cmdName]; + cmdName = Object.keys(cmdObjSeen)[0]; + } + + if (expectedLogicalSessionId) { + assert(cmdObjSeen.hasOwnProperty("lsid"), + "Expected operation " + tojson(cmdObjSeen) + " to have a logical session id: " + + func.toString()); + } else { + assert(!cmdObjSeen.hasOwnProperty("lsid"), + "Expected operation " + tojson(cmdObjSeen) + + " to not have a logical session id: " + func.toString()); + } + + if (expectedTransactionNumber) { + assert(cmdObjSeen.hasOwnProperty("txnNumber"), + "Expected operation " + tojson(cmdObjSeen) + + " to be assigned a transaction number since it can be retried: " + + func.toString()); + } else { + assert(!cmdObjSeen.hasOwnProperty("txnNumber"), + "Expected operation " + tojson(cmdObjSeen) + + " to not be assigned a transaction number since it cannot be retried: " + + func.toString()); + } + } + + testCommandCanBeRetried(function() { + assert.writeOK(coll.insert({_id: "while fCV=3.6"})); + }); + + assert.commandWorked(db.adminCommand({setFeatureCompatibilityVersion: "3.4"})); + + // The server continues to accept lsid and txnNumber while in featureCompatibilityVersion=3.4. + // + // TODO SERVER-31777: The server should return an error if an lsid or txnNumber is specified + // while in featureCompatibilityVersion=3.4. + testCommandCanBeRetried(function() { + assert.writeOK(coll.insert({_id: "while fCV=3.4"})); + }); + + rst.restart(primary, {binVersion: "3.4"}); + rst.waitForMaster(); + + assert(db.getSession().getOptions().shouldRetryWrites(), + "Re-establishing the connection shouldn't change the state of the SessionOptions"); + + // After downgrading to MongoDB 3.4, the mongo shell shouldn't attempt to automatically retry + // write operations. + assert.throws(function() { + coll.insert({_id: "while in binVersion=3.4 and disconnected"}); + }); + + // After downgrading to MongoDB 3.4, the mongo shell shouldn't inject an lsid or assign a + // transaction number to its write requests. + testCommandCanBeRetried(function() { + assert.writeOK(coll.insert({_id: "while binVersion=3.4 and reconnected"})); + }, {expectedLogicalSessionId: false, expectedTransactionNumber: false}); + + rst.restart(primary, {binVersion: "latest", noReplSet: true}); + rst.waitForMaster(); + reconnect(primary); + + // When upgrading to MongoDB 3.6 but running as a stand-alone server, the mongo shell should + // still assign a transaction number to its write requests (per the Driver's specification). + // + // TODO SERVER-31777: The server should return an error if an lsid or txnNumber is specified + // while in featureCompatibilityVersion=3.4. + testCommandCanBeRetried(function() { + assert.writeOK(coll.insert({_id: "while binVersion=3.6 as stand-alone and reconnected"})); + }); + + db.getSession().endSession(); + rst.stopSet(); +})(); |