summaryrefslogtreecommitdiff
path: root/jstests
diff options
context:
space:
mode:
authorRui Liu <rui.liu@mongodb.com>2022-02-09 16:42:49 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-02-22 17:35:12 +0000
commit27592b271b35207836c1a69e2849ef9d3dc54697 (patch)
tree09cf5ce4b2599d5678a1dfbcba64bf9f6366ba5e /jstests
parent974b470bccf8890b466b165ccee14b4929e0536f (diff)
downloadmongo-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.js4
-rw-r--r--jstests/replsets/update_with_dollar_fields.js50
-rw-r--r--jstests/sharding/update_sharded.js8
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");