0
0
mirror of https://github.com/mongodb/mongo.git synced 2024-12-01 01:21:03 +01:00
mongodb/jstests/sharding/merge_to_non_existing.js

109 lines
4.5 KiB
JavaScript
Raw Normal View History

// Tests for $merge with a non-existing target collection.
(function() {
"use strict";
load("jstests/aggregation/extras/out_helpers.js"); // For withEachMergeMode.
load("jstests/aggregation/extras/utils.js"); // For assertErrorCode.
const st = new ShardingTest({shards: 2, rs: {nodes: 1}, config: 1});
const sourceDB = st.s0.getDB("source_db");
/**
* Run an aggregation on 'sourceColl' that writes documents to 'targetColl' with $merge.
*/
function testMerge(sourceColl, targetColl, shardedSource) {
sourceColl.drop();
if (shardedSource) {
st.shardColl(sourceColl, {_id: 1}, {_id: 0}, {_id: 1}, sourceDB.getName());
}
for (let i = 0; i < 10; i++) {
assert.commandWorked(sourceColl.insert({_id: i}));
}
// Test the behavior for each of the $merge modes. Since the target collection does not
// exist, the behavior should be identical.
withEachMergeMode(({whenMatchedMode, whenNotMatchedMode}) => {
// Skip the combination of merge modes which will fail depending on the contents of the
// source and target collection, as this will cause the assertion below to trip.
if (whenMatchedMode == "fail" || whenNotMatchedMode == "fail")
return;
targetColl.drop();
sourceColl.aggregate([{
$merge: {
into: {db: targetColl.getDB().getName(), coll: targetColl.getName()},
whenMatched: whenMatchedMode,
whenNotMatched: whenNotMatchedMode,
on: "_id"
}
}]);
assert.eq(whenNotMatchedMode == "discard" ? 0 : 10, targetColl.find().itcount());
});
// Test that $merge fails if the "on" field is anything but "_id" when the target collection
// does not exist.
withEachMergeMode(({whenMatchedMode, whenNotMatchedMode}) => {
// Skip the combination of merge modes which will fail depending on the contents of the
// source and target collection, as this will cause the assertion below to trip.
if (whenMatchedMode == "fail" || whenNotMatchedMode == "fail")
return;
targetColl.drop();
assertErrorCode(
sourceColl,
[{
$merge: {
into: {db: targetColl.getDB().getName(), coll: targetColl.getName()},
whenMatched: whenMatchedMode,
whenNotMatched: whenNotMatchedMode,
on: "not_allowed"
}
}],
51190);
});
// If 'targetColl' is in the same database as 'sourceColl', test that the legacy $out works
// correctly.
if (targetColl.getDB() == sourceColl.getDB()) {
jsTestLog(
`Testing $out from ${sourceColl.getFullName()} ` +
`(${shardedSource ? "sharded" : "unsharded"}) to ${targetColl.getFullName()} ` +
`with legacy syntax`);
targetColl.drop();
sourceColl.aggregate([{$out: targetColl.getName()}]);
assert.eq(10, targetColl.find().itcount());
}
}
const sourceColl = sourceDB["source_coll"];
const outputCollSameDb = sourceDB["output_coll"];
// Test $merge from an unsharded source collection to a non-existent output collection in the
// same database.
testMerge(sourceColl, outputCollSameDb, false);
// Like the last test case, but perform a $merge from a sharded source collection to a
// non-existent output collection in the same database.
testMerge(sourceColl, outputCollSameDb, true);
// Test that $merge in a sharded cluster fails when the output is sent to a different database
// that doesn't exist.
const foreignDb = st.s0.getDB("foreign_db");
const outputCollDiffDb = foreignDb["output_coll"];
foreignDb.dropDatabase();
assert.throws(() => testMerge(sourceColl, outputCollDiffDb, false));
assert.throws(() => testMerge(sourceColl, outputCollDiffDb, true));
// Test $merge from an unsharded source collection to an output collection in a different
// database where the database exists but the collection does not.
assert.commandWorked(foreignDb["test"].insert({_id: "forcing database creation"}));
testMerge(sourceColl, outputCollDiffDb, false);
// Like the last test, but with a sharded source collection.
testMerge(sourceColl, outputCollDiffDb, true);
st.stop();
}());