You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by ab...@apache.org on 2014/08/01 18:59:41 UTC

git commit: AMBARI-6714 Step5 skipped during installaton, if only "Tez", "Hive+Hcatalog+WebHCat" services choosen. (Buzhor Denys via ababiichuk)

Repository: ambari
Updated Branches:
  refs/heads/trunk 6961561be -> 99bab6aba


AMBARI-6714 Step5 skipped during installaton, if only "Tez","Hive+Hcatalog+WebHCat" services choosen. (Buzhor Denys via ababiichuk)


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

Branch: refs/heads/trunk
Commit: 99bab6aba6fac63f3a0182d255d34dc9e1c62e29
Parents: 6961561
Author: aBabiichuk <ab...@cybervisiontech.com>
Authored: Fri Aug 1 19:54:52 2014 +0300
Committer: aBabiichuk <ab...@cybervisiontech.com>
Committed: Fri Aug 1 19:59:41 2014 +0300

----------------------------------------------------------------------
 .../app/controllers/wizard/step4_controller.js  | 206 +++++++++---
 .../service/reassign/step2_controller_test.js   |   7 +-
 .../test/controllers/wizard/step4_test.js       | 311 +++++++++++++++----
 ambari-web/test/views/main/host/summary_test.js |   2 +-
 4 files changed, 408 insertions(+), 118 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/99bab6ab/ambari-web/app/controllers/wizard/step4_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/wizard/step4_controller.js b/ambari-web/app/controllers/wizard/step4_controller.js
