Uploaded image for project: 'Core Server'
  1. Core Server
  2. SERVER-59909

ShardingTest mutates options objects passed to it.

    • Fully Compatible
    • ALL
    • 2

      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);
      }
      

            Assignee:
            davis.haupt@mongodb.com Davis Haupt (Inactive)
            Reporter:
            sara.golemon@mongodb.com Sara Golemon
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: