diff options
author | Rui Liu <rui.liu@mongodb.com> | 2022-02-09 16:42:49 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-02-22 17:35:12 +0000 |
commit | 27592b271b35207836c1a69e2849ef9d3dc54697 (patch) | |
tree | 09cf5ce4b2599d5678a1dfbcba64bf9f6366ba5e /jstests | |
parent | 974b470bccf8890b466b165ccee14b4929e0536f (diff) | |
download | mongo-27592b271b35207836c1a69e2849ef9d3dc54697.tar.gz |
SERVER-63428 Robustify oplog applying code for update operation
(cherry picked from commit a3158ab422e4d8091203166c5f2601f9bfa0099d)
Diffstat (limited to 'jstests')
-rw-r--r-- | jstests/core/apply_ops1.js | 4 | ||||
-rw-r--r-- | jstests/replsets/update_with_dollar_fields.js | 50 | ||||
-rw-r--r-- | jstests/sharding/update_sharded.js | 8 |
3 files changed, 60 insertions, 2 deletions
diff --git a/jstests/core/apply_ops1.js b/jstests/core/apply_ops1.js index 9ecaef4c763..86754d7b9ba 100644 --- a/jstests/core/apply_ops1.js +++ b/jstests/core/apply_ops1.js @@ -457,7 +457,7 @@ res = assert.commandFailed(db.adminCommand({ } ] })); -assert.eq(res.code, 4772604); +assert.eq(res.code, 4772600); // When we explicitly specify {$v: 1}, we should get 'UpdateNode' update semantics, and $set // operations get performed in lexicographic order. @@ -503,7 +503,7 @@ res = assert.commandFailed(db.adminCommand({ } ] })); -assert.eq(res.code, 4772604); +assert.eq(res.code, 4772600); var insert_op1 = {_id: 13, x: 'inserted apply ops1'}; var insert_op2 = {_id: 14, x: 'inserted apply ops2'}; diff --git a/jstests/replsets/update_with_dollar_fields.js b/jstests/replsets/update_with_dollar_fields.js new file mode 100644 index 00000000000..9ecb8a4399c --- /dev/null +++ b/jstests/replsets/update_with_dollar_fields.js @@ -0,0 +1,50 @@ +/** + * Tests that replacement style update with $v field in the document is correctly applied. + * @tags: [ + * requires_fcv_60, + * ] + */ + +(function() { +"use strict"; + +const rst = new ReplSetTest({nodes: 2}); +rst.startSet(); +rst.initiate(); + +const dbName = 'testDb'; +const collName = 'testColl'; +const primary = rst.getPrimary(); +const coll = primary.getDB(dbName).getCollection(collName); +const oplog = primary.getDB('local').getCollection('oplog.rs'); + +function assertLastUpdateOplogEntryIsReplacement() { + const lastUpdate = oplog.find({op: 'u'}).sort({$natural: -1}).limit(1).next(); + assert(lastUpdate.o._id); +} + +[true].forEach($v => { + const _id = assert.commandWorked(coll.insertOne({$v})).insertedId; + assert.commandWorked(coll.update({_id}, [{$set: {p: 1, q: 1}}])); + assertLastUpdateOplogEntryIsReplacement(); +}); + +[true, "hello", 0, 1, 2, 3].forEach($v => { + const _id = assert.commandWorked(coll.insertOne({})).insertedId; + assert.commandWorked(coll.update( + {_id}, + [{$replaceWith: {"$setField": {field: {$literal: "$v"}, input: "$$ROOT", value: $v}}}])); + assertLastUpdateOplogEntryIsReplacement(); +}); + +(function() { +const _id = assert.commandWorked(coll.insertOne({})).insertedId; +assert.commandWorked(coll.update( + {_id}, + [{$replaceWith: {"$setField": {field: {$literal: "$set"}, input: "$$ROOT", value: {a: 1}}}}])); +assertLastUpdateOplogEntryIsReplacement(); +})(); + +rst.awaitReplication(); +rst.stopSet(); +}()); diff --git a/jstests/sharding/update_sharded.js b/jstests/sharding/update_sharded.js index ee9ec595bb6..73da8316f4e 100644 --- a/jstests/sharding/update_sharded.js +++ b/jstests/sharding/update_sharded.js @@ -40,6 +40,14 @@ for (let i = 0; i < 2; i++) { assert.commandWorked(coll.update({_id: 2, key: 2}, {key: 2, foo: 'bar'}, {upsert: true})); assert.commandWorked(coll.update({_id: 3, key: 3}, {$set: {foo: 'bar'}}, {upsert: true})); + // Mixing operator & non-operator fields in updates is not allowed. + assert.commandFailedWithCode( + coll.update({_id: 4, key: 4}, {key: 4, $baz: {foo: 'bar'}}, {upsert: true}), + ErrorCodes.UnsupportedFormat); + assert.commandFailedWithCode( + coll.update({_id: 5, key: 5}, {$baz: {foo: 'bar'}, key: 5}, {upsert: true}), + ErrorCodes.UnsupportedFormat); + assert.eq(coll.count(), 3, "count A"); assert.eq(coll.findOne({_id: 3}).key, 3, "findOne 3 key A"); assert.eq(coll.findOne({_id: 3}).foo, 'bar', "findOne 3 foo A"); |