summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMihai Andrei <mihai.andrei@10gen.com>2021-12-16 18:53:47 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-12-16 19:27:05 +0000
commitfcedcd3cd0e30b40666435e2777a0f86a5ef3ed0 (patch)
treeb0824a4c454ab4958bc7dbd77288de39b00d91cc
parent3285f14892712d7fef470bb4aa745e8dd0f76803 (diff)
downloadmongo-fcedcd3cd0e30b40666435e2777a0f86a5ef3ed0.tar.gz
SERVER-60788 Update 'merge_causes_infinite_loop.js' to demonstrate the halloween problem
(cherry picked from commit d77b27f4baa8139ef8baa48d1588342e95cae389) (cherry picked from commit 11e9d81741e822df6eacfbf2fe065cc7e63388f9)
-rw-r--r--jstests/noPassthrough/merge_causes_infinite_loop.js26
1 files changed, 21 insertions, 5 deletions
diff --git a/jstests/noPassthrough/merge_causes_infinite_loop.js b/jstests/noPassthrough/merge_causes_infinite_loop.js
index 2e626180414..70cbd85c1a7 100644
--- a/jstests/noPassthrough/merge_causes_infinite_loop.js
+++ b/jstests/noPassthrough/merge_causes_infinite_loop.js
@@ -2,7 +2,9 @@
* Test that exposes the Halloween problem.
*
* The Halloween problem describes the potential for a document to be visited more than once
- * following an update operation that changes its physical location.
+ * following an update operation that changes its physical location. The purpose of this test is
+ * to show that this behavior can be encountered when running a $merge aggregation which writes
+ * to the collection being read from.
*/
(function() {
"use strict";
@@ -71,18 +73,32 @@ for (const doc of diffCollResult) {
assert.eq(doc["a"], expectedVal, doc);
}
-// Targeting the same collection that is being aggregated over will still result in each
-// document's value of 'a' being updated exactly once.
+// Targeting the same collection that is being aggregated over will result in some documents' value
+// of 'a' being updated multiple times.
assert.commandWorked(
db.runCommand({aggregate: coll.getName(), pipeline: sameCollPipeline, cursor: {}}));
-const sameCollResult = out.find({}, {largeArray: 0}).toArray();
+const sameCollResult = coll.find({}, {largeArray: 0}).toArray();
+// At least one document in our collection should have been updated multiple times.
+let foundDocumentUpdatedMultipleTimes = false;
for (const doc of sameCollResult) {
assert(doc.hasOwnProperty("a"), doc);
const expectedVal = doc["_id"] * 2 * largeNum;
- assert.eq(doc["a"], expectedVal, doc);
+ const actualVal = doc["a"];
+
+ // If we find a mismatch, it must be the case that 'actualVal' is at least twice as large as
+ // 'expectedVal'. This means that the $multiply expression was applied multiple times to the
+ // same document.
+ if (actualVal !== expectedVal && actualVal >= 2 * expectedVal) {
+ foundDocumentUpdatedMultipleTimes = true;
+ break;
+ }
}
+assert(foundDocumentUpdatedMultipleTimes,
+ "All documents were updated exactly once, which is unexpected. Contents of the collection" +
+ " being aggregated over and merged into: " + tojson(sameCollResult));
+
MongoRunner.stopMongod(conn);
}());