ambari-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From onechipore...@apache.org
Subject git commit: AMBARI-3884. Validate string-type dynamic configs in YARN and MR2. (onechiporenko)
Date Tue, 26 Nov 2013 11:53:49 GMT
Updated Branches:
  refs/heads/trunk 275096202 -> e6e7ec1f9


AMBARI-3884. Validate string-type dynamic configs in YARN and MR2. (onechiporenko)


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

Branch: refs/heads/trunk
Commit: e6e7ec1f9b740f4b6dbbd2b6db30122cb292f087
Parents: 2750962
Author: Oleg Nechiporenko <cv_github@yahoo.com>
Authored: Tue Nov 26 13:50:35 2013 +0200
Committer: Oleg Nechiporenko <cv_github@yahoo.com>
Committed: Tue Nov 26 13:53:42 2013 +0200

----------------------------------------------------------------------
 .../validators/mapreduce2_configs_validator.js  |   6 +-
 .../validators/service_configs_validator.js     |  81 +++++++++
 .../service_configs_validator_test.js           | 179 +++++++++++++++++++
 3 files changed, 263 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/e6e7ec1f/ambari-web/app/utils/configs/validators/mapreduce2_configs_validator.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/configs/validators/mapreduce2_configs_validator.js b/ambari-web/app/utils/configs/validators/mapreduce2_configs_validator.js
