[SERVER-59909] ShardingTest mutates options objects passed to it. Created: 13/Sep/21  Updated: 29/Oct/23  Resolved: 03/Dec/21

Status: Closed
Project: Core Server
Component/s: None
Affects Version/s: None
Fix Version/s: 5.2.0

Type: Bug Priority: Major - P3
Reporter: Sara Golemon Assignee: Davis Haupt (Inactive)
Resolution: Fixed Votes: 0
Labels: neweng, sharding-nyc-subteam2
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Backwards Compatibility: Fully Compatible
Operating System: ALL
Participants:
Story Points: 2

 Description   

When using a single JS object containing setParameters (and optionally other things) to start up an instance of ShardingTest (for example, to enable a featureFlag, which will be a common setParameter used by both mongos and mongod) the setParameter subobject in the options object will be mutated by ShardingTest at somepoint during the mongod replica set startups. Since Javascript behaves in a reference-like manner, this mutates the original object passed to ShardingTest and mongos gets these settings as well. The simplest repro script showing this behavior is:

// Demonstrate mutation of opts object by ShardingTest
 
(function() {
'use strict';
 
const opts = { 
    setParameter: {}, 
};
 
try {
    const st = new ShardingTest({
        mongos: [opts],
        config: [opts],
        rs: {nodes: [opts]},
        shards: 1,
    }); 
} finally {
    jsTest.log('After attempting start, opts == ' + tojson(opts));
}
 
})();

Which results in an exception due to mongos receiving an unknown setParameter, injected by ShardingTest due to the mutation by reference:

[js_test:repro] s20022| {"t":{"$date":"2021-09-13T15:29:06.232Z"},"s":"F",  "c":"-",        "id":22865,   "ctx":"-","msg":"Error during global initialization","attr":{"error":{"code":2,"codeName":"BadValue","errmsg":"Unknown --setParameter 'shutdownTimeoutMillisForSignaledShutdown'"}}}

And indeed, we can see that the test's `opts` object now contains many setParameters:

[js_test:repro] [jsTest] ----
[js_test:repro] [jsTest] After attempting start, opts == {
[js_test:repro] [jsTest] 	"setParameter" : {
[js_test:repro] [jsTest] 		"writePeriodicNoops" : false,
[js_test:repro] [jsTest] 		"numInitialSyncConnectAttempts" : 60,
[js_test:repro] [jsTest] 		"shutdownTimeoutMillisForSignaledShutdown" : 100,
[js_test:repro] [jsTest] 		"enableDefaultWriteConcernUpdatesForInitiate" : true,
[js_test:repro] [jsTest] 		"enableReconfigRollbackCommittedWritesCheck" : false,
[js_test:repro] [jsTest] 		"mongosShutdownTimeoutMillisForSignaledShutdown" : 100
[js_test:repro] [jsTest] 	}
[js_test:repro] [jsTest] }
[js_test:repro] [jsTest] ----

ShardingTest needs to clone the primary opts object as well as any sub objects (e.g. setParameters) prior to mutating them. Note that JS object clones are shallow so in addition to the following:

const opts = Object.assign({}, opts);

It'll be important to do the same with the setParameter property as well, and possibly other elements of the ShardingTest configuration.

if (opts.setParameters) {
    opts.setParameters = Object.assign({}, opts.setParameters);
}



 Comments   
Comment by Githook User [ 02/Dec/21 ]

Author:

{'name': 'Davis Haupt', 'email': 'davis.haupt@mongodb.com', 'username': 'davish'}

Message: SERVER-59909 make ShardingTest and ReplSetTest option objects immutable
Branch: master
https://github.com/mongodb/mongo/commit/7f120e5dbf538ce29b637c5caa2d175a58e1afad

Comment by Githook User [ 02/Dec/21 ]

Author:

{'name': 'Davis Haupt', 'email': 'davis.haupt@mongodb.com', 'username': 'davish'}

Message: SERVER-59909 rely on deep copy of options in ShardingTest
Branch: master
https://github.com/10gen/mongo-enterprise-modules/commit/b4f87d7d399ff246dad3d724b6bf0ab41bc265c7

Generated at Thu Feb 08 05:48:28 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.