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

Avoid closing over $config.data in setup, teardown, and FSM state functions

    • Type: Icon: Bug Bug
    • Resolution: Done
    • Priority: Icon: Major - P3 Major - P3
    • 3.1.8
    • Affects Version/s: 3.1.7
    • Component/s: Testing Infrastructure
    • None
    • Fully Compatible
    • ALL
    • QuInt 8 08/28/15, Quint 9 09/18/15
    • 0
    • None
    • 0
    • None
    • None
    • None
    • None
    • None
    • None

      The $config closed over by a function will actually refer to a copy of the workload configuration. This means that changes to the $config.data made by a workload B that extends a workload A will not be reflected if workload A uses $config.data explicitly in its functions. The modified $config.data is bound as the this value when the functions are executed and should be used instead.

      The following JavaScript show the basic logic that the concurrency framework uses to let one workload configuration derive from another:

      // Taken from parse_config.js, but removed the validation code.
      function parseConfig(config) {
          config = Object.extend({}, config, true); // defensive deep copy
      
          config.startState = config.startState || 'init';
          config.setup = config.setup || Function.prototype;
          config.teardown = config.teardown || Function.prototype;
          config.data = config.data || {};
      
          return config;
      }
      
      // Taken from extend_workload.js, but removed the validation code.
      function extendWorkload($config, callback) {
          var parsedSuperConfig = parseConfig($config);
          var childConfig = Object.extend({}, parsedSuperConfig, true);
          return callback(childConfig, parsedSuperConfig);
      }
      
      var $config = {}; // Normally would be defined by doing some load() call.
      
      (function() {
          var extend1 = extendWorkload($config, function($config, $super) {
              $config.data.test = 'original';
      
              $config.setup = function setup(db, collName, cluster) {
                  $super.setup.apply(this, arguments);
                  print('using $config.data: ' + $config.data.test);
      
              };
      
              return $config;
          });
      
          var extend2 = extendWorkload(extend1, function($config, $super) {
              $config.data.test = 'changed';
      
              return $config;
          });
      
          extend2.setup.call(extend2.data); // See setupWorkload() in runner.js
      })();
      
      (function() {
          var extend1 = extendWorkload($config, function($config, $super) {
              $config.data.test = 'original';
      
              $config.setup = function setup(db, collName, cluster) {
                  $super.setup.apply(this, arguments);
                  print('using this: ' + this.test);
      
              };
      
              return $config;
          });
      
          var extend2 = extendWorkload(extend1, function($config, $super) {
              $config.data.test = 'changed';
      
              return $config;
          });
      
          extend2.setup.call(extend2.data); // See setupWorkload() in runner.js
      })();
      
      using $config.data: original
      using this: changed
      

            Assignee:
            max.hirschhorn@mongodb.com Max Hirschhorn
            Reporter:
            max.hirschhorn@mongodb.com Max Hirschhorn
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: