소스 검색

AMBARI-10755 NodeManager Disk and Network widget appears blank. (atkach)

Andrii Tkach 10 년 전
부모
커밋
efb9235474

+ 2 - 0
ambari-web/app/assets/test/tests.js

@@ -86,6 +86,7 @@ var files = ['test/init_model_test',
   'test/controllers/main/service/reassign/step4_controller_test',
   'test/controllers/main/service/reassign/step6_controller_test',
   'test/controllers/main/service/reassign/step7_controller_test',
+  'test/controllers/main/service/widgets/create/step1_controller_test',
   'test/controllers/main/dashboard_test',
   'test/controllers/main/host_test',
   'test/controllers/main/service/item_test',
@@ -176,6 +177,7 @@ var files = ['test/init_model_test',
   'test/views/common/sort_view_test',
   'test/views/common/custom_date_popup_test',
   'test/views/common/progress_bar_view_test',
+  'test/views/common/widget/graph_widget_view_test',
   'test/views/main/admin_test',
   'test/views/main/dashboard_test',
   'test/views/main/menu_test',

+ 4 - 0
ambari-web/app/controllers/main/service/widgets/create/step1_controller.js

@@ -54,6 +54,10 @@ App.WidgetWizardStep1Controller = Em.Controller.extend({
     });
   }.property('widgetType'),
 
+  /**
+   * choose widget type and proceed to the next step
+   * @param {object} event
+   */
   chooseOption: function (event) {
     this.set('widgetType', event.context);
     this.next();

+ 7 - 0
ambari-web/app/controllers/main/service/widgets/create/step2_controller.js

@@ -75,6 +75,13 @@ App.WidgetWizardStep2Controller = Em.Controller.extend({
    */
   widgetPropertiesViews: [],
 
+  /**
+   * @type {boolean}
+   */
+  isEditWidget: function () {
+    return this.get('content.controllerName') === 'widgetEditController';
+  }.property('content.controllerName'),
+
   /**
    * metrics filtered by type
    * @type {Array}

+ 3 - 1
ambari-web/app/templates/main/service/widgets/create/step2.hbs

@@ -49,7 +49,9 @@
 
 
   <div class="btn-area">
-    <button id="add-widget-step2-back" class="btn" {{action back}}>&larr; {{t common.back}}</button>
+    {{#unless isEditWidget}}
+      <button id="add-widget-step2-back" class="btn" {{action back}}>&larr; {{t common.back}}</button>
+    {{/unless}}
     <button id="add-widget-step2-next" class="btn btn-success pull-right" {{bindAttr disabled="isSubmitDisabled"}} {{action "next" target="controller"}}>{{t common.next}} &rarr;</button>
   </div>
 </div>

+ 36 - 3
ambari-web/app/views/common/widget/graph_widget_view.js

@@ -84,15 +84,19 @@ App.GraphWidgetView = Em.View.extend(App.WidgetMixin, {
     var validExpression = true,
       value = [],
       dataLinks = {},
-      dataLength = 0,
+      dataLength = -1,
       beforeCompute,
-      result = {};
+      result = {},
+      isDataCorrupted = false;
 
     //replace values with metrics data
     expression.match(this.get('VALUE_NAME_REGEX')).forEach(function (match) {
       if (metrics.someProperty('name', match)) {
         dataLinks[match] = metrics.findProperty('name', match).data;
-        dataLength = metrics.findProperty('name', match).data.length;
+        if (!isDataCorrupted) {
+          isDataCorrupted = (dataLength !== -1 && dataLength !== dataLinks[match].length);
+        }
+        dataLength = (dataLinks[match].length > dataLength) ? dataLinks[match].length : dataLength;
       } else {
         validExpression = false;
         console.error('Metrics with name "' + match + '" not found to compute expression');
@@ -100,6 +104,9 @@ App.GraphWidgetView = Em.View.extend(App.WidgetMixin, {
     });
 
     if (validExpression) {
+      if (isDataCorrupted) {
+        this.adjustData(dataLinks, dataLength);
+      }
       for (var i = 0, timestamp; i < dataLength; i++) {
         beforeCompute = expression.replace(this.get('VALUE_NAME_REGEX'), function (match) {
           timestamp = dataLinks[match][i][1];
@@ -113,6 +120,32 @@ App.GraphWidgetView = Em.View.extend(App.WidgetMixin, {
     return result;
   },
 
+  /**
+   *  add missing points, with zero value, to series
+   *
+   * @param {object} dataLinks
+   * @param {number} length
+   */
+  adjustData: function(dataLinks, length) {
+    //series with full data taken as original
+    var original = [];
+    var substituteValue = 0;
+
+    for (var i in dataLinks) {
+      if (dataLinks[i].length === length) {
+        original = dataLinks[i];
+        break;
+      }
+    }
+    original.forEach(function(point, index) {
+      for (var i in dataLinks) {
+        if (!dataLinks[i][index] || dataLinks[i][index][1] !== point[1]) {
+          dataLinks[i].splice(index, 0, [substituteValue, point[1]]);
+        }
+      }
+    }, this);
+  },
+
   /**
    * make GET call to server in order to fetch service-component metrics
    * @param {object} request

+ 89 - 0
ambari-web/test/controllers/main/service/widgets/create/step1_controller_test.js

@@ -0,0 +1,89 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+App = require('app');
+
+require('controllers/main/service/widgets/create/step1_controller');
+
+
+describe('App.WidgetWizardStep1Controller', function () {
+  var controller = App.WidgetWizardStep1Controller.create();
+
+  describe("#isSubmitDisabled", function() {
+    it("disabled", function() {
+      controller.set('widgetType', '');
+      controller.propertyDidChange('isSubmitDisabled');
+      expect(controller.get('isSubmitDisabled')).to.be.true;
+    });
+    it("enabled", function() {
+      controller.set('widgetType', 'w1');
+      controller.propertyDidChange('isSubmitDisabled');
+      expect(controller.get('isSubmitDisabled')).to.be.false;
+    });
+  });
+
+  describe("#chooseOption()", function () {
+    before(function () {
+      sinon.stub(controller, 'next');
+    });
+    after(function () {
+      controller.next.restore();
+    });
+    it("", function () {
+      controller.chooseOption({context: 'type1'});
+      expect(controller.get('widgetType')).to.equal('type1');
+      expect(controller.next.calledOnce).to.be.true;
+    });
+  });
+
+  describe("#loadStep()", function () {
+    before(function () {
+      sinon.stub(controller, 'clearStep');
+    });
+    after(function () {
+      controller.clearStep.restore();
+    });
+    it("", function () {
+      controller.loadStep();
+      expect(controller.clearStep.calledOnce).to.be.true;
+    });
+  });
+
+  describe("#clearStep()", function () {
+    it("", function () {
+      controller.clearStep();
+      expect(controller.get('widgetType')).to.be.empty;
+    });
+  });
+
+  describe("#next()", function () {
+    before(function () {
+      sinon.stub(App.router, 'send');
+    });
+    after(function () {
+      App.router.send.restore();
+    });
+    it("", function () {
+      controller.next();
+      expect(App.router.send.calledWith('next')).to.be.true;
+    });
+  });
+
+
+
+});

+ 129 - 0
ambari-web/test/views/common/widget/graph_widget_view_test.js

@@ -0,0 +1,129 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+require('views/common/widget/graph_widget_view');
+
+describe('App.GraphWidgetView', function () {
+  var view = App.GraphWidgetView.create();
+
+  describe("#adjustData()", function() {
+    var testCases = [
+      {
+        title: 'empty data',
+        data: {
+          dataLinks: {},
+          dataLength: 0
+        },
+        result: {}
+      },
+      {
+        title: 'correct data',
+        data: {
+          dataLinks: {
+            s1: [[0, 0]]
+          },
+          dataLength: 1
+        },
+        result:  {
+          s1: [[0, 0]]
+        }
+      },
+      {
+        title: 'second series empty',
+        data: {
+          dataLinks: {
+            s1: [[1, 0]],
+            s2: []
+          },
+          dataLength: 1
+        },
+        result:  {
+          s1: [[1, 0]],
+          s2: [[0, 0]]
+        }
+      },
+      {
+        title: 'second series missing data at the end',
+        data: {
+          dataLinks: {
+            s1: [[1, 0], [2, 1], [3, 2]],
+            s2: [[1, 0]]
+          },
+          dataLength: 3
+        },
+        result:  {
+          s1: [[1, 0], [2, 1], [3, 2]],
+          s2: [[1, 0], [0, 1], [0, 2]]
+        }
+      },
+      {
+        title: 'second series missing data at the beginning',
+        data: {
+          dataLinks: {
+            s1: [[1, 0], [2, 1], [3, 2]],
+            s2: [[3, 2]]
+          },
+          dataLength: 3
+        },
+        result:  {
+          s1: [[1, 0], [2, 1], [3, 2]],
+          s2: [[0, 0], [0, 1], [3, 2]]
+        }
+      },
+      {
+        title: 'second series missing data in the middle',
+        data: {
+          dataLinks: {
+            s1: [[1, 0], [2, 1], [3, 2]],
+            s2: [[1, 1]]
+          },
+          dataLength: 3
+        },
+        result:  {
+          s1: [[1, 0], [2, 1], [3, 2]],
+          s2: [[0, 0], [1, 1], [0, 2]]
+        }
+      },
+      {
+        title: 'second and third series missing data',
+        data: {
+          dataLinks: {
+            s1: [[1, 0], [2, 1], [3, 2]],
+            s2: [[1, 1]],
+            s3: [[1, 2]]
+          },
+          dataLength: 3
+        },
+        result:  {
+          s1: [[1, 0], [2, 1], [3, 2]],
+          s2: [[0, 0], [1, 1], [0, 2]],
+          s3: [[0, 0], [0, 1], [1, 2]]
+        }
+      }
+    ];
+
+    testCases.forEach(function (test) {
+      it(test.title, function () {
+        view.adjustData(test.data.dataLinks, test.data.dataLength);
+        expect(test.data.dataLinks).to.eql(test.result);
+      });
+    });
+  });
+
+});