Skip to content

Commit 41d291a

Browse files
authored
fix: honor journal=true in connection string
Ensure the journal option returned byparseQueryString is converted into j during the connect operation. This fixes the issue of the write concern not being set on commands where journal is only specified in the connection string. NODE-2422
1 parent d3bd81f commit 41d291a

File tree

3 files changed

+79
-2
lines changed

3 files changed

+79
-2
lines changed

lib/operations/connect.js

+6
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,12 @@ function connect(mongoClient, url, options, callback) {
213213
delete _finalOptions.db_options.auth;
214214
}
215215

216+
// `journal` should be translated to `j` for the driver
217+
if (_finalOptions.journal != null) {
218+
_finalOptions.j = _finalOptions.journal;
219+
_finalOptions.journal = undefined;
220+
}
221+
216222
// resolve tls options if needed
217223
resolveTLSOptions(_finalOptions);
218224

test/functional/shared.js

+32-2
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,13 @@ function withTempDb(name, options, client, operation, errorHandler) {
8686
);
8787
}
8888

89+
/**
90+
* Safely perform a test with provided MongoClient, ensuring client won't leak.
91+
*
92+
* @param {MongoClient} client
93+
* @param {Function|Promise} operation
94+
* @param {Function|Promise} [errorHandler]
95+
*/
8996
function withClient(client, operation, errorHandler) {
9097
const cleanup = makeCleanupFn(client);
9198

@@ -203,13 +210,29 @@ class EventCollector {
203210
}
204211
}
205212

206-
function withMonitoredClient(commands, callback) {
213+
/**
214+
* Perform a test with a monitored MongoClient that will filter for certain commands.
215+
*
216+
* @param {string|Array} commands commands to filter for
217+
* @param {object} [options] options to pass on to configuration.newClient
218+
* @param {object} [options.queryOptions] connection string options
219+
* @param {object} [options.clientOptions] MongoClient options
220+
* @param {withMonitoredClientCallback} callback the test function
221+
*/
222+
function withMonitoredClient(commands, options, callback) {
223+
if (arguments.length === 2) {
224+
callback = options;
225+
options = {};
226+
}
207227
if (!Object.prototype.hasOwnProperty.call(callback, 'prototype')) {
208228
throw new Error('withMonitoredClient callback can not be arrow function');
209229
}
210230
return function(done) {
211231
const configuration = this.configuration;
212-
const client = configuration.newClient({ monitorCommands: true });
232+
const client = configuration.newClient(
233+
Object.assign({}, options.queryOptions),
234+
Object.assign({ monitorCommands: true }, options.clientOptions)
235+
);
213236
const events = [];
214237
client.on('commandStarted', filterForCommands(commands, events));
215238
client.connect((err, client) => {
@@ -222,6 +245,13 @@ function withMonitoredClient(commands, callback) {
222245
};
223246
}
224247

248+
/**
249+
* @callback withMonitoredClientCallback
250+
* @param {MongoClient} client monitored client
251+
* @param {Array} events record of monitored commands
252+
* @param {Function} done trigger end of test and cleanup
253+
*/
254+
225255
module.exports = {
226256
connectToDb,
227257
setupDatabase,

test/functional/write_concern.test.js

+41
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
'use strict';
22

3+
const chai = require('chai');
4+
const expect = chai.expect;
35
const TestRunnerContext = require('./spec-runner').TestRunnerContext;
46
const generateTopologyTests = require('./spec-runner').generateTopologyTests;
57
const loadSpecTests = require('../spec').loadSpecTests;
8+
const { withMonitoredClient } = require('./shared');
69

710
describe('Write Concern', function() {
811
describe('spec tests', function() {
@@ -16,4 +19,42 @@ describe('Write Concern', function() {
1619

1720
generateTopologyTests(testSuites, testContext);
1821
});
22+
23+
// TODO: once `read-write-concern/connection-string` spec tests are implemented these can likely be removed
24+
describe('test journal connection string option', function() {
25+
function journalOptionTest(client, events, done) {
26+
expect(client).to.have.nested.property('s.options');
27+
const clientOptions = client.s.options;
28+
expect(clientOptions).to.containSubset({ j: true });
29+
client
30+
.db('test')
31+
.collection('test')
32+
.insertOne({ a: 1 }, (err, result) => {
33+
expect(err).to.not.exist;
34+
expect(result).to.exist;
35+
expect(events)
36+
.to.be.an('array')
37+
.with.lengthOf(1);
38+
expect(events[0]).to.containSubset({
39+
commandName: 'insert',
40+
command: {
41+
writeConcern: { j: true }
42+
}
43+
});
44+
done();
45+
});
46+
}
47+
48+
// baseline to confirm client option is working
49+
it(
50+
'should set write concern with j: true client option',
51+
withMonitoredClient('insert', { clientOptions: { j: true } }, journalOptionTest)
52+
);
53+
54+
// ensure query option in connection string passes through
55+
it(
56+
'should set write concern with journal=true connection string option',
57+
withMonitoredClient('insert', { queryOptions: { journal: true } }, journalOptionTest)
58+
);
59+
});
1960
});

0 commit comments

Comments
 (0)