瀏覽代碼

AMBARI-12591. Upon failure RU should allow clicking into the last stage that has failures
(alexantonenko)

Alex Antonenko 10 年之前
父節點
當前提交
9e7d0d5189

+ 19 - 4
ambari-web/app/controllers/main/admin/stack_and_upgrade_controller.js

@@ -135,6 +135,12 @@ App.MainAdminStackAndUpgradeController = Em.Controller.extend(App.LocalStorage,
    */
   skippedServiceChecks: [],
 
+  /**
+   * status of tasks/items/groups which should be grayed out and disabled
+   * @type {Array}
+   */
+  nonActiveStates: ['PENDING', 'ABORTED'],
+
   init: function () {
     this.initDBProperties();
   },
@@ -231,6 +237,7 @@ App.MainAdminStackAndUpgradeController = Em.Controller.extend(App.LocalStorage,
    */
   updateUpgradeData: function (newData) {
     var oldData = this.get('upgradeData'),
+      nonActiveStates = this.get('nonActiveStates'),
       groupsMap = {},
       itemsMap = {};
 
@@ -253,7 +260,11 @@ App.MainAdminStackAndUpgradeController = Em.Controller.extend(App.LocalStorage,
         oldGroup.upgradeItems.forEach(function (item) {
           item.set('status', itemsMap[item.get('stage_id')].status);
           item.set('progress_percent', itemsMap[item.get('stage_id')].progress_percent);
-        })
+        });
+        var hasExpandableItems = oldGroup.upgradeItems.some(function (item) {
+          return !nonActiveStates.contains(item.get('status'));
+        });
+        oldGroup.set('hasExpandableItems', hasExpandableItems);
       });
       oldData.set('Upgrade', newData.Upgrade);
     }
