You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by nc...@apache.org on 2016/02/18 14:33:31 UTC

[12/33] ambari git commit: AMBARI-15054 Changing Yarn queues does not update hive.server2.tez.default.queues. (ababiichuk)

AMBARI-15054 Changing Yarn queues does not update hive.server2.tez.default.queues. (ababiichuk)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/8cfb2db6
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/8cfb2db6
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/8cfb2db6

Branch: refs/heads/branch-dev-patch-upgrade
Commit: 8cfb2db63021fe5d1ed7f44f1d4412e397810090
Parents: e4800e1
Author: ababiichuk <ab...@hortonworks.com>
Authored: Wed Feb 17 11:55:27 2016 +0200
Committer: ababiichuk <ab...@hortonworks.com>
Committed: Wed Feb 17 11:55:27 2016 +0200

----------------------------------------------------------------------
 .../controllers/main/service/info/configs.js    |  23 +-
 ambari-web/app/controllers/wizard.js            |   3 -
 .../app/controllers/wizard/step7_controller.js  |   6 +-
 .../app/mixins/common/configs/configs_saver.js  |   4 -
 .../configs/objects/service_config_property.js  |   2 +
 ambari-web/app/utils/config.js                  | 151 +++++-------
 ambari-web/app/views/common/controls_view.js    |  75 +++++-
 .../test/controllers/wizard/step7_test.js       |  26 --
 ambari-web/test/utils/config_test.js            | 242 -------------------
 9 files changed, 140 insertions(+), 392 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/8cfb2db6/ambari-web/app/controllers/main/service/info/configs.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/service/info/configs.js b/ambari-web/app/controllers/main/service/info/configs.js
index b6a434c..3cd652a 100644
--- a/ambari-web/app/controllers/main/service/info/configs.js
+++ b/ambari-web/app/controllers/main/service/info/configs.js
@@ -181,24 +181,6 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ConfigsLoader, A
   ],
 
   /**
-   * get array of config properties that are shown in settings tab
-   * @type {String[]}
-   */
-  settingsTabProperties: function () {
-    var properties = [];
-    App.Tab.find().forEach(function (t) {
-      if (!t.get('isAdvanced') && t.get('serviceName') === this.get('content.serviceName')) {
-        t.get('sections').forEach(function (s) {
-          s.get('subSections').forEach(function (ss) {
-            properties = properties.concat(ss.get('configProperties'));
-          });
-        });
-      }
-    }, this);
-    return properties;
-  }.property('content.serviceName', 'App.router.clusterController.isStackConfigsLoaded'),
-
-  /**
    * Dropdown menu items in filter combobox
    * @type {{attributeName: string, attributeValue: string, name: string, selected: boolean}[]}
    */