index 872962d..b4742c2 100644
--- a/ambari-web/app/controllers/wizard/step4_controller.js
+++ b/ambari-web/app/controllers/wizard/step4_controller.js
@@ -38,6 +38,14 @@ App.WizardStep4Controller = Em.ArrayController.extend({
   }.property("@each.isSelected"),
 
   /**
+   * List of validation errors. Look to #createError method for information
+   * regarding object structure.
+   *
+   * @type {Object[]}
+   */
+  errorStack: [],
+
+  /**
    * Check whether all properties are selected
    * @type {bool}
    */
@@ -58,6 +66,12 @@ App.WizardStep4Controller = Em.ArrayController.extend({
   }.property('@each.isSelected'),
 
   /**
+   * Drop errorStack content on selected state changes.
+   **/
+  clearErrors: function() {
+    this.set('errorStack', []);
+  }.observes('@each.isSelected'),
+  /**
    * Onclick handler for <code>select all</code> link
    * @method selectAll
    */
@@ -93,86 +107,169 @@ App.WizardStep4Controller = Em.ArrayController.extend({
   },
 
   /**
-   * Check do we have any monitoring service turned on
-   * @return {bool}
-   * @method gangliaOrNagiosNotSelected
-   */
-  isMonitoringServiceNotSelected: function () {
-    var stackMonitoringServices = this.filterProperty('isMonitoringService',true);
-    return stackMonitoringServices.someProperty('isSelected',false);
-  },
-
-  /**
    * Check whether user turned on monitoring service and go to next step
    * @method validateMonitoring
    */
-  validateMonitoring: function () {
-    var monitoringServices =  this.filterProperty('isMonitoringService',true);
-    var notSelectedService = monitoringServices.filterProperty('isSelected',false);
+  serviceMonitoringValidation: function () {
+    var monitoringServices =  this.filterProperty('isMonitoringService', true);
+    var notSelectedService = monitoringServices.filterProperty('isSelected', false);
     if (!!notSelectedService.length) {
       notSelectedService = stringUtils.getFormattedStringFromArray(notSelectedService.mapProperty('displayNameOnSelectServicePage'));
       monitoringServices = stringUtils.getFormattedStringFromArray(monitoringServices.mapProperty('displayNameOnSelectServicePage'));
-      this.monitoringCheckPopup(notSelectedService,monitoringServices);
-    } else {
-      App.router.send('next');
+      this.addValidationError({
+        id: 'monitoringCheck',
+        type: 'WARNING',
+        callback: this.monitoringCheckPopup,
+        callbackParams: [notSelectedService, monitoringServices]
+      });
     }
   },
 
   /**
-   * Onclick handler for <code>Next</code> button
+   * Onclick handler for <code>Next</code> button.
    * @method submit
    */
   submit: function () {
-    this.setGroupedServices();
-    if (!this.get("isSubmitDisabled") && !this.isSubmitChecksFailed()) {
-      this.validateMonitoring();
+    if (!this.get('isSubmitDisabled')) {
+      if (this.validate()) {
+        this.set('errorStack', []);
+        this.setGroupedServices();
+        App.router.send('next');
+      }
     }
   },
 
   /**
-   * @method  {isSubmitChecksFailed} Do the required checks on Next button click event
-   * @returns {boolean}
-   */
-  isSubmitChecksFailed: function() {
-    return this.isFileSystemCheckFailed() || this.isServiceDependencyCheckFailed();
+   * Check if validation passed:
+   *  - required file system services selected
+   *  - dependencies between services
+   *  - monitoring services selected (not required)
+   *
+   * @return {Boolean}
+   * @method validate
+   **/
+  validate: function() {
+    this.serviceDependencyValidation();
+    this.fileSystemServiceValidation();
+    this.serviceMonitoringValidation();
+    if (!!this.get('errorStack').filterProperty('isShown', false).length) {
+      this.showError(this.get('errorStack').findProperty('isShown', false));
+      return false;
+    }
+    return true;
   },
 
   /**
-   * @method: isFileSystemCheckFailed - Checks if a filesystem is selected and only one filesystem is selected
-   * @return: {boolean}
+   * Create error and push it to stack.
+   *
+   * @param {Object} errorObject - look to #createError
+   * @return {Boolean}
+   * @method addValidationError
+   **/
+  addValidationError: function(errorObject) {
+    if (!this.get('errorStack').mapProperty('id').contains(errorObject.id)) {
+      this.get('errorStack').push(this.createError(errorObject));
+      return true;
+    } else {
+      return false;
+    }
+  },
+
+  /**
+   * Show current error by passed error object.
+   *
+   * @param {Object} errorObject
+   * @method showError
+   **/
+  showError: function(errorObject) {
+    return errorObject.callback.apply(errorObject.callbackContext, errorObject.callbackParams);
+  },
+
+  /**
+   * Default primary button("Ok") callback for warning popups.
+   *  Change isShown state for last shown error.
+   *  Call #submit() method.
+   *
+   *  @method onPrimaryPopupCallback
+   **/
+  onPrimaryPopupCallback: function() {
+    if (this.get('errorStack').someProperty('isShown', false)) {
+      this.get('errorStack').findProperty('isShown', false).isShown = true;
+    }
+    this.submit();
+  },
+
+  /**
+   * Create error object with passed options.
+   * Available options:
+   *  id - {String}
+   *  type - {String}
+   *  isShowed - {Boolean}
+   *  callback - {Function}
+   *  callbackContext
+   *  callbackParams - {Array}
+   *
+   * @param {Object} opt
+   * @return {Object}
+   * @method createError
+   **/
+  createError: function(opt) {
+    var options = {
+      // {String} error identifier
+      id: '',
+      // {String} type of error CRITICAL|WARNING
+      type: 'CRITICAL',
+      // {Boolean} error was shown
+      isShown: false,
+      // {Function} callback to execute
+      callback: null,
+      // context which execute from
+      callbackContext: this,
+      // {Array} params applied to callback
+      callbackParams: []
+    };
+    $.extend(options, opt);
+    return options;
+  },
+
+  /**
+   * Checks if a filesystem is selected and only one filesystem is selected
+   *
+   * @method isFileSystemCheckFailed
    */
-  isFileSystemCheckFailed: function() {
-    var isCheckFailed = false;
+  fileSystemServiceValidation: function() {
     var primaryDFS = this.findProperty('isPrimaryDFS',true);
     var primaryDfsDisplayName = primaryDFS.get('displayNameOnSelectServicePage');
     var primaryDfsServiceName = primaryDFS.get('serviceName');
      if (this.noDFSs()) {
-       isCheckFailed = true;
-       this.needToAddServicePopup.apply(this, [{serviceName: primaryDfsServiceName, selected: true},'fsCheck',primaryDfsDisplayName]);
-     } else if (this.multipleDFSs()) {
+       this.addValidationError({
+         id: 'fsCheck',
+         callback: this.needToAddServicePopup,
+         callbackParams: [{serviceName: primaryDfsServiceName, selected: true},'fsCheck', primaryDfsDisplayName]
+       });
+     }
+     else if (this.multipleDFSs()) {
        var dfsServices = this.filterProperty('isDFS',true).filterProperty('isSelected',true).mapProperty('serviceName');
        var services = dfsServices.map(function (item){
-         var mappedObj = {
+         return  {
            serviceName: item,
-           selected: false
+           selected: item === primaryDfsServiceName
          };
-         if (item ===  primaryDfsServiceName) {
-           mappedObj.selected = true;
-         }
-         return mappedObj;
        });
-       isCheckFailed = true;
-       this.needToAddServicePopup.apply(this, [services,'multipleDFS',primaryDfsDisplayName]);
+       this.addValidationError({
+         id: 'multipleDFS',
+         callback: this.needToAddServicePopup,
+         callbackParams: [services, 'multipleDFS', primaryDfsDisplayName]
+       });
      }
-    return isCheckFailed;
   },
 
   /**
-   * @method: isServiceDependencyCheckFailed - Checks if a dependent service is selected without selecting the main service
-   * @return {boolean}
+   * Checks if a dependent service is selected without selecting the main service.
+   *
+   * @method serviceDependencyValidation
    */
-  isServiceDependencyCheckFailed: function() {
-    var isCheckFailed = false;
+  serviceDependencyValidation: function() {
     var notSelectedServices = this.filterProperty('isSelected',false);
     notSelectedServices.forEach(function(service){
       var showWarningPopup;
@@ -183,17 +280,24 @@ App.WizardStep4Controller = Em.ArrayController.extend({
           var dependentService = this.findProperty('serviceName', _dependentService);
           if (dependentService && dependentService.get('isSelected') === true) {
             showWarningPopup = true;
-            isCheckFailed = true;
           }
         },this);
         if (showWarningPopup) {
-          this.needToAddServicePopup.apply(this, [{serviceName: service.get('serviceName'), selected: true},'serviceCheck',service.get('displayNameOnSelectServicePage')]);
+          this.addValidationError({
+            id: 'serviceCheck_' + service.get('serviceName'),
+            callback: this.needToAddServicePopup,
+            callbackParams: [{serviceName: service.get('serviceName'), selected: true}, 'serviceCheck', service.get('displayNameOnSelectServicePage')]
+          });
         }
       }
     },this);
-    return isCheckFailed;
   },
 
+  /**
+   * Select co hosted services which not showed on UI.
+   *
+   * @method setGroupedServices
+   **/
   setGroupedServices: function() {
     this.forEach(function(service){
       var coSelectedServices = service.get('coSelectedServices');
@@ -204,7 +308,6 @@ App.WizardStep4Controller = Em.ArrayController.extend({
     },this);
   },
 
-
   /**
    * Select/deselect services
    * @param services array of objects
@@ -235,8 +338,8 @@ App.WizardStep4Controller = Em.ArrayController.extend({
         services.forEach(function (service) {
           self.findProperty('serviceName', service.serviceName).set('isSelected', service.selected);
         });
+        self.onPrimaryPopupCallback();
         this.hide();
-        self.submit();
       }
     });
   },
@@ -247,12 +350,13 @@ App.WizardStep4Controller = Em.ArrayController.extend({
    * @method monitoringCheckPopup
    */
   monitoringCheckPopup: function (notSelectedServiceNames,monitoringServicesNames) {
+    var self = this;
     return App.ModalPopup.show({
       header: Em.I18n.t('installer.step4.monitoringCheck.popup.header'),
       body: Em.I18n.t('installer.step4.monitoringCheck.popup.body').format(notSelectedServiceNames,monitoringServicesNames),
       onPrimary: function () {
+        self.onPrimaryPopupCallback();
         this.hide();
-        App.router.send('next');
       }
     });
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/99bab6ab/ambari-web/test/controllers/main/service/reassign/step2_controller_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/main/service/reassign/step2_controller_test.js b/ambari-web/test/controllers/main/service/reassign/step2_controller_test.js
index 67c1d35..5e89c7e 100644
--- a/ambari-web/test/controllers/main/service/reassign/step2_controller_test.js
+++ b/ambari-web/test/controllers/main/service/reassign/step2_controller_test.js
@@ -16,7 +16,7 @@
  * limitations under the License.
  */
 
-App = require('app');
+var App = require('app');
 
 require('controllers/main/service/reassign/step2_controller');
 require('models/host_component');
@@ -37,10 +37,15 @@ describe('App.ReassignMasterWizardStep2Controller', function () {
   describe('#loadStep', function () {
 
     beforeEach(function () {
+      sinon.stub(App.router, 'send', Em.K);
+      sinon.stub(controller, 'loadStepCallback', Em.K);
       sinon.stub(controller, 'rebalanceSingleComponentHosts', Em.K);
     });
+
     afterEach(function () {
       controller.rebalanceSingleComponentHosts.restore();
+      App.router.send.restore();
+      controller.loadStepCallback.restore();
     });
 
     it('SECONDARY_NAMENODE is absent, reassign component is NAMENODE', function () {

http://git-wip-us.apache.org/repos/asf/ambari/blob/99bab6ab/ambari-web/test/controllers/wizard/step4_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/wizard/step4_test.js b/ambari-web/test/controllers/wizard/step4_test.js
index 811c0f7..507a809 100644
--- a/ambari-web/test/controllers/wizard/step4_test.js
+++ b/ambari-web/test/controllers/wizard/step4_test.js
@@ -18,8 +18,9 @@
 
 var Ember = require('ember');
 var App = require('app');
-require('controllers/wizard/step4_controller');
+var modelSetup = require('test/init_model_test');
 
+require('controllers/wizard/step4_controller');
 describe('App.WizardStep4Controller', function () {
 
   var services = [
@@ -28,6 +29,34 @@ describe('App.WizardStep4Controller', function () {
   ];
 
   var controller = App.WizardStep4Controller.create();
+
+  var generateSelectedServicesContent = function(selectedServiceNames) {
+    var allServices = services.slice(0);
+    if (selectedServiceNames.contains('GLUSTERFS')) allServices.push('GLUSTERFS');
+    allServices = allServices.map(function(serviceName) {
+      return [Ember.Object.create({
+        'serviceName': serviceName,
+        'isSelected': false,
+        'canBeSelected': true,
+        'isInstalled': false,
+        isPrimaryDFS: serviceName == 'HDFS',
+        isDFS: ['HDFS','GLUSTERFS'].contains(serviceName),
+        isMonitoringService: ['NAGIOS','GANGLIA'].contains(serviceName),
+        dependentServices: App.StackService.dependency['HDP-2'][serviceName],
+        displayNameOnSelectServicePage: App.format.role(serviceName),
+        coSelectedServices: function() {
+          return App.StackService.coSelected[this.get('serviceName')] || [];
+        }.property('serviceName')
+      })];
+    }).reduce(function(current, prev) { return current.concat(prev); });
+
+    selectedServiceNames.forEach(function(serviceName) {
+      allServices.findProperty('serviceName', serviceName).set('isSelected', true);
+    });
+
+    return allServices;
+  };
+
   services.forEach(function(serviceName, index){
     controller.pushObject(Ember.Object.create({
       'serviceName':serviceName, 'isSelected': true, 'isHiddenOnSelectServicePage': false, 'isInstalled': false, 'isDisabled': 'HDFS' === serviceName, isDFS: 'HDFS' === serviceName
@@ -211,19 +240,181 @@ describe('App.WizardStep4Controller', function () {
     }, this);
   });
 
-  describe('#monitoringCheckPopup', function() {
-    it('should show App.ModalPopup', function() {
-      sinon.spy(App.ModalPopup, 'show');
-      controller.monitoringCheckPopup();
-      expect(App.ModalPopup.show.calledOnce).to.equal(true);
-      App.ModalPopup.show.restore();
+  describe('#addValidationError()', function() {
+    var tests = [
+      {
+        errorObjects: [
+          {
+            id: 'serviceCheck_ZOOKEEPER',
+            shouldBeAdded: true
+          },
+          {
+            id: 'serviceCheck_YARN',
+            shouldBeAdded: true
+          }
+        ],
+        expectedIds: ['serviceCheck_ZOOKEEPER', 'serviceCheck_YARN']
+      },
+      {
+        errorObjects: [
+          {
+            id: 'fsCheck',
+            shouldBeAdded: true
+          },
+          {
+            id: 'fsCheck',
+            shouldBeAdded: false
+          }
+        ],
+        expectedIds: ['fsCheck']
+      }
+    ];
+
+    beforeEach(function() {
+      controller.clear();
+      controller.set('errorStack', []);
     });
-    it('onPrimary should proceed to next step', function() {
+
+    tests.forEach(function(test) {
+      var message = 'Erorrs {0} thrown. errorStack property should contains ids: {1}'
+        .format(test.errorObjects.mapProperty('id').join(', '), test.expectedIds.join(', '));
+      it(message, function() {
+        test.errorObjects.forEach(function(errorObject) {
+          expect(controller.addValidationError(errorObject)).to.equal(errorObject.shouldBeAdded);
+        });
+        expect(controller.get('errorStack').mapProperty('id')).to.eql(test.expectedIds);
+      });
+    })
+  });
+
+  describe('#validate()', function() {
+    var tests = [
+      {
+        services: ['HDFS','ZOOKEEPER'],
+        errorsExpected: ['monitoringCheck']
+      },
+      {
+        services: ['ZOOKEEPER'],
+        errorsExpected: ['fsCheck', 'monitoringCheck']
+      },
+      {
+        services: ['HDFS'],
+        errorsExpected: ['serviceCheck_ZOOKEEPER', 'monitoringCheck']
+      },
+      {
+        services: ['HDFS', 'TEZ', 'ZOOKEEPER'],
+        errorsExpected: ['serviceCheck_YARN', 'monitoringCheck']
+      },
+      {
+        services: ['HDFS', 'ZOOKEEPER', 'FALCON', 'NAGIOS'],
+        errorsExpected: ['serviceCheck_OOZIE', 'monitoringCheck']
+      },
+      {
+        services: ['HDFS', 'ZOOKEEPER', 'GANGLIA', 'NAGIOS', 'HIVE'],
+        errorsExpected: ['serviceCheck_YARN']
+      },
+      {
+        services: ['HDFS', 'GLUSTERFS', 'ZOOKEEPER', 'HIVE'],
+        errorsExpected: ['serviceCheck_YARN', 'multipleDFS', 'monitoringCheck']
+      },
+      {
+        services: ['HDFS','ZOOKEEPER', 'NAGIOS', 'GANGLIA'],
+        errorsExpected: []
+      }
+    ];
+
+    tests.forEach(function(test) {
+      var message = '{0} selected validation should be {1}, errors with ids: {2} present'
+        .format(test.services.join(','), !!test.validationPassed ? 'passed' : 'failed', test.errorsExpected.join(','));
+      it(message, function() {
+        controller.clear();
+        controller.set('content', generateSelectedServicesContent(test.services));
+        controller.validate();
+        expect(controller.get('errorStack').mapProperty('id')).to.be.eql(test.errorsExpected);
+      });
+    })
+  });
+
+  describe('#onPrimaryPopupCallback()', function() {
+    var c;
+    var tests = [
+      {
+        services: ['HDFS','ZOOKEEPER'],
+        confirmPopupCount: 1,
+        errorsExpected: ['monitoringCheck']
+      },
+      {
+        services: ['ZOOKEEPER'],
+        confirmPopupCount: 2,
+        errorsExpected: ['fsCheck', 'monitoringCheck']
+      },
+      {
+        services: ['HDFS', 'GLUSTERFS', 'ZOOKEEPER', 'HIVE'],
+        confirmPopupCount: 3,
+        errorsExpected: ['serviceCheck_YARN', 'serviceCheck_TEZ', 'multipleDFS', 'monitoringCheck']
+      },
+      {
+        services: ['HDFS','ZOOKEEPER', 'NAGIOS', 'GANGLIA'],
+        confirmPopupCount: 0,
+        errorsExpected: []
+      }
+    ];
+
+    beforeEach(function() {
+      c = App.WizardStep4Controller.create({});
       sinon.stub(App.router, 'send', Em.K);
-      controller.monitoringCheckPopup().onPrimary();
-      expect(App.router.send.calledWith('next')).to.equal(true);
+      sinon.stub(c, 'submit', Em.K);
+      sinon.spy(c, 'onPrimaryPopupCallback');
+    });
+
+    afterEach(function() {
       App.router.send.restore();
+      c.submit.restore();
+      c.onPrimaryPopupCallback.restore();
     });
+
+
+    tests.forEach(function(test) {
+      var message = 'Selected services: {0}. {1} errors should be confirmed'
+        .format(test.services.join(', '), test.confirmPopupCount);
+
+      it(message, function() {
+        var runValidations = function() {
+          c.serviceDependencyValidation();
+          c.fileSystemServiceValidation();
+          c.serviceMonitoringValidation();
+        }
+
+        c.set('content', generateSelectedServicesContent(test.services));
+        runValidations();
+        // errors count validation
+        expect(c.get('errorStack.length')).to.equal(test.confirmPopupCount);
+        // if errors detected than it should be shown
+        if (test.errorsExpected) {
+          test.errorsExpected.forEach(function(error, index, errors) {
+            // validate current error
+            var currentErrorObject = c.get('errorStack').findProperty('isShown', false);
+            if (currentErrorObject) {
+              expect(error).to.be.equal(currentErrorObject.id);
+              // show current error
+              var popup = c.showError(currentErrorObject);
+              // submit popup
+              popup.onPrimary();
+              // onPrimaryPopupCallback should be called
+              expect(c.onPrimaryPopupCallback.called).to.equal(true);
+              // submit called
+              expect(c.submit.called).to.equal(true);
+              if (c.get('errorStack').length) {
+                // current error isShown flag changed to true
+                expect(currentErrorObject.isShown).to.equal(true);
+              }
+              runValidations();
+            }
+          });
+        }
+      });
+    });
+
   });
 
   describe('#needToAddServicePopup', function() {
@@ -253,65 +444,55 @@ describe('App.WizardStep4Controller', function () {
       });
   });
 
- describe('#submit', function() {
+  describe('#submit', function() {
+    var c;
+    var tests = [
+      {
+        isSubmitDisabled: true,
+        validate: false,
+        userCanProceed: false
+      },
+      {
+        isSubmitDisabled: false,
+        validate: false,
+        userCanProceed: false
+      },
+      {
+        isSubmitDisabled: false,
+        validate: true,
+        userCanProceed: true
+      }
+    ];
+
     beforeEach(function() {
-      sinon.stub(controller, 'validateMonitoring', Em.K);
-      sinon.stub(controller, 'setGroupedServices', Em.K);
+      c = App.WizardStep4Controller.create();
+      sinon.stub(App.router, 'send', Em.K);
     });
+
     afterEach(function() {
-      controller.validateMonitoring.restore();
-      controller.setGroupedServices.restore();
-    });
-    it('if not isSubmitDisabled shound\'t do nothing', function() {
-      controller.reopen({isSubmitDisabled: true});
-      controller.submit();
-      expect(controller.validateMonitoring.called).to.equal(false);
-    });
-    it('if isSubmitDisabled and not submitChecks should call validateMonitoring', function() {
-      sinon.stub(controller, 'isSubmitChecksFailed', function() { return false; });
-      controller.reopen({
-        isSubmitDisabled: false,
-        submitChecks: []
-      });
-      controller.submit();
-      expect(controller.validateMonitoring.calledOnce).to.equal(true);
-      controller.isSubmitChecksFailed.restore();
-    });
-    it('if isSubmitDisabled and some submitChecks true shouldn\'t call validateMonitoring', function() {
-      controller.reopen({
-        isSubmitDisabled: false,
-        submitChecks: [
-          {
-            popupParams: [
-              {serviceName: 'MAPREDUCE', selected: true},
-              'mapreduceCheck'
-            ]
-          }
-        ]
-      });
-      sinon.stub(controller, 'isSubmitChecksFailed', function() { return true; });
-      controller.submit();
-      controller.isSubmitChecksFailed.restore();
-      expect(controller.validateMonitoring.called).to.equal(false);
+      App.router.send.restore();
     });
-    it('if isSubmitDisabled and some submitChecks false should call validateMonitoring', function() {
-      controller.reopen({
-        isSubmitDisabled: false,
-        submitChecks: [
-          {
-            checkCallback: 'needToAddMapReduce',
-            popupParams: [
-              {serviceName: 'MAPREDUCE', selected: true},
-              'mapreduceCheck'
-            ]
-          }
-        ]
+
+    tests.forEach(function(test) {
+      var messageFormat = [
+        test.isSubmitDisabled ? 'disabled' : 'enabled',
+        test.validate ? 'success' : 'failed',
+        test.userCanProceed ? '' : 'not'
+      ];
+      var message = String.prototype.format.apply('Submit btn: {0}. Validation: {1}. Can{2} move to the next step.', messageFormat);
+
+      it(message, function() {
+        c.reopen({
+          isSubmitDisabled: test.isSubmitDisabled,
+          validate: function() { return test.validate; }
+        });
+        c.clear();
+        c.submit();
+
+        expect(App.router.send.calledOnce).to.equal(test.userCanProceed);
       });
-      sinon.stub(controller, 'isSubmitChecksFailed', function() { return false; });
-      controller.submit();
-      controller.isSubmitChecksFailed.restore();
-      expect(controller.validateMonitoring.calledOnce).to.equal(true);
-    });
+
+    })
   });
 
-});
\ No newline at end of file
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/99bab6ab/ambari-web/test/views/main/host/summary_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/views/main/host/summary_test.js b/ambari-web/test/views/main/host/summary_test.js
index b5637db..95ea90b 100644
--- a/ambari-web/test/views/main/host/summary_test.js
+++ b/ambari-web/test/views/main/host/summary_test.js
@@ -288,7 +288,7 @@ describe('App.MainHostSummaryView', function() {
           ])
         }),
         services: ['HDFS', 'YARN', 'MAPREDUCE2'],
-        e: ['NODEMANAGER', 'CLIENTS'],
+        e: ['MAPREDUCE2_CLIENT', 'NODEMANAGER', 'YARN_CLIENT', 'CLIENTS'],
         m: 'some components are already installed'
       },
       {