@@ -266,12 +277,16 @@ App.MainAdminStackAndUpgradeController = Em.Controller.extend(App.LocalStorage,
    * @param {object} newData
    */
   initUpgradeData: function (newData) {
-    var upgradeGroups = [];
+    var upgradeGroups = [],
+      nonActiveStates = this.get('nonActiveStates');
 
     //wrap all entities into App.upgradeEntity
     newData.upgrade_groups.forEach(function (newGroup) {
-      var oldGroup = App.upgradeEntity.create({type: 'GROUP'}, newGroup.UpgradeGroup);
-      var upgradeItems = [];
+      var hasExpandableItems = newGroup.upgrade_items.some(function (item) {
+          return !nonActiveStates.contains(item.UpgradeItem.status);
+        }),
+        oldGroup = App.upgradeEntity.create({type: 'GROUP', hasExpandableItems: hasExpandableItems}, newGroup.UpgradeGroup),
+        upgradeItems = [];
       newGroup.upgrade_items.forEach(function (item) {
         var oldItem = App.upgradeEntity.create({type: 'ITEM'}, item.UpgradeItem);
         oldItem.set('tasks', []);

+ 20 - 1
ambari-web/app/models/upgrade_entity.js

@@ -34,6 +34,11 @@ App.upgradeEntity = Em.Object.extend({
    */
   isExpanded: false,
 
+  /**
+   * @type {boolean}
+   */
+  hasExpandableItems: false,
+
   /**
    * @type {boolean}
    */
@@ -67,5 +72,19 @@ App.upgradeEntity = Em.Object.extend({
    */
   isActive: function () {
     return !this.get('nonActiveStates').contains(this.get('status'));
-  }.property('status')
+  }.property('status'),
+
+  /**
+   * indicate whether upgrade group should be expanded
+   * @type {boolean}
+   */
+  isExpandableGroup: function () {
+    return this.get('type') === 'GROUP' && (this.get('isActive') || this.get('hasExpandableItems'));
+  }.property('isActive', 'hasExpandableItems'),
+
+  upgradeGroupStatus: function () {
+    if (this.get('type') === 'GROUP') {
+      return !this.get('isActive') && this.get('hasExpandableItems') ? 'SUBITEM_FAILED' : this.get('status');
+    }
+  }.property('isExpandableGroup')
 });

+ 2 - 2
ambari-web/app/templates/main/admin/stack_upgrade/upgrade_group.hbs

@@ -18,8 +18,8 @@
 
 
 <div class="row-fluid">
-  <div {{bindAttr class="view.content.isActive::not-active-link :span8"}}>
-    {{statusIcon view.content.status}}
+  <div {{bindAttr class="view.content.isExpandableGroup::not-active-link :span8"}}>
+    {{statusIcon view.content.upgradeGroupStatus}}
     <a href="#" {{action toggleExpanded view.content controller.upgradeData.upgradeGroups target="view"}}>{{view.content.title}}</a>
   </div>
   {{#if view.content.isRunning}}

+ 4 - 3
ambari-web/app/utils/helper.js

@@ -309,7 +309,7 @@ App.isEmptyObject = function(obj) {
   var empty = true;
   for (var prop in obj) { if (obj.hasOwnProperty(prop)) {empty = false; break;} }
   return empty;
-}
+};
 
 /**
  * Convert object under_score keys to camelCase
@@ -715,7 +715,7 @@ App.registerBoundHelper('pluralize', Em.View.extend({
       case 'controller':
         return Em.get(this, value);
       case 'view':
-        return Em.get(this, value.replace(/^view/, 'parentView'))
+        return Em.get(this, value.replace(/^view/, 'parentView'));
       default:
         break;
     }
@@ -809,7 +809,8 @@ App.registerBoundHelper('statusIcon', Em.View.extend({
     'HOLDING': 'icon-pause',
     'ABORTED': 'icon-minus aborted',
     'TIMEDOUT': 'icon-time timedout',
-    'HOLDING_TIMEDOUT': 'icon-time timedout'
+    'HOLDING_TIMEDOUT': 'icon-time timedout',
+    'SUBITEM_FAILED': 'icon-remove failed'
   },
 
   classNameBindings: ['iconClass'],

+ 73 - 5
ambari-web/test/controllers/main/admin/stack_and_upgrade_controller_test.js

@@ -537,6 +537,17 @@ describe('App.MainAdminStackAndUpgradeController', function() {
                 stage_id: 1
               })
             ]
+          }),
+          Em.Object.create({
+            group_id: 2,
+            upgradeItems: [
+              Em.Object.create({
+                stage_id: 2
+              }),
+              Em.Object.create({
+                stage_id: 3
+              })
+            ]
           })
         ]
       });
@@ -561,6 +572,30 @@ describe('App.MainAdminStackAndUpgradeController', function() {
                 }
               }
             ]
+          },
+          {
+            UpgradeGroup: {
+              group_id: 2,
+              status: 'ABORTED',
+              progress_percent: 50,
+              completed_task_count: 1
+            },
+            upgrade_items: [
+              {
+                UpgradeItem: {
+                  stage_id: 2,
+                  status: 'ABORTED',
+                  progress_percent: 99
+                }
+              },
+              {
+                UpgradeItem: {
+                  stage_id: 3,
+                  status: 'PENDING',
+                  progress_percent: 0
+                }
+              }
+            ]
           }
         ]
       };
@@ -571,6 +606,15 @@ describe('App.MainAdminStackAndUpgradeController', function() {
       expect(controller.get('upgradeData.upgradeGroups')[0].get('completed_task_count')).to.equal(3);
       expect(controller.get('upgradeData.upgradeGroups')[0].get('upgradeItems')[0].get('status')).to.equal('COMPLETED');
       expect(controller.get('upgradeData.upgradeGroups')[0].get('upgradeItems')[0].get('progress_percent')).to.equal(100);
+      expect(controller.get('upgradeData.upgradeGroups')[0].get('hasExpandableItems')).to.be.true;
+      expect(controller.get('upgradeData.upgradeGroups')[1].get('status')).to.equal('ABORTED');
+      expect(controller.get('upgradeData.upgradeGroups')[1].get('progress_percent')).to.equal(50);
+      expect(controller.get('upgradeData.upgradeGroups')[1].get('completed_task_count')).to.equal(1);
+      expect(controller.get('upgradeData.upgradeGroups')[1].get('upgradeItems')[0].get('status')).to.equal('ABORTED');
+      expect(controller.get('upgradeData.upgradeGroups')[1].get('upgradeItems')[1].get('status')).to.equal('PENDING');
+      expect(controller.get('upgradeData.upgradeGroups')[1].get('upgradeItems')[0].get('progress_percent')).to.equal(99);
+      expect(controller.get('upgradeData.upgradeGroups')[1].get('upgradeItems')[1].get('progress_percent')).to.equal(0);
+      expect(controller.get('upgradeData.upgradeGroups')[1].get('hasExpandableItems')).to.be.false;
     });
   });
 
@@ -588,7 +632,8 @@ describe('App.MainAdminStackAndUpgradeController', function() {
             upgrade_items: [
               {
                 UpgradeItem: {
-                  stage_id: 1
+                  stage_id: 1,
+                  status: 'IN_PROGRESS'
                 }
               },
               {
@@ -603,15 +648,38 @@ describe('App.MainAdminStackAndUpgradeController', function() {
               group_id: 2
             },
             upgrade_items: []
+          },
+          {
+            UpgradeGroup: {
+              group_id: 3
+            },
+            upgrade_items: [
+              {
+                UpgradeItem: {
+                  stage_id: 3,
+                  status: 'ABORTED'
+                }
+              },
+              {
+                UpgradeItem: {
+                  stage_id: 4,
+                  status: 'PENDING'
+                }
+              }
+            ]
           }
         ]
       };
       controller.initUpgradeData(newData);
       expect(controller.get('upgradeData.Upgrade.request_id')).to.equal(1);
-      expect(controller.get('upgradeData.upgradeGroups')[0].get('group_id')).to.equal(2);
-      expect(controller.get('upgradeData.upgradeGroups')[1].get('group_id')).to.equal(1);
-      expect(controller.get('upgradeData.upgradeGroups')[1].get('upgradeItems')[0].get('stage_id')).to.equal(2);
-      expect(controller.get('upgradeData.upgradeGroups')[1].get('upgradeItems')[1].get('stage_id')).to.equal(1);
+      expect(controller.get('upgradeData.upgradeGroups')[0].get('group_id')).to.equal(3);
+      expect(controller.get('upgradeData.upgradeGroups')[1].get('group_id')).to.equal(2);
+      expect(controller.get('upgradeData.upgradeGroups')[2].get('group_id')).to.equal(1);
+      expect(controller.get('upgradeData.upgradeGroups')[2].get('upgradeItems')[0].get('stage_id')).to.equal(2);
+      expect(controller.get('upgradeData.upgradeGroups')[2].get('upgradeItems')[1].get('stage_id')).to.equal(1);
+      expect(controller.get('upgradeData.upgradeGroups')[0].get('hasExpandableItems')).to.be.false;
+      expect(controller.get('upgradeData.upgradeGroups')[1].get('hasExpandableItems')).to.be.false;
+      expect(controller.get('upgradeData.upgradeGroups')[2].get('hasExpandableItems')).to.be.true;
     });
   });
 

+ 110 - 1
ambari-web/test/models/upgrade_entity_test.js

@@ -20,7 +20,11 @@ var App = require('app');
 require('models/upgrade_entity');
 
 describe('App.upgradeEntity', function () {
-  var model = App.upgradeEntity.create();
+  var model;
+
+  beforeEach(function () {
+    model = App.upgradeEntity.create();
+  });
 
   describe("#isRunning", function() {
     it("status IN_PROGRESS", function() {
@@ -60,4 +64,109 @@ describe('App.upgradeEntity', function () {
       expect(model.get('isActive')).to.be.false;
     });
   });
+
+  describe('#isExpandableGroup', function () {
+
+    var cases = [
+      {
+        input: {
+          type: 'ITEM'
+        },
+        isExpandableGroup: false,
+        title: 'not upgrade group'
+      },
+      {
+        input: {
+          type: 'GROUP',
+          status: 'PENDING',
+          hasExpandableItems: false
+        },
+        isExpandableGroup: false,
+        title: 'pending upgrade group without expandable items'
+      },
+      {
+        input: {
+          type: 'GROUP',
+          status: 'ABORTED',
+          hasExpandableItems: false
+        },
+        isExpandableGroup: false,
+        title: 'aborted upgrade group without expandable items'
+      },
+      {
+        input: {
+          type: 'GROUP',
+          status: 'ABORTED',
+          hasExpandableItems: true
+        },
+        isExpandableGroup: true,
+        title: 'aborted upgrade group with expandable items'
+      },
+      {
+        input: {
+          type: 'GROUP',
+          status: 'IN_PROGRESS',
+          hasExpandableItems: false
+        },
+        isExpandableGroup: true,
+        title: 'active upgrade group'
+      }
+    ];
+
+    cases.forEach(function (item) {
+      it(item.title, function () {
+        model.setProperties(item.input);
+        expect(model.get('isExpandableGroup')).to.equal(item.isExpandableGroup);
+      });
+    });
+
+  });
+
+  describe('#upgradeGroupStatus', function () {
+
+    var cases = [
+      {
+        input: {
+          type: 'ITEM'
+        },
+        upgradeGroupStatus: undefined,
+        title: 'not upgrade group'
+      },
+      {
+        input: {
+          type: 'GROUP',
+          status: 'PENDING',
+          hasExpandableItems: false
+        },
+        upgradeGroupStatus: 'PENDING',
+        title: 'pending upgrade group'
+      },
+      {
+        input: {
+          type: 'GROUP',
+          status: 'ABORTED',
+          hasExpandableItems: true
+        },
+        upgradeGroupStatus: 'SUBITEM_FAILED',
+        title: 'aborted upgrade group with expandable items'
+      },
+      {
+        input: {
+          type: 'GROUP',
+          status: 'IN_PROGRESS',
+          hasExpandableItems: false
+        },
+        upgradeGroupStatus: 'IN_PROGRESS',
+        title: 'active upgrade'
+      }
+    ];
+
+    cases.forEach(function (item) {
+      it(item.title, function () {
+        model.setProperties(item.input);
+        expect(model.get('upgradeGroupStatus')).to.equal(item.upgradeGroupStatus);
+      });
+    });
+
+  });
 });