diff options
author | Mihai Andrei <mihai.andrei@10gen.com> | 2020-05-06 09:54:01 -0400 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2020-05-11 14:12:43 +0000 |
commit | 7c9225a68a9e6d2d9f4507812fcbcf7924dce45d (patch) | |
tree | 403130c3d14f9f5c975404d4d2703163f78d0b49 | |
parent | f2aa1ffe05804aa3cc21ad5f980bca998dde09f3 (diff) | |
download | mongo-7c9225a68a9e6d2d9f4507812fcbcf7924dce45d.tar.gz |
SERVER-46903 Ensure mongo shell respects readPreference for $out and $merge when 'Mongo.setReadPref' is called
-rw-r--r-- | jstests/aggregation/bugs/server18198.js | 67 | ||||
-rw-r--r-- | jstests/noPassthrough/aggregation_out_on_secondary.js | 8 | ||||
-rw-r--r-- | jstests/noPassthrough/merge_on_secondary.js | 9 | ||||
-rw-r--r-- | src/mongo/shell/db.js | 18 |
4 files changed, 11 insertions, 91 deletions
diff --git a/jstests/aggregation/bugs/server18198.js b/jstests/aggregation/bugs/server18198.js deleted file mode 100644 index 9aa26451161..00000000000 --- a/jstests/aggregation/bugs/server18198.js +++ /dev/null @@ -1,67 +0,0 @@ -// SERVER-18198 check read pref is only applied when there is no $out stage -// in aggregate shell helper -(function() { -"use strict"; -var t = db.server18198; -t.drop(); - -var mongo = db.getMongo(); - -try { - var commandsRan = []; - // hook in our patched mongo - var mockMongo = { - getSlaveOk: function() { - return true; - }, - runCommand: function(db, cmd, opts) { - commandsRan.push({db: db, cmd: cmd, opts: opts}); - return {ok: 1.0}; - }, - getReadPref: function() { - return {mode: "secondaryPreferred"}; - }, - getReadPrefMode: function() { - return "secondaryPreferred"; - }, - getMinWireVersion: function() { - return mongo.getMinWireVersion(); - }, - getMaxWireVersion: function() { - return mongo.getMaxWireVersion(); - }, - isReplicaSetMember: function() { - return mongo.isReplicaSetMember(); - }, - isMongos: function() { - return mongo.isMongos(); - }, - isCausalConsistency: function() { - return false; - }, - getClusterTime: function() { - return mongo.getClusterTime(); - }, - }; - - db._mongo = mockMongo; - db._session = new _DummyDriverSession(mockMongo); - - // this query should not get a read pref - t.aggregate([{$sort: {"x": 1}}, {$out: "foo"}]); - assert.eq(commandsRan.length, 1); - // check that it doesn't have a read preference - assert(!commandsRan[0].cmd.hasOwnProperty("$readPreference")); - - commandsRan = []; - - t.aggregate([{$sort: {"x": 1}}]); - // check another command was run - assert.eq(commandsRan.length, 1); - // check that it has a read preference - assert(commandsRan[0].cmd.hasOwnProperty("$readPreference")); -} finally { - db._mongo = mongo; - db._session = new _DummyDriverSession(mongo); -} -})(); diff --git a/jstests/noPassthrough/aggregation_out_on_secondary.js b/jstests/noPassthrough/aggregation_out_on_secondary.js index ef9c7894c2b..32a5f5668e9 100644 --- a/jstests/noPassthrough/aggregation_out_on_secondary.js +++ b/jstests/noPassthrough/aggregation_out_on_secondary.js @@ -26,6 +26,9 @@ const readColl = primaryDB[readCollName]; const secondary = rs.getSecondary(); const secondaryDB = secondary.getDB(dbName); +const replSetConn = new Mongo(rs.getURL()); +replSetConn.setReadPref("secondary"); +const db = replSetConn.getDB(dbName); // Keeps track of values which we expect the aggregate command to return. let expectedResults = []; // Insert some documents which our pipeline will eventually read from. @@ -44,10 +47,7 @@ assert.commandWorked(secondaryDB.setProfilingLevel(2)); const pipeline = [{$group: {_id: "$groupKey", sum: {$sum: "$num"}}}, {$out: outCollName}]; const comment = "$out issued to secondary"; -assert.eq(secondaryDB[readCollName] - .aggregate(pipeline, {$readPreference: {mode: "secondary"}, comment: comment}) - .itcount(), - 0); +assert.eq(db[readCollName].aggregate(pipeline, {comment: comment}).itcount(), 0); // Verify that $out wrote to the primary and that query is correct. assert(anyEq(primaryDB[outCollName].find().toArray(), expectedResults)); diff --git a/jstests/noPassthrough/merge_on_secondary.js b/jstests/noPassthrough/merge_on_secondary.js index 1c91a04ef34..8db2685cb26 100644 --- a/jstests/noPassthrough/merge_on_secondary.js +++ b/jstests/noPassthrough/merge_on_secondary.js @@ -16,12 +16,15 @@ replTest.awaitReplication(); const primary = replTest.getPrimary().getDB("test"); const secondary = replTest.getSecondary().getDB("test"); assert.commandWorked(primary.setProfilingLevel(2)); -secondary.getMongo().setReadPref("secondary"); const inputCollPrimary = primary.getCollection("inputColl"); -const inputCollSecondary = secondary.getCollection("inputColl"); const outColl = primary.getCollection("outColl"); +const replSetConn = new Mongo(replTest.getURL()); +replSetConn.setReadPref("secondary"); +const db = replSetConn.getDB("test"); +const inputColl = db["inputColl"]; + assert.commandWorked(inputCollPrimary.insert({_id: 0, a: 1}, {writeConcern: {w: 2}})); assert.commandWorked(inputCollPrimary.insert({_id: 1, a: 2}, {writeConcern: {w: 2}})); @@ -35,7 +38,7 @@ withEachMergeMode(({whenMatchedMode, whenNotMatchedMode}) => { const commentStr = "whenMatched_" + whenMatchedMode + "_whenNotMatched_" + whenNotMatchedMode; assert.eq(0, - inputCollSecondary + inputColl .aggregate([{ $merge: { into: outColl.getName(), diff --git a/src/mongo/shell/db.js b/src/mongo/shell/db.js index 5a10d55ff5f..62bd56bf8c5 100644 --- a/src/mongo/shell/db.js +++ b/src/mongo/shell/db.js @@ -229,23 +229,7 @@ DB.prototype._runAggregate = function(cmdObj, aggregateOptions) { cmdObj.cursor = {}; } - const pipeline = cmdObj.pipeline; - - // Check whether the pipeline has a stage which performs writes like $out. If not, we may - // run on a Secondary and should attach a readPreference. - const hasWritingStage = (function() { - if (pipeline.length == 0) { - return false; - } - const lastStage = pipeline[pipeline.length - 1]; - return lastStage.hasOwnProperty("$out") || lastStage.hasOwnProperty("$merge"); - }()); - - const doAgg = function(cmdObj) { - return hasWritingStage ? this.runCommand(cmdObj) : this.runReadCommand(cmdObj); - }.bind(this); - - const res = doAgg(cmdObj); + const res = this.runReadCommand(cmdObj); if (!res.ok && (res.code == 17020 || res.errmsg == "unrecognized field \"cursor") && !("cursor" in aggregateOptions)) { |