@@ -379,8 +361,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ConfigsLoader, A
 
     //put properties from capacity-scheduler.xml into one config with textarea view
     if (this.get('content.serviceName') === 'YARN') {
-      var configsToSkip = this.get('settingsTabProperties').filterProperty('filename', 'capacity-scheduler.xml');
-      configs = App.config.fileConfigsIntoTextarea(configs, 'capacity-scheduler.xml', configsToSkip);
+      configs = App.config.addYarnCapacityScheduler(configs);
     }
 
     if (this.get('content.serviceName') === 'KERBEROS') {
@@ -407,7 +388,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ConfigsLoader, A
    * @method mergeWithStackProperties
    */
   mergeWithStackProperties: function (configs) {
-    this.get('settingsTabProperties').forEach(function (advanced_id) {
+    App.config.getPropertiesFromTheme(this.get('content.serviceName')).forEach(function (advanced_id) {
       if (!configs.someProperty('id', advanced_id)) {
         var advanced = App.configsCollection.getConfig(advanced_id);
         if (advanced) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/8cfb2db6/ambari-web/app/controllers/wizard.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/wizard.js b/ambari-web/app/controllers/wizard.js
index 05ef68e..329d246 100644
--- a/ambari-web/app/controllers/wizard.js
+++ b/ambari-web/app/controllers/wizard.js
@@ -889,9 +889,6 @@ App.WizardController = Em.Controller.extend(App.LocalStorage, App.ThemesMappingM
     var installedServiceNames = stepController.get('installedServiceNames') || [];
     var installedServiceNamesMap = installedServiceNames.toWickMap();
     stepController.get('stepConfigs').forEach(function (_content) {
-      if (_content.serviceName === 'YARN') {
-        _content.set('configs', App.config.textareaIntoFileConfigs(_content.get('configs'), 'capacity-scheduler.xml'));
-      }
       _content.get('configs').forEach(function (_configProperties) {
         if (!Em.isNone(_configProperties.get('group'))) {
           return false;

http://git-wip-us.apache.org/repos/asf/ambari/blob/8cfb2db6/ambari-web/app/controllers/wizard/step7_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/wizard/step7_controller.js b/ambari-web/app/controllers/wizard/step7_controller.js
index 634c86b..0b29fe5 100644
--- a/ambari-web/app/controllers/wizard/step7_controller.js
+++ b/ambari-web/app/controllers/wizard/step7_controller.js
@@ -718,9 +718,6 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin, App.E
   },
 
   applyServicesConfigs: function (configs) {
-    if (this.get('allSelectedServiceNames').contains('YARN')) {
-      configs = App.config.fileConfigsIntoTextarea(configs, 'capacity-scheduler.xml', []);
-    }
     if (!this.get('installedServiceNames').contains('HAWQ') && this.get('allSelectedServiceNames').contains('HAWQ')) {
       this.updateHawqConfigs(configs);
     }
@@ -941,6 +938,9 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin, App.E
     }, this);
 
     stepConfigs.forEach(function (service) {
+      if (service.get('serviceName') === 'YARN') {
+        configsByService[service.get('serviceName')] = App.config.addYarnCapacityScheduler(configsByService[service.get('serviceName')]);
+      }
       service.set('configs', configsByService[service.get('serviceName')]);
       if (['addServiceController', 'installerController'].contains(this.get('wizardController.name'))) {
         this.addHostNamesToConfigs(service, localDB.masterComponentHosts, localDB.slaveComponentHosts);

http://git-wip-us.apache.org/repos/asf/ambari/blob/8cfb2db6/ambari-web/app/mixins/common/configs/configs_saver.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mixins/common/configs/configs_saver.js b/ambari-web/app/mixins/common/configs/configs_saver.js
index d2b2623..c2da486 100644
--- a/ambari-web/app/mixins/common/configs/configs_saver.js
+++ b/ambari-web/app/mixins/common/configs/configs_saver.js
@@ -293,10 +293,6 @@ App.ConfigsSaverMixin = Em.Mixin.create({
    */
   getServiceConfigToSave: function(serviceName, configs) {
 
-    if (serviceName === 'YARN') {
-      configs = App.config.textareaIntoFileConfigs(configs, 'capacity-scheduler.xml');
-    }
-
     //generates list of properties that was changed
     var modifiedConfigs = this.getModifiedConfigs(configs);
     var serviceFilenames = Object.keys(App.StackService.find(serviceName).get('configTypes')).map(function (type) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/8cfb2db6/ambari-web/app/models/configs/objects/service_config_property.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/models/configs/objects/service_config_property.js b/ambari-web/app/models/configs/objects/service_config_property.js
index 21e3dd3..a437c98 100644
--- a/ambari-web/app/models/configs/objects/service_config_property.js
+++ b/ambari-web/app/models/configs/objects/service_config_property.js
@@ -329,6 +329,8 @@ App.ServiceConfigProperty = Em.Object.extend({
         return App.ServiceConfigComponentHostsView;
       case 'supportTextConnection':
         return App.checkConnectionView;
+      case 'capacityScheduler':
+        return App.CapacitySceduler;
       default:
         if (this.get('unit')) {
           return App.ServiceConfigTextFieldWithUnit;

http://git-wip-us.apache.org/repos/asf/ambari/blob/8cfb2db6/ambari-web/app/utils/config.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/config.js b/ambari-web/app/utils/config.js
index d18c937..40d4699 100644
--- a/ambari-web/app/utils/config.js
+++ b/ambari-web/app/utils/config.js
@@ -438,7 +438,13 @@ App.config = Em.Object.create({
    * @returns {string}
    */
   getDefaultCategory: function(stackConfigProperty, fileName) {
-    return (stackConfigProperty ? 'Advanced ' : 'Custom ') + this.getConfigTagFromFileName(fileName);
+    var tag = this.getConfigTagFromFileName(fileName);
+    switch (tag) {
+      case 'capacity-scheduler':
+        return 'CapacityScheduler';
+      default :
+        return (stackConfigProperty ? 'Advanced ' : 'Custom ') + tag;
+    }
   },
 
   /**
@@ -693,106 +699,67 @@ App.config = Em.Object.create({
     return App.ServiceConfigProperty.create(propertyObject);
   },
 
-  complexConfigsTemplate: [
-    {
-      "name": "capacity-scheduler",
-      "displayName": "Capacity Scheduler",
-      "value": "",
-      "description": "Capacity Scheduler properties",
-      "displayType": "custom",
-      "isOverridable": true,
-      "isRequired": true,
-      "isVisible": true,
-      "isReconfigurable": true,
-      "supportsFinal": false,
-      "serviceName": "YARN",
-      "filename": "capacity-scheduler.xml",
-      "category": "CapacityScheduler"
-    }
-  ],
-
   /**
-   * transform set of configs from file
-   * into one config with textarea content:
-   * name=value
-   * @param {App.ServiceConfigProperty[]} configs
-   * @param {String} filename
-   * @param {App.ServiceConfigProperty[]} [configsToSkip=[]]
-   * @return {*}
+   *
+   * @param configs
    */
-  fileConfigsIntoTextarea: function (configs, filename, configsToSkip) {
-    var fileConfigs = configs.filterProperty('filename', filename);
-    var value = '', savedValue = '', recommendedValue = '';
-    var template = this.get('complexConfigsTemplate').findProperty('filename', filename);
-    var complexConfig = $.extend({}, template);
-    if (complexConfig) {
-      fileConfigs.forEach(function (_config) {
-        if (!(configsToSkip && configsToSkip.someProperty('name', _config.name))) {
-          value += _config.name + '=' + _config.value + '\n';
-          if (!Em.isNone(_config.savedValue)) {
-            savedValue += _config.name + '=' + _config.savedValue + '\n';
-          }
-          if (!Em.isNone(_config.recommendedValue)) {
-            recommendedValue += _config.name + '=' + _config.recommendedValue + '\n';
-          }
-        }
-      }, this);
-      var isFinal = fileConfigs.someProperty('isFinal', true);
-      var savedIsFinal = fileConfigs.someProperty('savedIsFinal', true);
-      var recommendedIsFinal = fileConfigs.someProperty('recommendedIsFinal', true);
-      complexConfig.value = value;
-      if (savedValue) {
-        complexConfig.savedValue = savedValue;
+  addYarnCapacityScheduler: function(configs) {
+    var value = '', savedValue = '', recommendedValue = '',
+      excludedConfigs = App.config.getPropertiesFromTheme('YARN');
+
+    var connectedConfigs = configs.filter(function(config) {
+      return !excludedConfigs.contains(App.config.configId(config.get('name'), config.get('filename'))) && (config.get('filename') === 'capacity-scheduler.xml');
+    });
+    connectedConfigs.setEach('isVisible', false);
+
+    connectedConfigs.forEach(function (config) {
+      value += config.get('name') + '=' + config.get('value') + '\n';
+      if (!Em.isNone(config.get('savedValue'))) {
+        savedValue += config.get('name') + '=' + config.get('savedValue') + '\n';
       }
-      if (recommendedValue) {
-        complexConfig.recommendedValue = recommendedValue;
+      if (!Em.isNone(config.get('recommendedValue'))) {
+        recommendedValue += config.get('name') + '=' + config.get('recommendedValue') + '\n';
       }
-      complexConfig.isFinal = isFinal;
-      complexConfig.savedIsFinal = savedIsFinal;
-      complexConfig.recommendedIsFinal = recommendedIsFinal;
-      configs = configs.filter(function (_config) {
-        return _config.filename !== filename || (configsToSkip && configsToSkip.someProperty('name', _config.name));
-      });
-      configs.push(App.ServiceConfigProperty.create(complexConfig));
-    }
+    }, this);
+
+    var isFinal = connectedConfigs.someProperty('isFinal', true);
+    var savedIsFinal = connectedConfigs.someProperty('savedIsFinal', true);
+    var recommendedIsFinal = connectedConfigs.someProperty('recommendedIsFinal', true);
+
+    var cs = App.config.createDefaultConfig('capacity-scheduler', 'YARN', 'capacity-scheduler.xml', true, {
+      'value': value,
+      'savedValue': savedValue || null,
+      'recommendedValue': recommendedValue || null,
+      'isFinal': isFinal,
+      'savedIsFinal': savedIsFinal,
+      'recommendedIsFinal': recommendedIsFinal,
+      'displayName': 'Capacity Scheduler',
+      'description': 'Capacity Scheduler properties',
+      'displayType': 'capacityScheduler',
+      'isRequiredByAgent': false
+    });
+
+    configs.push(App.ServiceConfigProperty.create(cs));
     return configs;
   },
 
   /**
-   * transform one config with textarea content
-   * into set of configs of file
-   * @param configs
-   * @param filename
-   * @return {*}
+   *
+   * @param serviceName
+   * @returns {Array}
    */
-  textareaIntoFileConfigs: function (configs, filename) {
-    var complexConfigName = this.get('complexConfigsTemplate').findProperty('filename', filename).name;
-    var configsTextarea = configs.findProperty('name', complexConfigName);
-    if (configsTextarea && !App.get('testMode')) {
-      var properties = configsTextarea.get('value').split('\n');
-
-      properties.forEach(function (_property) {
-        var name, value;
-        if (_property) {
-          _property = _property.split('=');
-          name = _property[0];
-          value = (_property[1]) ? _property[1] : "";
-          configs.push(Em.Object.create({
-            name: name,
-            value: value,
-            savedValue: value,
-            serviceName: configsTextarea.get('serviceName'),
-            filename: filename,
-            isFinal: configsTextarea.get('isFinal'),
-            isNotDefaultValue: configsTextarea.get('isNotDefaultValue'),
-            isRequiredByAgent: configsTextarea.get('isRequiredByAgent'),
-            group: null
-          }));
-        }
-      });
-      return configs.without(configsTextarea);
-    }
-    return configs;
+  getPropertiesFromTheme: function (serviceName) {
+    var properties = [];
+    App.Tab.find().forEach(function (t) {
+      if (!t.get('isAdvanced') && t.get('serviceName') === serviceName) {
+        t.get('sections').forEach(function (s) {
+          s.get('subSections').forEach(function (ss) {
+            properties = properties.concat(ss.get('configProperties'));
+          });
+        });
+      }
+    }, this);
+    return properties;
   },
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/8cfb2db6/ambari-web/app/views/common/controls_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/common/controls_view.js b/ambari-web/app/views/common/controls_view.js
index 9226b15..2290f58 100644
--- a/ambari-web/app/views/common/controls_view.js
+++ b/ambari-web/app/views/common/controls_view.js
@@ -104,7 +104,7 @@ App.SupportsDependentConfigs = Ember.Mixin.create({
       var type = App.config.getConfigTagFromFileName(config.get('filename'));
       var p = App.configsCollection.getConfig(App.config.configId(name, type));
       controller.removeCurrentFromDependentList(config, saveRecommended);
-       if ((p && Em.get(p, 'propertyDependedBy.length') > 0 || Em.get(p, 'displayType') === 'user') && config.get('oldValue') !== config.get('value')) {
+       if ((p && Em.get(p, 'propertyDependedBy.length') > 0 || config.get('displayType') === 'user') && config.get('oldValue') !== config.get('value')) {
          var old = config.get('oldValue');
          config.set('oldValue', config.get('value'));
          return controller.loadConfigRecommendations([{
@@ -295,6 +295,79 @@ App.ServiceConfigTextArea = Ember.TextArea.extend(App.ServiceConfigPopoverSuppor
   widthClass: 'span9'
 });
 
+
+/**
+ * Special config type for Capacity Scheduler
+ */
+App.CapacitySceduler = Ember.TextArea.extend(App.ServiceConfigPopoverSupport, App.ServiceConfigCalculateId, App.SupportsDependentConfigs, {
+
+  configs: function() {
+    return this.get('controller.stepConfigs').findProperty('serviceName', 'YARN').get('configs');
+  }.property('controller.stepConfigs'),
+
+  valueBinding: 'serviceConfig.value',
+  excludedConfigs: function() {
+    return App.config.getPropertiesFromTheme('YARN');
+  }.property(),
+  rows: 16,
+  classNames: ['directories'],
+  classNameBindings: ['widthClass'],
+  widthClass: 'span9',
+
+  connectedConfigs: function() {
+    return this.get('categoryConfigsAll').filter(function(config) {
+      return !this.get('excludedConfigs').contains(App.config.configId(config.get('name'), config.get('filename')))
+        && (config.get('name') !== this.get('serviceConfig.name'))
+        && (config.get('filename') === 'capacity-scheduler.xml');
+    }, this);
+  }.property('categoryConfigsAll.length'),
+
+  valueObserver: function () {
+    var self = this, controller = this.get('controller'),
+      names = [];
+    delay(function () {
+      self.get('serviceConfig.value').split('\n').forEach(function (_property) {
+        if (_property) {
+          _property = _property.split('=');
+          var name = _property[0];
+          var value = (_property[1]) ? _property[1] : "";
+
+          names.push(name);
+
+          var cfg = self.get('connectedConfigs').findProperty('name', name);
+          if (cfg) {
+            /** update configs **/
+            if (cfg.get('value') !== value) {
+              cfg.set('value', value);
+              self.sendRequestRorDependentConfigs(cfg, controller);
+            }
+          } else {
+            /** add configs **/
+            var newCfg = App.config.getDefaultConfig(name, 'YARN', 'capacity-scheduler', {
+              'value': value
+            });
+            self.get('configs').pushObject(App.ServiceConfigProperty.create(newCfg));
+          }
+        }
+      });
+
+      /** remove configs **/
+      self.get('connectedConfigs').filter(function(c) {
+        return !names.contains(c.get('name'));
+      }).forEach(function(c) {
+        self.get('configs').removeObject(c);
+      });
+    }, 500);
+  }.observes('serviceConfig.value'),
+
+  /**
+   * update fina; value for connected configs
+   */
+  isFinalObserver: function () {
+    this.get('connectedConfigs').setEach('isFinal', this.get('serviceConfig.isFinal'));
+  }.observes('serviceConfig.isFinal')
+});
+
 /**
  * Textarea control for content type
  * @type {*}

http://git-wip-us.apache.org/repos/asf/ambari/blob/8cfb2db6/ambari-web/test/controllers/wizard/step7_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/wizard/step7_test.js b/ambari-web/test/controllers/wizard/step7_test.js
index 8a4a96f..a089150 100644
--- a/ambari-web/test/controllers/wizard/step7_test.js
+++ b/ambari-web/test/controllers/wizard/step7_test.js
@@ -1071,7 +1071,6 @@ describe('App.InstallerStep7Controller', function () {
           stackConfigsLoaded: true
         })
       });
-      sinon.stub(App.config, 'fileConfigsIntoTextarea', Em.K);
       sinon.stub(installerStep7Controller, 'clearStep', Em.K);
       sinon.stub(installerStep7Controller, 'getConfigTags', Em.K);
       sinon.stub(installerStep7Controller, 'setInstalledServiceConfigs', Em.K);
@@ -1081,7 +1080,6 @@ describe('App.InstallerStep7Controller', function () {
       sinon.stub(App.router, 'send', Em.K);
     });
     afterEach(function () {
-      App.config.fileConfigsIntoTextarea.restore();
       installerStep7Controller.clearStep.restore();
       installerStep7Controller.getConfigTags.restore();
       installerStep7Controller.setInstalledServiceConfigs.restore();
@@ -1111,9 +1109,6 @@ describe('App.InstallerStep7Controller', function () {
       installerStep7Controller.reopen({
         allSelectedServiceNames: []
       });
-      sinon.stub(App.config, 'fileConfigsIntoTextarea', function(configs) {
-        return configs;
-      });
       sinon.stub(installerStep7Controller, 'loadConfigRecommendations', function(c, callback) {
         return callback();
       });
@@ -1137,7 +1132,6 @@ describe('App.InstallerStep7Controller', function () {
     });
 
     afterEach(function () {
-      App.config.fileConfigsIntoTextarea.restore();
       installerStep7Controller.loadConfigRecommendations.restore();
       installerStep7Controller.checkHostOverrideInstaller.restore();
       installerStep7Controller.selectProperService.restore();
@@ -1158,26 +1152,6 @@ describe('App.InstallerStep7Controller', function () {
      expect(installerStep7Controller.selectProperService.calledOnce).to.equal(true);
     });
 
-    Em.A([
-      {
-        allSelectedServiceNames: ['YARN'],
-        fileConfigsIntoTextarea: true,
-        m: 'should run fileConfigsIntoTextarea'
-      }
-    ]).forEach(function(t) {
-      it(t.m, function () {
-        installerStep7Controller.reopen({
-          allSelectedServiceNames: t.allSelectedServiceNames
-        });
-        installerStep7Controller.applyServicesConfigs([{name: 'configs'}]);
-        if (t.fileConfigsIntoTextarea) {
-          expect(App.config.fileConfigsIntoTextarea.calledWith([{name: 'configs'}], 'capacity-scheduler.xml')).to.equal(true);
-        } else {
-          expect(App.config.fileConfigsIntoTextarea.calledOnce).to.equal(false);
-        }
-      });
-    });
-
   });
 
   describe('#removeHawqStandbyHostAddressConfig', function() {

http://git-wip-us.apache.org/repos/asf/ambari/blob/8cfb2db6/ambari-web/test/utils/config_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/utils/config_test.js b/ambari-web/test/utils/config_test.js
index 0df828e..18471a2 100644
--- a/ambari-web/test/utils/config_test.js
+++ b/ambari-web/test/utils/config_test.js
@@ -29,248 +29,6 @@ function dummyCopy(val) {
 
 describe('App.config', function () {
 
-  describe('#fileConfigsIntoTextarea', function () {
-
-    var filename = 'capacity-scheduler.xml';
-
-    var configs = [
-      {
-        name: 'config1',
-        value: 'value1',
-        recommendedValue: 'value1',
-        filename: 'capacity-scheduler.xml'
-      },
-      {
-        name: 'config2',
-        value: 'value2',
-        recommendedValue: 'value2',
-        filename: 'capacity-scheduler.xml'
-      }
-    ];
-
-    var c3 = {
-      name: 'config3',
-      value: 'value3',
-      recommendedValue: 'value3',
-      filename: 'capacity-scheduler.xml'
-    };
-
-    describe('two configs into textarea', function () {
-      var result;
-      beforeEach(function () {
-        result = App.config.fileConfigsIntoTextarea(configs, filename);
-      });
-      it('One config is returned', function () {
-        expect(result.length).to.equal(1);
-      });
-      it('value is valid', function () {
-        expect(result[0].value).to.equal('config1=value1\nconfig2=value2\n');
-      });
-      it('recommendedValue is valid', function () {
-        expect(result[0].recommendedValue).to.equal('config1=value1\nconfig2=value2\n');
-      });
-    });
-
-    describe('three config into textarea', function () {
-      var newConfigs = dummyCopy(configs);
-      newConfigs.push(dummyCopy(c3));
-      var result;
-      beforeEach(function () {
-        result = App.config.fileConfigsIntoTextarea(newConfigs, filename);
-      });
-      it('One config is returned', function () {
-        expect(result.length).to.equal(1);
-      });
-      it('valid is valid', function () {
-        expect(result[0].value).to.equal('config1=value1\nconfig2=value2\nconfig3=value3\n');
-      });
-      it('recommendedValue is valid', function () {
-        expect(result[0].recommendedValue).to.equal('config1=value1\nconfig2=value2\nconfig3=value3\n');
-      });
-    });
-
-    describe('one of three configs has different filename', function () {
-      var newConfigs = dummyCopy(configs);
-      newConfigs.push(dummyCopy(c3));
-      newConfigs[1].filename = 'another filename';
-      var result;
-
-      beforeEach(function () {
-        result = App.config.fileConfigsIntoTextarea(newConfigs, filename);
-      });
-
-      it('Two configs are returned', function () {
-        //result contains two configs: one with different filename and one textarea config
-        expect(result.length).to.equal(2);
-      });
-      it('Value is valid', function () {
-        expect(result[1].value).to.equal('config1=value1\nconfig3=value3\n');
-      });
-      it('RecommendedValue is valid', function () {
-        expect(result[1].recommendedValue).to.equal('config1=value1\nconfig3=value3\n');
-      });
-    });
-
-    describe('none configs into empty textarea', function () {
-      var result;
-      beforeEach(function () {
-        result = App.config.fileConfigsIntoTextarea([], 'capacity-scheduler.xml');
-      });
-      it('One config is returned', function () {
-        expect(result.length).to.equal(1);
-      });
-      it('value is empty', function () {
-        expect(result[0].value).to.equal('');
-      });
-      it('recommendedValue is none', function () {
-        expect(Em.isNone(result[0].recommendedValue)).to.be.true;
-      });
-      it('savedValue is none', function () {
-        expect(Em.isNone(result[0].savedValue)).to.be.true;
-      });
-    });
-
-    describe("filename has configs that shouldn't be included in textarea", function () {
-      var newConfigs = dummyCopy(configs);
-      newConfigs.push(dummyCopy(c3));
-      var result;
-      beforeEach(function () {
-        result = App.config.fileConfigsIntoTextarea(newConfigs, 'capacity-scheduler.xml', [c3]);
-      });
-      it('Two configs are returned', function () {
-        expect(result.length).to.equal(2);
-      });
-      it('value is correct', function () {
-        expect(result[1].value).to.equal('config1=value1\nconfig2=value2\n');
-      });
-      it('recommendedValue is correct', function () {
-        expect(result[1].recommendedValue).to.equal('config1=value1\nconfig2=value2\n');
-      });
-      it('skipped config is correct', function () {
-        expect(newConfigs.findProperty('name', 'config3')).to.eql(c3);
-      });
-    });
-
-  });
-
-  describe('#textareaIntoFileConfigs', function () {
-    var filename = 'capacity-scheduler.xml';
-    var testData = [
-      {
-        configs: [Em.Object.create({
-          "name": "capacity-scheduler",
-          "value": "config1=value1",
-          "filename": "capacity-scheduler.xml",
-          "isRequiredByAgent": true
-        })]
-      },
-      {
-        configs: [Em.Object.create({
-          "name": "capacity-scheduler",
-          "value": "config1=value1\nconfig2=value2\n",
-          "filename": "capacity-scheduler.xml",
-          "isRequiredByAgent": false
-        })]
-      },
-      {
-        configs: [Em.Object.create({
-          "name": "capacity-scheduler",
-          "value": "config1=value1,value2\n",
-          "filename": "capacity-scheduler.xml",
-          "isRequiredByAgent": true
-        })]
-      },
-      {
-        configs: [Em.Object.create({
-          "name": "capacity-scheduler",
-          "value": "config1=value1 config2=value2\n",
-          "filename": "capacity-scheduler.xml",
-          "isRequiredByAgent": false
-        })]
-      }
-    ];
-
-    describe('config1=value1 to one config', function () {
-      var result;
-      beforeEach(function () {
-        result = App.config.textareaIntoFileConfigs(testData[0].configs, filename);
-      });
-      it('One config is returned', function () {
-        expect(result.length).to.equal(1);
-      });
-      it('value is correct', function () {
-        expect(result[0].value).to.equal('value1');
-      });
-      it('name is correct', function () {
-        expect(result[0].name).to.equal('config1');
-      });
-      it('isRequiredByAgent is true', function () {
-        expect(result[0].isRequiredByAgent).to.be.true;
-      });
-    });
-
-    describe('config1=value1\\nconfig2=value2\\n to two configs', function () {
-      var result;
-      beforeEach(function () {
-        result = App.config.textareaIntoFileConfigs(testData[1].configs, filename);
-      });
-      it('Two configs are returned', function (){
-        expect(result.length).to.equal(2);
-      });
-      it('1st value is valid', function (){
-        expect(result[0].value).to.equal('value1');
-      });
-      it('1st name is valid', function (){
-        expect(result[0].name).to.equal('config1');
-      });
-      it('2nd value is valid', function (){
-        expect(result[1].value).to.equal('value2');
-      });
-      it('2nd name is valid', function (){
-        expect(result[1].name).to.equal('config2');
-      });
-      it('1st isRequiredByAgent is false', function (){
-        expect(result[0].isRequiredByAgent).to.be.false;
-      });
-      it('2nd isRequiredByAgent is false', function (){
-        expect(result[1].isRequiredByAgent).to.be.false;
-      });
-    });
-
-    describe('config1=value1,value2\n to one config', function () {
-      var result;
-      beforeEach(function () {
-        result = App.config.textareaIntoFileConfigs(testData[2].configs, filename);
-      });
-      it('One config is returned', function () {
-        expect(result.length).to.equal(1);
-      });
-      it('value is correct', function () {
-        expect(result[0].value).to.equal('value1,value2');
-      });
-      it('name is correct', function () {
-        expect(result[0].name).to.equal('config1');
-      });
-      it('isRequiredByAgent is true', function () {
-        expect(result[0].isRequiredByAgent).to.be.true;
-      });
-    });
-
-    describe('config1=value1 config2=value2 to two configs', function () {
-      var result;
-      beforeEach(function () {
-        result = App.config.textareaIntoFileConfigs(testData[3].configs, filename);
-      });
-      it('One config is returned', function () {
-        expect(result.length).to.equal(1);
-      });
-      it('isRequiredByAgent is false', function () {
-        expect(result[0].isRequiredByAgent).to.be.false;
-      });
-    });
-
-  });
-
   describe('#trimProperty',function() {
     var testMessage = 'displayType `{0}`, value `{1}`{3} should return `{2}`';
     var tests = [