// Each entry in the returned array contains a command whose noop write concern behavior needs to be // tested. Entries have the following structure: // { // req: , // Command request object that will result in a noop // // write after the setup function is called. // // setupFunc: , // Function to run to ensure that the request is a // // noop. // // confirmFunc: , // Function to run after the command is run to ensure // // that it executed properly. Accepts the result of // // the noop request to validate it. // } export function getNoopWriteCommands(coll) { const db = coll.getDB(); const collName = coll.getName(); const commands = []; // 'applyOps' where the update has already been done. commands.push({ req: {applyOps: [{op: "u", ns: coll.getFullName(), o: {_id: 1}, o2: {_id: 1}}]}, setupFunc: function() { assert.commandWorked(coll.insert({_id: 1})); }, confirmFunc: function(res) { assert.commandWorkedIgnoringWriteConcernErrors(res); assert.eq(res.applied, 1); assert.eq(res.results[0], true); assert.eq(coll.find().itcount(), 1); assert.eq(coll.count({_id: 1}), 1); } }); // 'update' where the document to update does not exist. commands.push({ req: {update: collName, updates: [{q: {a: 1}, u: {b: 2}}]}, setupFunc: function() { assert.commandWorked(coll.insert({a: 1})); assert.commandWorked(coll.update({a: 1}, {b: 2})); }, confirmFunc: function(res) { assert.commandWorkedIgnoringWriteConcernErrors(res); assert.eq(res.n, 0); assert.eq(res.nModified, 0); assert.eq(coll.find().itcount(), 1); assert.eq(coll.count({b: 2}), 1); } }); // 'update' where the update has already been done. commands.push({ req: {update: collName, updates: [{q: {a: 1}, u: {$set: {b: 2}}}]}, setupFunc: function() { assert.commandWorked(coll.insert({a: 1})); assert.commandWorked(coll.update({a: 1}, {$set: {b: 2}})); }, confirmFunc: function(res) { assert.commandWorkedIgnoringWriteConcernErrors(res); assert.eq(res.n, 1); assert.eq(res.nModified, 0); assert.eq(coll.find().itcount(), 1); assert.eq(coll.count({a: 1, b: 2}), 1); } }); // 'update' with immutable field error. commands.push({ req: {update: collName, updates: [{q: {_id: 1}, u: {$set: {_id: 2}}}]}, setupFunc: function() { assert.commandWorked(coll.insert({_id: 1})); }, confirmFunc: function(res) { assert.eq(res.n, 0); assert.eq(res.nModified, 0); assert.eq(coll.count({_id: 1}), 1); } }); // 'delete' where the document to delete does not exist. commands.push({ req: {delete: collName, deletes: [{q: {a: 1}, limit: 1}]}, setupFunc: function() { assert.commandWorked(coll.insert({a: 1})); assert.commandWorked(coll.remove({a: 1})); }, confirmFunc: function(res) { assert.commandWorkedIgnoringWriteConcernErrors(res); assert.eq(res.n, 0); assert.eq(coll.count({a: 1}), 0); } }); // 'createIndexes' where the index has already been created. // All voting data bearing nodes are not up for this test. So 'createIndexes' command can't // succeed with the default index commitQuorum value "votingMembers". So, running createIndexes // cmd using commit quorum "majority". commands.push({ req: { createIndexes: collName, indexes: [{key: {a: 1}, name: "a_1"}], commitQuorum: "majority" }, setupFunc: function() { assert.commandWorked(coll.insert({a: 1})); assert.commandWorkedIgnoringWriteConcernErrors(db.runCommand({ createIndexes: collName, indexes: [{key: {a: 1}, name: "a_1"}], commitQuorum: "majority" })); }, confirmFunc: function(res) { assert.commandWorkedIgnoringWriteConcernErrors(res); let details = res; if ("raw" in details) { const raw = details.raw; details = raw[Object.keys(raw)[0]]; } assert.eq(details.numIndexesBefore, details.numIndexesAfter); assert.eq(details.note, 'all indexes already exist'); } }); // 'findAndModify' where the document to update does not exist. commands.push({ req: {findAndModify: collName, query: {a: 1}, update: {b: 2}}, setupFunc: function() { assert.commandWorked(coll.insert({a: 1})); assert.commandWorkedIgnoringWriteConcernErrors( db.runCommand({findAndModify: collName, query: {a: 1}, update: {b: 2}})); }, confirmFunc: function(res) { assert.commandWorkedIgnoringWriteConcernErrors(res); assert.eq(res.lastErrorObject.updatedExisting, false); assert.eq(coll.find().itcount(), 1); assert.eq(coll.count({b: 2}), 1); } }); // 'findAndModify' where the update has already been done. commands.push({ req: {findAndModify: collName, query: {a: 1}, update: {$set: {b: 2}}}, setupFunc: function() { assert.commandWorked(coll.insert({a: 1})); assert.commandWorkedIgnoringWriteConcernErrors( db.runCommand({findAndModify: collName, query: {a: 1}, update: {$set: {b: 2}}})); }, confirmFunc: function(res) { assert.commandWorkedIgnoringWriteConcernErrors(res); assert.eq(res.lastErrorObject.updatedExisting, true); assert.eq(coll.find().itcount(), 1); assert.eq(coll.count({a: 1, b: 2}), 1); } }); // 'findAndModify' with immutable field error. commands.push({ req: {findAndModify: collName, query: {_id: 1}, update: {$set: {_id: 2}}}, setupFunc: function() { assert.commandWorked(coll.insert({_id: 1})); }, confirmFunc: function(res) { assert.commandFailedWithCode(res, ErrorCodes.ImmutableField); assert.eq(coll.find().itcount(), 1); assert.eq(coll.count({_id: 1}), 1); } }); // 'findAndModify' where the document to delete does not exist. commands.push({ req: {findAndModify: collName, query: {a: 1}, remove: true}, setupFunc: function() { assert.commandWorked(coll.insert({a: 1})); assert.commandWorked(coll.remove({a: 1})); }, confirmFunc: function(res) { assert.commandWorkedIgnoringWriteConcernErrors(res); assert.eq(res.lastErrorObject.n, 0); } }); // 'dropDatabase' where the database has already been dropped. commands.push({ req: {dropDatabase: 1}, setupFunc: function() { assert.commandWorked(coll.insert({a: 1})); assert.commandWorkedIgnoringWriteConcernErrors(db.runCommand({dropDatabase: 1})); }, confirmFunc: function(res) { assert.commandWorkedIgnoringWriteConcernErrors(res); } }); // 'drop' where the collection has already been dropped. commands.push({ req: {drop: collName}, setupFunc: function() { assert.commandWorked(coll.insert({a: 1})); assert.commandWorkedIgnoringWriteConcernErrors(db.runCommand({drop: collName})); }, confirmFunc: function(res) { assert.commandWorkedIgnoringWriteConcernErrors(res); } }); // 'create' where the collection has already been created. commands.push({ req: {create: collName}, setupFunc: function() { assert.commandWorkedIgnoringWriteConcernErrors(db.runCommand({create: collName})); }, confirmFunc: function(res) { assert.commandWorkedIgnoringWriteConcernErrors(res); } }); // 'insert' where the document with the same _id has already been inserted. commands.push({ req: {insert: collName, documents: [{_id: 1}]}, setupFunc: function() { assert.commandWorked(coll.insert({_id: 1})); }, confirmFunc: function(res) { assert.commandWorkedIgnoringWriteErrorsAndWriteConcernErrors(res); assert.eq(res.n, 0); assert.eq(res.writeErrors[0].code, ErrorCodes.DuplicateKey); assert.eq(coll.count({_id: 1}), 1); } }); return commands; }