From ddcd03d0f934d11a0707dd7d89bc4cb165775f55 Mon Sep 17 00:00:00 2001 From: Thomas Reggi Date: Mon, 21 Sep 2020 11:27:51 -0400 Subject: [PATCH] fix: sets primary read preference for writes Uses a primary read preference for write / DDL operations, needed for server selection. NODE-2784 --- lib/operations/command_v2.js | 4 ++- test/functional/collection.test.js | 40 ++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/lib/operations/command_v2.js b/lib/operations/command_v2.js index 2a53b8ea37..e59122a234 100644 --- a/lib/operations/command_v2.js +++ b/lib/operations/command_v2.js @@ -17,7 +17,9 @@ class CommandOperationV2 extends OperationBase { this.ns = parent.s.namespace.withCollection('$cmd'); const propertyProvider = this.hasAspect(Aspect.NO_INHERIT_OPTIONS) ? undefined : parent; - this.readPreference = ReadPreference.resolve(propertyProvider, this.options); + this.readPreference = this.hasAspect(Aspect.WRITE_OPERATION) + ? ReadPreference.primary + : ReadPreference.resolve(propertyProvider, this.options); this.readConcern = resolveReadConcern(propertyProvider, this.options); this.writeConcern = resolveWriteConcern(propertyProvider, this.options); this.explain = false; diff --git a/test/functional/collection.test.js b/test/functional/collection.test.js index a149757e88..83dfb3c41a 100644 --- a/test/functional/collection.test.js +++ b/test/functional/collection.test.js @@ -1,9 +1,11 @@ 'use strict'; +const Topology = require('../../lib/core/sdam/topology').Topology; const setupDatabase = require('./shared').setupDatabase; const chai = require('chai'); const expect = chai.expect; const sinonChai = require('sinon-chai'); const mock = require('mongodb-mock-server'); +const ReadPreference = require('../../lib/core/topologies/read_preference'); chai.use(sinonChai); describe('Collection', function() { @@ -1307,4 +1309,42 @@ describe('Collection', function() { }); } }); + + context('DDL methods with serverSelection readPreference primary', () => { + const collectionMethodSet = { + createIndex: [{ quote: 'text' }] + }; + + Object.keys(collectionMethodSet).forEach(operation => { + it(`should ${operation} with serverSelection readPreference primary`, { + metadata: { + requires: { topology: 'replicaset' } + }, + test: function(done) { + const opArgs = collectionMethodSet[operation]; + const configuration = this.configuration; + const client = configuration.newClient(configuration.writeConcernMax(), { + useUnifiedTopology: true, + readPreference: 'primaryPreferred' + }); + client.connect((err, client) => { + expect(err).to.not.exist; + const db = client.db(configuration.db); + const collection = db.collection('db-two'); + const TopologySpy = this.sinon.spy(Topology.prototype, 'selectServer'); + const callback = err => { + expect(err).to.not.exist; + expect(TopologySpy.called).to.equal(true); + expect(TopologySpy) + .nested.property('args[0][0].readPreference.mode') + .to.equal(ReadPreference.PRIMARY); + client.close(done); + }; + opArgs.push(callback); + collection[operation].apply(collection, opArgs); + }); + } + }); + }); + }); });