summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMihai Andrei <mihai.andrei@10gen.com>2020-05-08 11:33:45 -0400
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-05-11 22:58:41 +0000
commit649790b0ba9df895f168ac061941eacb633792f9 (patch)
treef4deedf582d5efafe568a0bc5d46ff4dfbb3814d
parentb9bd6ded04f0136157c50c85c8bdc6bb176cccc9 (diff)
downloadmongo-649790b0ba9df895f168ac061941eacb633792f9.tar.gz
SERVER-48043 mode_merge_fail.js and mode_pipeline_fail.js should not assume ordering of writes from $merge
-rw-r--r--jstests/aggregation/sources/merge/mode_merge_fail.js28
-rw-r--r--jstests/aggregation/sources/merge/mode_pipeline_fail.js28
-rw-r--r--jstests/aggregation/sources/merge/mode_replace_fail.js14
3 files changed, 57 insertions, 13 deletions
diff --git a/jstests/aggregation/sources/merge/mode_merge_fail.js b/jstests/aggregation/sources/merge/mode_merge_fail.js
index ec9ca5af3a4..7235c8e1c7e 100644
--- a/jstests/aggregation/sources/merge/mode_merge_fail.js
+++ b/jstests/aggregation/sources/merge/mode_merge_fail.js
@@ -26,15 +26,37 @@ const pipeline = [mergeStage];
assert.commandWorked(target.insert([{_id: 1, b: 1}, {_id: 3, b: 3}]));
let error = assert.throws(() => source.aggregate(pipeline));
assert.commandFailedWithCode(error, ErrorCodes.MergeStageNoMatchingDocument);
- assertArrayEq(
- {actual: target.find().toArray(), expected: [{_id: 1, a: 1, b: 1}, {_id: 3, a: 3, b: 3}]});
+ // Since there is no way to guarantee the ordering of the writes performed by $merge, it
+ // follows that the contents of the target collection will depend on when the write which
+ // triggers the MergeStageNoMatchingDocument error executes. As such, we test that the
+ // target collection contains some combination of its original documents and expected
+ // updates. In particular, it should be the case that each document has fields '_id' and
+ // 'b', but may or not have field 'a'. All present fields must share the same value as _id.
+ let checkOutputDocument = function(document) {
+ const hasB = document.hasOwnProperty("b");
+ const hasA = document.hasOwnProperty("a");
+ assert(hasB, document);
+ const bValue = document["b"];
+ assert.eq(bValue, document["_id"], document);
+ if (hasA) {
+ assert.eq(bValue, document["a"], document);
+ }
+ };
+
+ let result = target.find().toArray();
+ assert.eq(result.length, 2, result);
+ for (let elem of result) {
+ checkOutputDocument(elem);
+ }
// Multiple documents without a match.
assert(target.drop());
assert.commandWorked(target.insert([{_id: 1, b: 1}]));
error = assert.throws(() => source.aggregate(pipeline));
assert.commandFailedWithCode(error, ErrorCodes.MergeStageNoMatchingDocument);
- assertArrayEq({actual: target.find().toArray(), expected: [{_id: 1, a: 1, b: 1}]});
+ result = target.find().toArray();
+ assert.eq(result.length, 1, result);
+ checkOutputDocument(result[0]);
})();
// Test $merge when all documents in the source collection have a matching document in the
diff --git a/jstests/aggregation/sources/merge/mode_pipeline_fail.js b/jstests/aggregation/sources/merge/mode_pipeline_fail.js
index 39282011e5b..08e503a0086 100644
--- a/jstests/aggregation/sources/merge/mode_pipeline_fail.js
+++ b/jstests/aggregation/sources/merge/mode_pipeline_fail.js
@@ -25,15 +25,37 @@ const pipeline = [mergeStage];
assert.commandWorked(target.insert([{_id: 1, b: 1}, {_id: 3, b: 3}]));
let error = assert.throws(() => source.aggregate(pipeline));
assert.commandFailedWithCode(error, ErrorCodes.MergeStageNoMatchingDocument);
- assertArrayEq(
- {actual: target.find().toArray(), expected: [{_id: 1, b: 1, x: 2}, {_id: 3, b: 3, x: 2}]});
+ // Since there is no way to guarantee the ordering of the writes performed by $merge, it
+ // follows that the contents of the target collection will depend on when the write which
+ // triggers the MergeStageNoMatchingDocument error executes. As such, we test that the
+ // target collection contains some combination of its original documents and expected
+ // updates. In particular, it should be the case that each document has fields '_id' and
+ // 'b', but may or not have field 'x'. Additionally, 'b' should have the same value as
+ // '_id' and if 'x' is present, it should be equal to 2.
+ let checkOutputDocument = function(document) {
+ const hasB = document.hasOwnProperty("b");
+ const hasX = document.hasOwnProperty("x");
+ assert(hasB, document);
+ const value = document["b"];
+ assert.eq(value, document['_id'], document);
+ if (hasX)
+ assert.eq(2, document['x'], document);
+ };
+
+ let result = target.find().toArray();
+ assert.eq(result.length, 2, result);
+ for (let elem of result) {
+ checkOutputDocument(elem);
+ }
// Multiple documents without a match.
assert(target.drop());
assert.commandWorked(target.insert([{_id: 1, b: 1}]));
error = assert.throws(() => source.aggregate(pipeline));
assert.commandFailedWithCode(error, ErrorCodes.MergeStageNoMatchingDocument);
- assertArrayEq({actual: target.find().toArray(), expected: [{_id: 1, b: 1, x: 2}]});
+ result = target.find().toArray();
+ assert.eq(result.length, 1, result);
+ checkOutputDocument(result[0]);
})();
// Test $merge when all documents in the source collection have a matching document in the
diff --git a/jstests/aggregation/sources/merge/mode_replace_fail.js b/jstests/aggregation/sources/merge/mode_replace_fail.js
index ff05d131a62..88582238c8f 100644
--- a/jstests/aggregation/sources/merge/mode_replace_fail.js
+++ b/jstests/aggregation/sources/merge/mode_replace_fail.js
@@ -24,17 +24,17 @@ const pipeline = [mergeStage];
let error = assert.throws(() => source.aggregate(pipeline));
assert.commandFailedWithCode(error, ErrorCodes.MergeStageNoMatchingDocument);
// Since there is no way to guarantee the ordering of the writes performed by $merge, it
- // follows that the contents of the target collection will depend on when the document which
+ // follows that the contents of the target collection will depend on when the write which
// triggers the MergeStageNoMatchingDocument error executes. As such, we test that the
// target collection contains some combination of its original documents and expected
// updates. In particular, it should be the case that each document has exactly one of field
// 'a' or field 'b' and its value should equal that of '_id'.
- let checkOutputDocument = function(elem) {
- const hasA = elem.hasOwnProperty('a');
- const hasB = elem.hasOwnProperty('b');
- assert(hasA ^ hasB);
- const value = hasA ? elem['a'] : elem['b'];
- assert.eq(value, elem['_id'], elem);
+ let checkOutputDocument = function(document) {
+ const hasA = document.hasOwnProperty('a');
+ const hasB = document.hasOwnProperty('b');
+ assert(hasA ^ hasB, document);
+ const value = hasA ? document['a'] : document['b'];
+ assert.eq(value, document['_id'], document);
};
let result = target.find().toArray();