index c5803d7..a469daa 100644
--- a/ambari-web/app/utils/configs/validators/mapreduce2_configs_validator.js
+++ b/ambari-web/app/utils/configs/validators/mapreduce2_configs_validator.js
@@ -34,11 +34,11 @@ App.MapReduce2ConfigsValidator = App.ServiceConfigsValidator.create({
   },
 
   mapreduceMapJavaOpts: function(config) {
-    return null;
+    return this.validateXmxValue(config);
   },
 
   mapreduceReduceJavaOpts: function(config) {
-    return null;
+    return this.validateXmxValue(config);
   },
 
   mapreduceTaskIoSortMb: function(config) {
@@ -58,7 +58,7 @@ App.MapReduce2ConfigsValidator = App.ServiceConfigsValidator.create({
   },
 
   yarnAppMapreduceAmCommandOpts: function(config) {
-    return null;
+    return this.validateXmxValue(config);
   }
 
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/e6e7ec1f/ambari-web/app/utils/configs/validators/service_configs_validator.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/configs/validators/service_configs_validator.js b/ambari-web/app/utils/configs/validators/service_configs_validator.js
index a14108c..ed8d9a6 100644
--- a/ambari-web/app/utils/configs/validators/service_configs_validator.js
+++ b/ambari-web/app/utils/configs/validators/service_configs_validator.js
@@ -54,6 +54,7 @@ App.ServiceConfigsValidator = Em.Object.extend({
   /**
    * Check if provided <code>config.value</code> is less than <code>recommendedDefaults</code>
    * @param {object} config - configProperty name
+   * @return {string|null}
    */
   validatorLessThenDefaultValue: function(config) {
     var defaultValue = this.get('recommendedDefaults')[config.get('name')];
@@ -66,6 +67,86 @@ App.ServiceConfigsValidator = Em.Object.extend({
       return "Value is less than the recommended default of "+defaultValue;
     }
     return null;
+  },
+
+  /**
+   * Check if provided <code>config.value</code> is less than <code>recommendedDefaults</code>
+   * Value looks like "-Xmx****m"
+   * @param {object} config
+   * @return {string|null}
+   */
+  validateXmxValue: function(config) {
+    var defaultValueRaw = this.get('recommendedDefaults')[config.get('name')];
+    var currentValueRaw = config.get('value');
+    if (!this._checkXmxValueFormat(currentValueRaw)) {
+      return 'Invalid value format';
+    }
+    var currentValue = this._formatXmxSizeToBytes(this._getXmxSize(currentValueRaw));
+    var defaultValue = this._formatXmxSizeToBytes(this._getXmxSize(defaultValueRaw));
+    if (currentValue < defaultValue) {
+      return "Value is less than the recommended default of " + defaultValueRaw;
+    }
+    return null;
+  },
+  /**
+   * Verify if provided value has proper format (should be like "-Xmx***(b|k|m|g|p|t|B|K|M|G|P|T)")
+   * @param  {string} value
+   * @returns {boolean}
+   * @private
+   */
+  _checkXmxValueFormat: function(value) {
+    var regex = /^\-Xmx(\d+)(b|k|m|g|p|t|B|K|M|G|P|T)?(\s+)?(\s.+)?$/;
+    if (!regex.test(value)) {
+      return false;
+    }
+    // "-Xmx" can be only one
+    if (value.match(/\-Xmx/ig).length != 1) {
+      return false;
+    }
+    return true;
+  },
+  /**
+   * Parse Xmx size from raw value
+   * @param {string} value
+   * @returns {string}
+   * @private
+   */
+  _getXmxSize: function(value) {
+    var regex = /\-Xmx(\d+)(.?)/;
+    var result = regex.exec(value);
+    if (result.length > 1) {
+      // result[2] - is a space or size formatter (b|k|m|g etc)
+      return result[1] + result[2].toLowerCase();
+    }
+    return result[1];
+  },
+  /**
+   * Calculate bytes size from value
+   * @param {string} value
+   * @returns {int}
+   * @private
+   */
+  _formatXmxSizeToBytes: function(value) {
+    value = value.toLowerCase();
+    if (value.length == 0) {
+      return 0;
+    }
+    var modifier = value[value.length - 1];
+    if (modifier == ' ' || "0123456789".indexOf(modifier) != -1) {
+      modifier = 'b';
+    }
+    var m = 1;
+    switch (modifier) {
+      case 'b': m = 1; break;
+      case 'k': m = 1024; break;
+      case 'm': m = 1024 * 1024; break;
+      case 'g': m = 1024 * 1024 * 1024; break;
+      case 't': m = 1024 * 1024 * 1024 * 1024; break;
+      case 'p': m = 1024 * 1024 * 1024 * 1024 * 1024; break;
+    }
+    var result = parseInt(value.replace(modifier, '').trim());
+    result *= m;
+    return result;
   }
 
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/e6e7ec1f/ambari-web/test/utils/configs/validators/service_configs_validator_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/utils/configs/validators/service_configs_validator_test.js b/ambari-web/test/utils/configs/validators/service_configs_validator_test.js
index 744053f..3fbe2e5 100644
--- a/ambari-web/test/utils/configs/validators/service_configs_validator_test.js
+++ b/ambari-web/test/utils/configs/validators/service_configs_validator_test.js
@@ -78,4 +78,183 @@ describe('App.ServiceConfigsValidator', function() {
     });
   });
 
+  describe('#_checkXmxValueFormat', function() {
+    var tests = [
+      {value: '',e: false},
+      {value: '-',e: false},
+      {value: '100',e: false},
+      {value: '-Xmx',e: false},
+      {value: '-XMX1',e: false},
+      {value: '-Xmxb',e: false},
+      {value: '-Xmxk',e: false},
+      {value: '-Xmxm',e: false},
+      {value: '-Xmxg',e: false},
+      {value: '-Xmxp',e: false},
+      {value: '-Xmxt',e: false},
+      {value: '-XmxB',e: false},
+      {value: '-XmxK',e: false},
+      {value: '-XmxM',e: false},
+      {value: '-XmxG',e: false},
+      {value: '-XmxP',e: false},
+      {value: '-XmxT',e: false},
+      {value: '-Xmx1',e: true},
+      {value: '-Xmx1b',e: true},
+      {value: '-Xmx1k',e: true},
+      {value: '-Xmx1m',e: true},
+      {value: '-Xmx1g',e: true},
+      {value: '-Xmx1t',e: true},
+      {value: '-Xmx1p',e: true},
+      {value: '-Xmx1B',e: true},
+      {value: '-Xmx1K',e: true},
+      {value: '-Xmx1M',e: true},
+      {value: '-Xmx1G',e: true},
+      {value: '-Xmx1T',e: true},
+      {value: '-Xmx1P',e: true},
+      {value: '-Xmx100',e: true},
+      {value: '-Xmx100b',e: true},
+      {value: '-Xmx100k',e: true},
+      {value: '-Xmx100m',e: true},
+      {value: '-Xmx100g',e: true},
+      {value: '-Xmx100t',e: true},
+      {value: '-Xmx100p',e: true},
+      {value: '-Xmx100B',e: true},
+      {value: '-Xmx100K',e: true},
+      {value: '-Xmx100M',e: true},
+      {value: '-Xmx100G',e: true},
+      {value: '-Xmx100T',e: true},
+      {value: '-Xmx100P',e: true},
+      {value: '-Xmx100Psome',e: false},
+      {value: '-Xmx100P-Xmx',e: false},
+      {value: '-Xmx100P -Xmx',e: false},
+      {value: '-Xmx100P -XMX',e: false}
+    ];
+    tests.forEach(function(test) {
+      it(test.value, function() {
+        var v = App.ServiceConfigsValidator.create({});
+        expect(v._checkXmxValueFormat(test.value)).to.equal(test.e);
+      });
+    });
+  });
+
+  describe('#_getXmxSize', function() {
+    var tests = [
+      {value: '-Xmx1', e: '1'},
+      {value: '-Xmx1b', e: '1b'},
+      {value: '-Xmx1k', e: '1k'},
+      {value: '-Xmx1m', e: '1m'},
+      {value: '-Xmx1g', e: '1g'},
+      {value: '-Xmx1t', e: '1t'},
+      {value: '-Xmx1p', e: '1p'},
+      {value: '-Xmx1B', e: '1b'},
+      {value: '-Xmx1K', e: '1k'},
+      {value: '-Xmx1M', e: '1m'},
+      {value: '-Xmx1G', e: '1g'},
+      {value: '-Xmx1T', e: '1t'},
+      {value: '-Xmx1P', e: '1p'},
+      {value: '-Xmx100b', e: '100b'},
+      {value: '-Xmx100k', e: '100k'},
+      {value: '-Xmx100m', e: '100m'},
+      {value: '-Xmx100g', e: '100g'},
+      {value: '-Xmx100t', e: '100t'},
+      {value: '-Xmx100p', e: '100p'},
+      {value: '-Xmx100B', e: '100b'},
+      {value: '-Xmx100K', e: '100k'},
+      {value: '-Xmx100M', e: '100m'},
+      {value: '-Xmx100G', e: '100g'},
+      {value: '-Xmx100T', e: '100t'},
+      {value: '-Xmx100P', e: '100p'}
+    ];
+    tests.forEach(function(test) {
+      it(test.value, function() {
+        var v = App.ServiceConfigsValidator.create({});
+        expect(v._getXmxSize(test.value)).to.equal(test.e);
+      });
+    });
+  });
+
+  describe('#_formatXmxSizeToBytes', function() {
+    var tests = [
+      {value: '1', e: 1},
+      {value: '1 ', e: 1},
+      {value: '100', e: 100},
+      {value: '100 ', e: 100},
+      {value: '100b', e: 100},
+      {value: '100B', e: 100},
+      {value: '100k', e: 100 * 1024},
+      {value: '100K', e: 100 * 1024},
+      {value: '100m', e: 100 * 1024 * 1024},
+      {value: '100M', e: 100 * 1024 * 1024},
+      {value: '100g', e: 100 * 1024 * 1024 * 1024},
+      {value: '100G', e: 100 * 1024 * 1024 * 1024},
+      {value: '100t', e: 100 * 1024 * 1024 * 1024 * 1024},
+      {value: '100T', e: 100 * 1024 * 1024 * 1024 * 1024},
+      {value: '100p', e: 100 * 1024 * 1024 * 1024 * 1024 * 1024},
+      {value: '100P', e: 100 * 1024 * 1024 * 1024 * 1024 * 1024}
+    ];
+    tests.forEach(function(test) {
+      it(test.value, function() {
+        var v = App.ServiceConfigsValidator.create({});
+        expect(v._formatXmxSizeToBytes(test.value)).to.equal(test.e);
+      });
+    });
+  });
+
+  describe('#validateXmxValue', function() {
+    var tests = [
+      {
+        recommendedDefaults: {
+          'property1': '-Xmx1024m'
+        },
+        config: Em.Object.create({
+          value: '-Xmx2g',
+          name: 'property1'
+        }),
+        e: null
+      },
+      {
+        recommendedDefaults: {
+          'property1': '-Xmx12'
+        },
+        config: Em.Object.create({
+          value: '-Xmx24',
+          name: 'property1'
+        }),
+        e: null
+      },
+      {
+        recommendedDefaults: {
+          'property1': '-Xmx333k'
+        },
+        config: Em.Object.create({
+          value: '-Xmx134k',
+          name: 'property1'
+        }),
+        e: 'string'
+      },
+      {
+        recommendedDefaults: {
+          'property1': '-Xmx333k'
+        },
+        config: Em.Object.create({
+          value: '-Xmx534',
+          name: 'property1'
+        }),
+        e: 'string'
+      }
+    ];
+    tests.forEach(function(test) {
+      it(test.config.get('value'), function() {
+        var v = App.ServiceConfigsValidator.create({});
+        v.set('recommendedDefaults', test.recommendedDefaults);
+        var r = v.validateXmxValue(test.config);
+        if (test.e) {
+          expect(r).to.be.a(test.e);
+        }
+        else {
+          expect(r).to.equal(null)
+        }
+      });
+    });
+  });
+
 });


Mime
View raw message