瀏覽代碼

AMBARI-5703 UI unit tests for Add Security step 2. (atkach)

atkach 11 年之前
父節點
當前提交
9eb4aaa234

+ 280 - 162
ambari-web/app/controllers/main/admin/security/add/step2.js

@@ -17,7 +17,6 @@
  */
 
 var App = require('app');
-var stringUtils = require('utils/string_utils');
 
 App.MainAdminSecurityAddStep2Controller = Em.Controller.extend({
 
@@ -27,16 +26,170 @@ App.MainAdminSecurityAddStep2Controller = Em.Controller.extend({
   selectedService: null,
   securityUsers: [],
 
+  /**
+   * map which depict connection between config and slave component
+   * in order to set component hosts to config value
+   */
+  slaveComponentMap: [
+    {
+      serviceName: 'HDFS',
+      configName: 'datanode_hosts',
+      component: 'DATANODE'
+    },
+    {
+      serviceName: 'MAPREDUCE',
+      configName: 'tasktracker_hosts',
+      component: 'TASKTRACKER'
+    },
+    {
+      serviceName: 'YARN',
+      configName: 'nodemanager_host',
+      component: 'NODEMANAGER'
+    },
+    {
+      serviceName: 'HBASE',
+      configName: 'regionserver_hosts',
+      component: 'HBASE_REGIONSERVER'
+    },
+    {
+      serviceName: 'STORM',
+      configName: 'supervisor_hosts',
+      component: 'SUPERVISOR'
+    }
+  ],
+  /**
+   * map which depict connection between config and master component
+   * in order to set component hosts to config value
+   */
+  masterComponentMap: [
+    {
+      serviceName: 'OOZIE',
+      configName: 'oozie_servername',
+      components: ['OOZIE_SERVER']
+    },
+    {
+      serviceName: 'HIVE',
+      configName: 'hive_metastore',
+      components: ['HIVE_SERVER']
+    },
+    {
+      serviceName: 'WEBHCAT',
+      configName: 'webhcatserver_host',
+      components: ['WEBHCAT_SERVER']
+    },
+    {
+      serviceName: 'NAGIOS',
+      configName: 'nagios_server',
+      components: ['NAGIOS_SERVER']
+    },
+    {
+      serviceName: 'HDFS',
+      configName: 'namenode_host',
+      components: ['NAMENODE']
+    },
+    {
+      serviceName: 'HDFS',
+      configName: 'snamenode_host',
+      components: ['SECONDARY_NAMENODE']
+    },
+    {
+      serviceName: 'HDFS',
+      configName: 'journalnode_hosts',
+      components: ['JOURNALNODE']
+    },
+    {
+      serviceName: 'MAPREDUCE',
+      configName: 'jobtracker_host',
+      components: ['JOBTRACKER']
+    },
+    {
+      serviceName: 'MAPREDUCE',
+      configName: 'jobhistoryserver_host',
+      components: ['HISTORYSERVER']
+    },
+    {
+      serviceName: 'MAPREDUCE2',
+      configName: 'jobhistoryserver_host',
+      components: ['HISTORYSERVER']
+    },
+    {
+      serviceName: 'YARN',
+      configName: 'resourcemanager_host',
+      components: ['RESOURCEMANAGER']
+    },
+    {
+      serviceName: 'HBASE',
+      configName: 'hbasemaster_host',
+      components: ['HBASE_MASTER']
+    },
+    {
+      serviceName: 'ZOOKEEPER',
+      configName: 'zookeeperserver_hosts',
+      components: ['ZOOKEEPER_SERVER']
+    },
+    {
+      serviceName: 'FALCON',
+      configName: 'falcon_server_host',
+      components: ['FALCON_SERVER']
+    },
+    {
+      serviceName: 'STORM',
+      configName: 'storm_host',
+      components: ['STORM_UI_SERVER', 'NIMBUS', 'SUPERVISOR']
+    }
+  ],
+
+  hostToPrincipalMap: [
+    {
+      serviceName: 'OOZIE',
+      configName: 'oozie_servername',
+      principalName: 'oozie_principal_name',
+      primaryName: 'oozie/'
+    },
+    {
+      serviceName: 'OOZIE',
+      configName: 'oozie_servername',
+      principalName: 'oozie_http_principal_name',
+      primaryName: 'HTTP/'
+    },
+    {
+      serviceName: 'FALCON',
+      configName: 'falcon_server_host',
+      principalName: 'falcon_principal_name',
+      primaryName: 'falcon/'
+    },
+    {
+      serviceName: 'FALCON',
+      configName: 'falcon_server_host',
+      principalName: 'falcon_http_principal_name',
+      primaryName: 'HTTP/'
+    },
+    {
+      serviceName: 'WEBHCAT',
+      configName: 'webhcatserver_host',
+      principalName: 'webHCat_http_principal_name',
+      primaryName: 'HTTP/'
+    },
+    {
+      serviceName: 'NAGIOS',
+      configName: 'nagios_server',
+      principalName: 'nagios_principal_name',
+      primaryName: 'nagios/'
+    }
+  ],
+
   isSubmitDisabled: function () {
-    return !this.stepConfigs.filterProperty('showConfig', true).everyProperty('errorCount', 0);
+    return !this.get('stepConfigs').filterProperty('showConfig').everyProperty('errorCount', 0);
   }.property('stepConfigs.@each.errorCount'),
 
+  /**
+   * clear info of step
+   */
   clearStep: function () {
     this.get('stepConfigs').clear();
     this.get('securityUsers').clear();
   },
 
-
   /**
    *  Function is called whenever the step is loaded
    */
@@ -45,34 +198,34 @@ App.MainAdminSecurityAddStep2Controller = Em.Controller.extend({
     this.clearStep();
     this.loadUsers();
     this.addUserPrincipals(this.get('content.services'), this.get('securityUsers'));
-    this.addMasterHostToGlobals(this.get('content.services'));
-    this.addSlaveHostToGlobals(this.get('content.services'));
+    this.addMasterHostToGlobals();
+    this.addHostPrincipals();
+    this.addSlaveHostToGlobals();
     this.renderServiceConfigs(this.get('content.services'));
     this.changeCategoryOnHa(this.get('content.services'), this.get('stepConfigs'));
-    var storedServices = this.get('content.serviceConfigProperties');
-    if (storedServices) {
-      var configs = new Ember.Set();
+    this.setStoredConfigsValue(this.get('content.serviceConfigProperties'));
+    this.set('installedServices', App.Service.find().mapProperty('serviceName'));
+  },
 
-      // for all services`
-      this.get('stepConfigs').forEach(function (_content) {
-        //for all components
-        _content.get('configs').forEach(function (_config) {
+  /**
+   * set stored values to service configs
+   * @param storedConfigProperties
+   * @return {Boolean}
+   */
+  setStoredConfigsValue: function (storedConfigProperties) {
+    if (!storedConfigProperties) return false;
 
-          var componentVal = storedServices.findProperty('name', _config.get('name'));
-          //if we have config for specified component
-          if (componentVal) {
-            //set it
-            _config.set('value', componentVal.value);
-          }
+    // for all services`
+    this.get('stepConfigs').forEach(function (_content) {
+      _content.get('configs').forEach(function (_config) {
+        var configProperty = storedConfigProperties.findProperty('name', _config.get('name'));
 
-        }, this);
+        if (configProperty) {
+          _config.set('value', configProperty.value);
+        }
       }, this);
-
-    }
-    //
-    this.set('installedServices', App.Service.find().mapProperty('serviceName'));
-    console.log("The services are: " + this.get('installedServices'));
-    //
+    }, this);
+    return true;
   },
 
   /**
@@ -81,80 +234,94 @@ App.MainAdminSecurityAddStep2Controller = Em.Controller.extend({
    */
   renderServiceConfigs: function (serviceConfigs) {
     serviceConfigs.forEach(function (_serviceConfig) {
-
       var serviceConfig = App.ServiceConfig.create({
         filename: _serviceConfig.filename,
         serviceName: _serviceConfig.serviceName,
         displayName: _serviceConfig.displayName,
         configCategories: _serviceConfig.configCategories,
         showConfig: true,
-        configs: []
+        configs: this.wrapConfigProperties(_serviceConfig)
       });
 
-      this.loadComponentConfigs(_serviceConfig, serviceConfig);
-
       this.get('stepConfigs').pushObject(serviceConfig);
     }, this);
-    this.set('selectedService', this.get('stepConfigs').filterProperty('showConfig', true).objectAt(0));
+    this.set('selectedService', this.get('stepConfigs').filterProperty('showConfig').objectAt(0));
   },
 
   /**
-   * Load child components to service config object
+   * wrap configs into App.ServiceConfigProperty objects
    * @param _componentConfig
-   * @param componentConfig
    */
-  loadComponentConfigs: function (_componentConfig, componentConfig) {
+  wrapConfigProperties: function (_componentConfig) {
+    var configs = [];
     _componentConfig.configs.forEach(function (_serviceConfigProperty) {
       var serviceConfigProperty = App.ServiceConfigProperty.create(_serviceConfigProperty);
-      componentConfig.configs.pushObject(serviceConfigProperty);
       serviceConfigProperty.set('isEditable', serviceConfigProperty.get('isReconfigurable'));
       serviceConfigProperty.validate();
+      configs.pushObject(serviceConfigProperty);
     }, this);
+    return configs;
   },
 
   /**
    * fill config with hosts of component
-   * @param service
+   * @param serviceName
    * @param configName
-   * @param componentName
+   * @param componentNames
+   * @return {Boolean}
    */
-  setHostsToConfig: function (service, configName, componentName) {
+  setHostsToConfig: function (serviceName, configName, componentNames) {
+    var service = this.get('content.services').findProperty('serviceName', serviceName);
     if (service) {
       var hosts = service.configs.findProperty('name', configName);
       if (hosts) {
         hosts.defaultValue = App.Service.find(service.serviceName)
           .get('hostComponents')
-          .filterProperty('componentName', componentName)
-          .mapProperty('host.hostName');
+          .filter(function (component) {
+            return componentNames.contains(component.get('componentName'));
+          })
+          .mapProperty('host.hostName')
+          .uniq();
+        return true;
       }
+      return false;
     }
+    return false;
   },
 
   /**
-   * fill principal _HOST part with actual hostname of component
-   * @param service
+   * set principal default value based on config host and default primary name
+   * @param serviceName
    * @param hostConfigName
    * @param principalConfigName
    * @param defaultPrimaryName
+   * @return {Boolean}
    */
-  setHostToPrincipal: function (service, hostConfigName, principalConfigName, defaultPrimaryName) {
+  setHostToPrincipal: function (serviceName, hostConfigName, principalConfigName, defaultPrimaryName) {
+    var service = this.get('content.services').findProperty('serviceName', serviceName);
     if (service) {
       var host = service.configs.findProperty('name', hostConfigName);
       var principal = service.configs.findProperty('name', principalConfigName);
       if (host && principal) {
-        if (host.defaultValue instanceof Array) {
+        if (Array.isArray(host.defaultValue)) {
           host.defaultValue = host.defaultValue[0];
         }
         principal.defaultValue = defaultPrimaryName + host.defaultValue.toLowerCase();
+        return true;
       }
+      return false;
     }
+    return false;
   },
 
-
+  /**
+   * load services users
+   */
   loadUsers: function () {
     var securityUsers = App.router.get('mainAdminSecurityController').get('serviceUsers');
-    if (!securityUsers || securityUsers.length < 1) { // Page could be refreshed in middle
+    if (Em.isNone(securityUsers) || securityUsers.length === 0) {
       if (App.testMode) {
+        securityUsers = securityUsers || [];
         securityUsers.pushObject({id: 'puppet var', name: 'hdfs_user', value: 'hdfs'});
         securityUsers.pushObject({id: 'puppet var', name: 'mapred_user', value: 'mapred'});
         securityUsers.pushObject({id: 'puppet var', name: 'hbase_user', value: 'hbase'});
@@ -167,147 +334,98 @@ App.MainAdminSecurityAddStep2Controller = Em.Controller.extend({
     this.set('securityUsers', securityUsers);
   },
 
+  /**
+   * set default values to user principals and control their visibility
+   * @param serviceConfigs
+   * @param securityUsers
+   */
   addUserPrincipals: function (serviceConfigs, securityUsers) {
-    var smokeUser = securityUsers.findProperty('name', 'smokeuser');
-    var hdfsUser = securityUsers.findProperty('name', 'hdfs_user');
+    var generalService = serviceConfigs.findProperty('serviceName', 'GENERAL').configs;
+    var isHbaseService = serviceConfigs.someProperty('serviceName', 'HBASE');
+    var hbaseUserPrincipal = generalService.findProperty('name', 'hbase_principal_name');
+    var hbaseUserKeytab = generalService.findProperty('name', 'hbase_user_keytab');
     var hbaseUser = securityUsers.findProperty('name', 'hbase_user');
-    var generalService = serviceConfigs.findProperty('serviceName', 'GENERAL');
-    var smokeUserPrincipal = generalService.configs.findProperty('name', 'smokeuser_principal_name');
-    var hdfsUserPrincipal = generalService.configs.findProperty('name', 'hdfs_principal_name');
-    var hbaseUserPrincipal = generalService.configs.findProperty('name', 'hbase_principal_name');
-    var hbaseUserKeytab = generalService.configs.findProperty('name', 'hbase_user_keytab');
-    var hbaseService = serviceConfigs.findProperty('serviceName', 'HBASE');
-    if (smokeUser && smokeUserPrincipal) {
-      smokeUserPrincipal.defaultValue = smokeUser.value;
-    }
-    if (hdfsUser && hdfsUserPrincipal) {
-      hdfsUserPrincipal.defaultValue = hdfsUser.value;
-    }
-    if (hbaseService && hbaseUser && hbaseUserPrincipal) {
-      hbaseUserPrincipal.defaultValue = hbaseUser.value;
+
+    this.setUserPrincipalValue(securityUsers.findProperty('name', 'smokeuser'), generalService.findProperty('name', 'smokeuser_principal_name'));
+    this.setUserPrincipalValue(securityUsers.findProperty('name', 'hdfs_user'), generalService.findProperty('name', 'hdfs_principal_name'));
+
+    if (isHbaseService && this.setUserPrincipalValue(hbaseUser, hbaseUserPrincipal)) {
       hbaseUserPrincipal.isVisible = true;
       hbaseUserKeytab.isVisible = true;
     }
   },
+  /**
+   * set default value of user principal
+   * @param user
+   * @param userPrincipal
+   */
+  setUserPrincipalValue: function (user, userPrincipal) {
+    if (user && userPrincipal) {
+      userPrincipal.defaultValue = user.value;
+      return true;
+    }
+    return false;
+  },
 
-  addSlaveHostToGlobals: function (serviceConfigs) {
-    var serviceComponentMap = [
-      {
-        serviceName: 'HDFS',
-        configName: 'datanode_hosts',
-        component: 'DATANODE'
-      },
-      {
-        serviceName: 'MAPREDUCE',
-        configName: 'tasktracker_hosts',
-        component: 'TASKTRACKER'
-      },
-      {
-        serviceName: 'YARN',
-        configName: 'nodemanager_host',
-        component: 'NODEMANAGER'
-      },
-      {
-        serviceName: 'HBASE',
-        configName: 'regionserver_hosts',
-        component: 'HBASE_REGIONSERVER'
-      },
-      {
-        serviceName: 'STORM',
-        configName: 'supervisor_hosts',
-        component: 'SUPERVISOR'
-      }
-    ];
-    serviceComponentMap.forEach(function(service) {
-      this.setHostsToConfig(serviceConfigs.findProperty('serviceName', service.serviceName), service.configName, service.component);
+  /**
+   * put hosts of slave component into defaultValue of global configs
+   */
+  addSlaveHostToGlobals: function () {
+    this.get('slaveComponentMap').forEach(function (service) {
+      this.setHostsToConfig(service.serviceName, service.configName, [service.component]);
     }, this);
   },
 
-  addMasterHostToGlobals: function (serviceConfigs) {
-    var oozieService = serviceConfigs.findProperty('serviceName', 'OOZIE');
-    var hiveService = serviceConfigs.findProperty('serviceName', 'HIVE');
-    var webHcatService = serviceConfigs.findProperty('serviceName', 'WEBHCAT');
-    var nagiosService = serviceConfigs.findProperty('serviceName', 'NAGIOS');
-    var hbaseService = serviceConfigs.findProperty('serviceName', 'HBASE');
-    var zooKeeperService = serviceConfigs.findProperty('serviceName', 'ZOOKEEPER');
-    var hdfsService = serviceConfigs.findProperty('serviceName', 'HDFS');
-    var mapReduceService = serviceConfigs.findProperty('serviceName', 'MAPREDUCE');
-    var mapReduce2Service = serviceConfigs.findProperty('serviceName', 'MAPREDUCE2');
-    var yarnService = serviceConfigs.findProperty('serviceName', 'YARN');
-    var stormService = serviceConfigs.findProperty('serviceName', 'STORM');
-    var falconService = serviceConfigs.findProperty('serviceName', 'FALCON');
-
-
-    this.setHostsToConfig(oozieService, 'oozie_servername', 'OOZIE_SERVER');
-    this.setHostsToConfig(hiveService, 'hive_metastore', 'HIVE_SERVER');
-    this.setHostsToConfig(webHcatService, 'webhcatserver_host', 'WEBHCAT_SERVER');
-    this.setHostsToConfig(nagiosService, 'nagios_server', 'NAGIOS_SERVER');
-    this.setHostsToConfig(hdfsService, 'namenode_host', 'NAMENODE');
-    this.setHostsToConfig(hdfsService, 'snamenode_host', 'SECONDARY_NAMENODE');
-    this.setHostsToConfig(hdfsService, 'journalnode_hosts', 'JOURNALNODE');
-    this.setHostsToConfig(mapReduceService, 'jobtracker_host', 'JOBTRACKER');
-    this.setHostsToConfig(mapReduceService, 'jobhistoryserver_host', 'HISTORYSERVER');
-    this.setHostsToConfig(mapReduce2Service, 'jobhistoryserver_host', 'HISTORYSERVER');
-    this.setHostsToConfig(yarnService, 'resourcemanager_host', 'RESOURCEMANAGER');
-    this.setHostsToConfig(hbaseService, 'hbasemaster_host', 'HBASE_MASTER');
-    this.setHostsToConfig(zooKeeperService, 'zookeeperserver_hosts', 'ZOOKEEPER_SERVER');
-    this.setHostsToConfig(falconService, 'falcon_server_host', 'FALCON_SERVER');
-    if (stormService) {
-      var stormComponents = ['STORM_UI_SERVER','NIMBUS','SUPERVISOR'];
-      var stormHosts = [];
-      stormComponents.forEach(function(componentName) {
-        stormHosts.pushObjects(App.Service.find(stormService.serviceName)
-          .get('hostComponents')
-          .filterProperty('componentName', componentName)
-          .mapProperty('host.hostName'));
-      }, this);
-      var hosts = stormService.configs.findProperty('name', 'storm_host');
-      hosts.defaultValue  = stormHosts.uniq();
-    }
-
-    // Oozie, Falcon, WebHcat and Nagios does not support _HOST in the principal name. Actual hostname should be set instead of _HOST
+  /**
+   * put hosts of master component into defaultValue of global configs
+   */
+  addMasterHostToGlobals: function () {
+    this.get('masterComponentMap').forEach(function (item) {
+      this.setHostsToConfig(item.serviceName, item.configName, item.components);
+    }, this);
+  },
 
-    this.setHostToPrincipal(oozieService, 'oozie_servername','oozie_principal_name','oozie/');
-    this.setHostToPrincipal(oozieService, 'oozie_servername','oozie_http_principal_name','HTTP/');
-    this.setHostToPrincipal(falconService, 'falcon_server_host','falcon_principal_name','falcon/');
-    this.setHostToPrincipal(falconService, 'falcon_server_host','falcon_http_principal_name','HTTP/');
-    this.setHostToPrincipal(webHcatService, 'webhcatserver_host','webHCat_http_principal_name','HTTP/');
-    this.setHostToPrincipal(nagiosService, 'nagios_server','nagios_principal_name','nagios/');
+  /**
+   * put hosts to principal default values
+   */
+  addHostPrincipals: function () {
+    this.get('hostToPrincipalMap').forEach(function (item) {
+      this.setHostToPrincipal(item.serviceName, item.configName, item.principalName, item.primaryName);
+    }, this);
   },
 
+  /**
+   * modify config categories depending on whether HA is enabled or not
+   * @param serviceConfigs
+   * @param stepConfigs
+   */
   changeCategoryOnHa: function (serviceConfigs, stepConfigs) {
     var hdfsService = serviceConfigs.findProperty('serviceName', 'HDFS');
     if (hdfsService) {
-      var hdfsProperties = stepConfigs.findProperty('serviceName', 'HDFS').get('configs');
+      var properties = stepConfigs.findProperty('serviceName', 'HDFS').get('configs');
       var configCategories = hdfsService.configCategories;
       if ((App.testMode && App.testNameNodeHA) || (this.get('content.isNnHa') === 'true')) {
-        hdfsProperties.filterProperty('category', 'SNameNode').forEach(function (_snConfig) {
-          _snConfig.set('isVisible', false);
-        }, this);
-        var snCategory = configCategories.findProperty('name', 'SNameNode');
-        if (snCategory) {
-          configCategories.removeObject(snCategory);
-        }
+        this.removeConfigCategory(properties, configCategories, 'SNameNode');
       } else {
-        hdfsProperties.filterProperty('category', 'JournalNode').forEach(function (_jnConfig) {
-          _jnConfig.set('isVisible', false);
-        }, this);
-        var jnCategory = configCategories.findProperty('name', 'JournalNode');
-        if (jnCategory) {
-          configCategories.removeObject(jnCategory);
-        }
+        this.removeConfigCategory(properties, configCategories, 'JournalNode');
       }
+      return true;
     }
+    return false;
   },
-
   /**
-   *  submit and move to step3
+   * remove config category that belong to component and hide category configs
+   * @param properties
+   * @param configCategories
+   * @param component
    */
-
-  submit: function () {
-    if (!this.get('isSubmitDisabled')) {
-      App.router.send('next');
+  removeConfigCategory: function (properties, configCategories, component) {
+    properties.filterProperty('category', component).forEach(function (_snConfig) {
+      _snConfig.set('isVisible', false);
+    }, this);
+    var category = configCategories.findProperty('name', component);
+    if (category) {
+      configCategories.removeObject(category);
     }
   }
-
 });

+ 9 - 8
ambari-web/app/templates/main/admin/security/add/step2.hbs

@@ -19,15 +19,16 @@
 <h2>{{t admin.security.step2.header}}</h2>
 
 <div id="serviceConfig">
-  <p class="alert alert-info">
-    {{t admin.security.step2.body.header}}
-  </p>
+    <p class="alert alert-info">
+      {{t admin.security.step2.body.header}}
+    </p>
   {{view App.ServicesConfigView}}
 
-  <div class="btn-area">
-    <a class="btn" {{action back}}>&larr; {{t common.back}}</a>
+    <div class="btn-area">
+        <a class="btn" {{action back}}>&larr; {{t common.back}}</a>
 
-    <a class="btn btn-success pull-right" {{bindAttr disabled="isSubmitDisabled"}}
-      {{action submit target="controller"}}>{{t common.next}} &rarr;</a>
-  </div>
+        <button class="btn btn-success pull-right" {{bindAttr disabled="isSubmitDisabled"}}
+          {{action next}}>{{t common.next}} &rarr;
+        </button>
+    </div>
 </div>

+ 570 - 18
ambari-web/test/controllers/main/admin/security/add/step2_test.js

@@ -18,26 +18,37 @@
 
 
 var App = require('app');
+
 require('controllers/main/admin/security/add/step2');
-require('utils/polling');
-require('models/cluster_states');
+require('models/service');
 
 describe('App.MainAdminSecurityAddStep2Controller', function () {
 
-  var mainAdminSecurityAddStep2Controller = App.MainAdminSecurityAddStep2Controller.create();
+  var controller = App.MainAdminSecurityAddStep2Controller.create({
+    content: {}
+  });
 
-  describe('#clearStep', function() {
-    mainAdminSecurityAddStep2Controller.set('stepConfigs',[1,2,3]);
-    it('clear', function() {
-      mainAdminSecurityAddStep2Controller.clearStep();
-      expect(mainAdminSecurityAddStep2Controller.get('stepConfigs.length')).to.equal(0);
+  describe('#clearStep()', function () {
+    it('Info is empty', function () {
+      controller.set('stepConfigs', []);
+      controller.set('securityUsers', []);
+      controller.clearStep();
+      expect(controller.get('stepConfigs')).to.be.empty;
+      expect(controller.get('securityUsers')).to.be.empty;
+    });
+    it('Info filled', function () {
+      controller.set('stepConfigs', [1]);
+      controller.set('securityUsers', [1]);
+      controller.clearStep();
+      expect(controller.get('stepConfigs')).to.be.empty;
+      expect(controller.get('securityUsers')).to.be.empty;
     });
   });
 
-  describe('#isSubmitDisabled', function() {
+  describe('#isSubmitDisabled', function () {
     var tests = [
       {
-        config:[
+        config: [
           {
             showConfig: true,
             errorCount: 0
@@ -47,7 +58,7 @@ describe('App.MainAdminSecurityAddStep2Controller', function () {
         e: false
       },
       {
-        config:[
+        config: [
           {
             showConfig: true,
             errorCount: 0
@@ -61,7 +72,7 @@ describe('App.MainAdminSecurityAddStep2Controller', function () {
         e: true
       },
       {
-        config:[
+        config: [
           {
             showConfig: true,
             errorCount: 0
@@ -75,7 +86,7 @@ describe('App.MainAdminSecurityAddStep2Controller', function () {
         e: false
       },
       {
-        config:[
+        config: [
           {
             showConfig: false,
             errorCount: 0
@@ -89,7 +100,7 @@ describe('App.MainAdminSecurityAddStep2Controller', function () {
         e: false
       },
       {
-        config:[
+        config: [
           {
             showConfig: true,
             errorCount: 1
@@ -103,12 +114,553 @@ describe('App.MainAdminSecurityAddStep2Controller', function () {
         e: true
       }
     ];
-    tests.forEach(function(test) {
-      it(test.m, function() {
-        mainAdminSecurityAddStep2Controller.set('stepConfigs', test.config);
-        expect(mainAdminSecurityAddStep2Controller.get('isSubmitDisabled')).to.equal(test.e);
+    tests.forEach(function (test) {
+      it(test.m, function () {
+        controller.set('stepConfigs', test.config);
+        expect(controller.get('isSubmitDisabled')).to.equal(test.e);
+      });
+    });
+  });
+
+  describe('#loadStep()', function () {
+    it('load step', function () {
+      controller.set('stepConfigs', [
+        {}
+      ]);
+      controller.set('securityUsers', ['user1']);
+      controller.set('content.services', ['service1']);
+      controller.set('content.serviceConfigProperties', ['config1']);
+      sinon.stub(controller, 'clearStep', Em.K);
+      sinon.stub(controller, 'loadUsers', Em.K);
+      sinon.stub(controller, 'addUserPrincipals', Em.K);
+      sinon.stub(controller, 'addMasterHostToGlobals', Em.K);
+      sinon.stub(controller, 'addSlaveHostToGlobals', Em.K);
+      sinon.stub(controller, 'renderServiceConfigs', Em.K);
+      sinon.stub(controller, 'changeCategoryOnHa', Em.K);
+      sinon.stub(controller, 'setStoredConfigsValue', Em.K);
+      sinon.stub(controller, 'addHostPrincipals', Em.K);
+      sinon.stub(App.Service, 'find', function () {
+        return [
+          {serviceName: 'HDFS'}
+        ];
+      });
+
+      controller.loadStep();
+      expect(controller.get('installedServices')).to.eql(['HDFS']);
+      expect(controller.clearStep.calledOnce).to.be.true;
+      expect(controller.loadUsers.calledOnce).to.be.true;
+      expect(controller.addUserPrincipals.calledWith(['service1'], ['user1'])).to.be.true;
+      expect(controller.addMasterHostToGlobals.calledOnce).to.be.true;
+      expect(controller.addSlaveHostToGlobals.calledOnce).to.be.true;
+      expect(controller.addHostPrincipals.calledOnce).to.be.true;
+      expect(controller.renderServiceConfigs.calledWith(['service1'])).to.be.true;
+      expect(controller.changeCategoryOnHa.calledWith(['service1'], [{}])).to.be.true;
+      expect(controller.setStoredConfigsValue.calledWith(['config1'])).to.be.true;
+
+      controller.clearStep.restore();
+      controller.loadUsers.restore();
+      controller.addUserPrincipals.restore();
+      controller.addMasterHostToGlobals.restore();
+      controller.addSlaveHostToGlobals.restore();
+      controller.renderServiceConfigs.restore();
+      controller.changeCategoryOnHa.restore();
+      controller.setStoredConfigsValue.restore();
+      controller.addHostPrincipals.restore();
+      App.Service.find.restore();
+    });
+  });
+
+  describe('#setStoredConfigsValue()', function () {
+    it('storedConfigProperties is null', function () {
+      expect(controller.setStoredConfigsValue(null)).to.be.false;
+    });
+    it('stepConfigs is empty', function () {
+      controller.set('stepConfigs', []);
+      expect(controller.setStoredConfigsValue([])).to.be.true;
+      expect(controller.get('stepConfigs')).to.be.empty;
+    });
+    it('stepConfig has no configs', function () {
+      controller.set('stepConfigs', [Em.Object.create({
+        configs: []
+      })]);
+      expect(controller.setStoredConfigsValue([])).to.be.true;
+      expect(controller.get('stepConfigs')[0].get('configs')).to.be.empty;
+    });
+    it('stepConfig has no stored configs', function () {
+      controller.set('stepConfigs', [Em.Object.create({
+        configs: [Em.Object.create({
+          name: 'config1',
+          value: 'value1'
+        })]
+      })]);
+      var storedConfigProperties = [
+        {
+          name: 'config2',
+          value: "value2"
+        }
+      ];
+      expect(controller.setStoredConfigsValue(storedConfigProperties)).to.be.true;
+      expect(controller.get('stepConfigs')[0].get('configs').findProperty('name', 'config1').get('value')).to.equal('value1');
+    });
+    it('stepConfig has stored configs', function () {
+      controller.set('stepConfigs', [Em.Object.create({
+        configs: [Em.Object.create({
+          name: 'config2',
+          value: 'value1'
+        })]
+      })]);
+      var storedConfigProperties = [
+        {
+          name: 'config2',
+          value: "value2"
+        }
+      ];
+      expect(controller.setStoredConfigsValue(storedConfigProperties)).to.be.true;
+      expect(controller.get('stepConfigs')[0].get('configs').findProperty('name', 'config2').get('value')).to.equal('value2');
+    });
+  });
+
+  describe('#renderServiceConfigs()', function () {
+    it('serviceConfigs and stepConfigs are empty', function () {
+      controller.set('stepConfigs', []);
+      controller.renderServiceConfigs([]);
+      expect(controller.get('selectedService')).to.be.undefined;
+    });
+    it('serviceConfigs is empty', function () {
+      controller.set('stepConfigs', [
+        {showConfig: true}
+      ]);
+      controller.renderServiceConfigs([]);
+      expect(controller.get('selectedService')).to.eql({showConfig: true});
+    });
+    it('serviceConfigs has service', function () {
+      var serviceConfigs = [
+        {
+          serviceName: 'HDFS',
+          configs: []
+        }
+      ];
+      sinon.stub(controller, 'wrapConfigProperties', function () {
+        return [];
+      });
+      controller.set('stepConfigs', []);
+      controller.renderServiceConfigs(serviceConfigs);
+      expect(controller.get('selectedService').get('serviceName')).to.equal('HDFS');
+      expect(controller.get('selectedService').get('showConfig')).to.be.true;
+      expect(controller.get('selectedService').get('configs')).to.be.empty;
+      expect(controller.wrapConfigProperties.calledWith({
+        serviceName: 'HDFS',
+        configs: []
+      })).to.be.true;
+      controller.wrapConfigProperties.restore();
+    });
+  });
+
+  describe('#wrapConfigProperties()', function () {
+    it('_componentConfig is empty', function () {
+      expect(controller.wrapConfigProperties({configs: []})).to.be.empty;
+    });
+    it('serviceConfigs has service', function () {
+      var mock = Em.Object.create({
+        validate: Em.K,
+        isReconfigurable: true,
+        isEditable: false
+      });
+      var _componentConfig = {configs: [
+        {name: 'config1'}
+      ]};
+      sinon.stub(App.ServiceConfigProperty, 'create', function () {
+        return mock;
+      });
+      sinon.spy(mock, 'validate');
+      expect(controller.wrapConfigProperties(_componentConfig)[0].get('isEditable')).to.be.true;
+      expect(App.ServiceConfigProperty.create.calledWith({name: 'config1'})).to.be.true;
+      expect(mock.validate.calledOnce).to.be.true;
+      mock.validate.restore();
+      App.ServiceConfigProperty.create.restore();
+    });
+  });
+
+  describe('#setHostsToConfig()', function () {
+    it('service is null', function () {
+      expect(controller.setHostsToConfig(null)).to.be.false;
+    });
+    it('service.configs is empty', function () {
+      controller.set('content.services', [
+        {
+          serviceName: 'HDFS',
+          configs: []
+        }
+      ]);
+      expect(controller.setHostsToConfig('HDFS')).to.be.false;
+    });
+    it('No such config name in service.configs', function () {
+      controller.set('content.services', [
+        {
+          serviceName: 'HDFS',
+          configs: [
+            {
+              name: 'config1'
+            }
+          ]
+        }
+      ]);
+      expect(controller.setHostsToConfig('HDFS', 'config2')).to.be.false;
+    });
+    it('Correct config in service.configs', function () {
+      sinon.stub(App.Service, 'find', function () {
+        return Em.Object.create({
+          hostComponents: [
+            Em.Object.create({
+              componentName: 'comp1',
+              host: {hostName: 'host1'}
+            })
+          ]
+        });
+      });
+      expect(controller.setHostsToConfig('HDFS', 'config1', ['comp1'])).to.be.true;
+      expect(controller.get('content.services')[0].configs[0].defaultValue).to.eql(['host1']);
+      App.Service.find.restore();
+    });
+  });
+
+  describe('#setHostToPrincipal()', function () {
+    it('service is null', function () {
+      expect(controller.setHostToPrincipal(null)).to.be.false;
+    });
+    it('service.configs is empty', function () {
+      controller.set('content.services', [
+        {
+          serviceName: 'HDFS',
+          configs: []
+        }
+      ]);
+      expect(controller.setHostToPrincipal('HDFS')).to.be.false;
+    });
+    it('No such hostConfigName name in service.configs', function () {
+      controller.set('content.services', [
+        {
+          serviceName: 'HDFS',
+          configs: [
+            {
+              name: 'config1'
+            }
+          ]
+        }
+      ]);
+      expect(controller.setHostToPrincipal('HDFS', 'config2', 'config1')).to.be.false;
+    });
+    it('No such principalConfigName name in service.configs', function () {
+      expect(controller.setHostToPrincipal('HDFS', 'config1', 'config2')).to.be.false;
+    });
+    it('Correct config in service.configs', function () {
+      controller.set('content.services', [
+        {
+          serviceName: 'HDFS',
+          configs: [
+            {
+              name: 'config1',
+              defaultValue: 'value1'
+            },
+            {
+              name: 'principal1'
+            }
+          ]
+        }
+      ]);
+      expect(controller.setHostToPrincipal('HDFS', 'config1', 'principal1', 'name1')).to.be.true;
+      expect(controller.get('content.services')[0].configs[0].defaultValue).to.equal('value1');
+      expect(controller.get('content.services')[0].configs[1].defaultValue).to.equal('name1value1');
+    });
+    it('Correct config in service.configs, defaultValue is array', function () {
+      controller.set('content.services', [
+        {
+          serviceName: 'HDFS',
+          configs: [
+            {
+              name: 'config1',
+              defaultValue: ['Value1']
+            },
+            {
+              name: 'principal1'
+            }
+          ]
+        }
+      ]);
+      expect(controller.setHostToPrincipal('HDFS', 'config1', 'principal1', 'name1')).to.be.true;
+      expect(controller.get('content.services')[0].configs[0].defaultValue).to.equal('Value1');
+      expect(controller.get('content.services')[0].configs[1].defaultValue).to.equal('name1value1');
+    });
+  });
+
+  describe('#loadUsers()', function () {
+
+    afterEach(function () {
+      App.router.get.restore();
+    });
+
+    it('serviceUsers is correct', function () {
+      sinon.stub(App.router, 'get', function () {
+        return Em.Object.create({serviceUsers: [
+          {}
+        ]})
+      });
+      controller.loadUsers();
+      expect(controller.get('securityUsers')).to.eql([
+        {}
+      ]);
+    });
+    it('serviceUsers is null, testMode = true', function () {
+      sinon.stub(App.router, 'get', function () {
+        return Em.Object.create({serviceUsers: null})
+      });
+      App.testMode = true;
+      controller.loadUsers();
+      expect(controller.get('securityUsers').mapProperty('name')).to.eql(["hdfs_user",
+        "mapred_user",
+        "hbase_user",
+        "hive_user",
+        "smokeuser"
+      ]);
+    });
+    it('serviceUsers is empty, testMode = true', function () {
+      sinon.stub(App.router, 'get', function () {
+        return Em.Object.create({serviceUsers: []})
+      });
+      App.testMode = true;
+      controller.loadUsers();
+      expect(controller.get('securityUsers').mapProperty('name')).to.eql(["hdfs_user",
+        "mapred_user",
+        "hbase_user",
+        "hive_user",
+        "smokeuser"
+      ]);
+    });
+    it('serviceUsers is null, testMode = false', function () {
+      sinon.stub(App.router, 'get', function () {
+        return Em.Object.create({serviceUsers: null})
+      });
+      sinon.stub(App.db, 'getSecureUserInfo', function () {
+        return [
+          {}
+        ];
+      });
+      App.testMode = false;
+      controller.loadUsers();
+      expect(controller.get('securityUsers')).to.eql([
+        {}
+      ]);
+      expect(App.db.getSecureUserInfo.calledOnce).to.be.true;
+      App.db.getSecureUserInfo.restore();
+    });
+    it('serviceUsers is empty, testMode = false', function () {
+      sinon.stub(App.router, 'get', function () {
+        return Em.Object.create({serviceUsers: []})
+      });
+      sinon.stub(App.db, 'getSecureUserInfo', function () {
+        return [
+          {}
+        ];
+      });
+      App.testMode = false;
+      controller.loadUsers();
+      expect(controller.get('securityUsers')).to.eql([
+        {}
+      ]);
+      expect(App.db.getSecureUserInfo.calledOnce).to.be.true;
+      App.db.getSecureUserInfo.restore();
+    });
+  });
+
+  describe('#addUserPrincipals()', function () {
+
+    afterEach(function () {
+      controller.setUserPrincipalValue.restore();
+    });
+
+    var serviceConfigs = [
+      {
+        serviceName: 'GENERAL',
+        configs: [
+          {name: 'hbase_principal_name'},
+          {name: 'hbase_user_keytab'}
+        ]
+      }
+    ];
+    var securityUsers = [];
+
+    it('HBASE service is not installed', function () {
+      sinon.stub(controller, 'setUserPrincipalValue', Em.K);
+      controller.addUserPrincipals(serviceConfigs, securityUsers);
+      expect(controller.setUserPrincipalValue.calledTwice).to.be.true;
+    });
+    it('HBASE service is installed, setUserPrincipalValue return false', function () {
+      sinon.stub(controller, 'setUserPrincipalValue', function () {
+        return false;
+      });
+      serviceConfigs.push({serviceName: 'HBASE'});
+      controller.addUserPrincipals(serviceConfigs, securityUsers);
+      expect(controller.setUserPrincipalValue.calledThrice).to.be.true;
+    });
+    it('HBASE service is installed, setUserPrincipalValue return true', function () {
+      sinon.stub(controller, 'setUserPrincipalValue', function () {
+        return true;
       });
+      controller.addUserPrincipals(serviceConfigs, securityUsers);
+      expect(controller.setUserPrincipalValue.calledThrice).to.be.true;
+      expect(serviceConfigs[0].configs.findProperty('name', 'hbase_principal_name').isVisible).to.be.true;
+      expect(serviceConfigs[0].configs.findProperty('name', 'hbase_user_keytab').isVisible).to.be.true;
+    });
+  });
+
+  describe('#setUserPrincipalValue()', function () {
+    it('user and userPrincipal are null', function () {
+      expect(controller.setUserPrincipalValue(null, null)).to.be.false;
+    });
+    it('user is null', function () {
+      expect(controller.setUserPrincipalValue(null, {})).to.be.false;
+    });
+    it('userPrincipal is null', function () {
+      expect(controller.setUserPrincipalValue({}, null)).to.be.false;
+    });
+    it('user and userPrincipal are correct', function () {
+      var user = {value: 'value1'};
+      var userPrincipal = {};
+      expect(controller.setUserPrincipalValue(user, userPrincipal)).to.be.true;
+      expect(userPrincipal.defaultValue).to.equal('value1');
     });
   });
 
+  describe('#addSlaveHostToGlobals()', function () {
+    it('slaveComponentMap is empty', function () {
+      sinon.stub(controller, 'setHostsToConfig', Em.K);
+      controller.set('slaveComponentMap', []);
+      controller.addSlaveHostToGlobals();
+      expect(controller.setHostsToConfig.called).to.be.false;
+      controller.setHostsToConfig.restore();
+    });
+    it('Correct data', function () {
+      sinon.stub(controller, 'setHostsToConfig', Em.K);
+      controller.set('slaveComponentMap', [
+        {
+          serviceName: 'HDFS',
+          configName: 'datanode_hosts',
+          component: 'DATANODE'
+        }
+      ]);
+      controller.addSlaveHostToGlobals();
+      expect(controller.setHostsToConfig.calledWith('HDFS', 'datanode_hosts', ['DATANODE'])).to.be.true;
+      controller.setHostsToConfig.restore();
+    });
+  });
+
+  describe('#addMasterHostToGlobals()', function () {
+    it('masterComponentMap is empty', function () {
+      sinon.stub(controller, 'setHostsToConfig', Em.K);
+      controller.set('masterComponentMap', []);
+      controller.addMasterHostToGlobals();
+      expect(controller.setHostsToConfig.called).to.be.false;
+      controller.setHostsToConfig.restore();
+    });
+    it('Correct data', function () {
+      sinon.stub(controller, 'setHostsToConfig', Em.K);
+      controller.set('masterComponentMap', [
+        {
+          serviceName: 'HDFS',
+          configName: 'datanode_hosts',
+          components: ['DATANODE']
+        }
+      ]);
+      controller.addMasterHostToGlobals();
+      expect(controller.setHostsToConfig.calledWith('HDFS', 'datanode_hosts', ['DATANODE'])).to.be.true;
+      controller.setHostsToConfig.restore();
+    });
+  });
+
+  describe('#addHostPrincipals()', function () {
+    it('hostToPrincipalMap is empty', function () {
+      sinon.stub(controller, 'setHostToPrincipal', Em.K);
+      controller.set('hostToPrincipalMap', []);
+      controller.addHostPrincipals();
+      expect(controller.setHostToPrincipal.called).to.be.false;
+      controller.setHostToPrincipal.restore();
+    });
+    it('Correct data', function () {
+      sinon.stub(controller, 'setHostToPrincipal', Em.K);
+      controller.set('hostToPrincipalMap', [
+        {
+          serviceName: 'HDFS',
+          configName: 'datanode_hosts',
+          principalName: 'principal1',
+          primaryName: 'name1'
+        }
+      ]);
+      controller.addHostPrincipals();
+      expect(controller.setHostToPrincipal.calledWith('HDFS', 'datanode_hosts', 'principal1', 'name1')).to.be.true;
+      controller.setHostToPrincipal.restore();
+    });
+  });
+
+  describe('#changeCategoryOnHa()', function () {
+
+    beforeEach(function () {
+      sinon.stub(controller, 'removeConfigCategory', Em.K);
+    });
+    afterEach(function () {
+      controller.removeConfigCategory.restore();
+    });
+
+    var serviceConfigs = [{
+      serviceName: 'HDFS',
+      configCategories: []
+    }];
+    var stepConfigs = [Em.Object.create({
+      serviceName: 'HDFS',
+      configs: []
+    })];
+
+    it('HDFS service is absent', function () {
+      expect(controller.changeCategoryOnHa([], [])).to.be.false;
+    });
+    it('HDFS service installed, App.testMode and App.testNameNodeHA - true', function () {
+      App.testMode = true;
+      App.testNameNodeHA = true;
+      expect(controller.changeCategoryOnHa(serviceConfigs, stepConfigs)).to.be.true;
+      expect(controller.removeConfigCategory.calledWith([], [], 'SNameNode')).to.be.true;
+      App.testMode = false;
+      App.testNameNodeHA = false;
+    });
+    it('HDFS service installed, content.isNnHa = true', function () {
+      controller.set('content.isNnHa', 'true');
+      expect(controller.changeCategoryOnHa(serviceConfigs, stepConfigs)).to.be.true;
+      expect(controller.removeConfigCategory.calledWith([], [], 'SNameNode')).to.be.true;
+    });
+    it('HDFS service installed, HA disabled', function () {
+      controller.set('content.isNnHa', 'false');
+      expect(controller.changeCategoryOnHa(serviceConfigs, stepConfigs)).to.be.true;
+      expect(controller.removeConfigCategory.calledWith([], [], 'JournalNode')).to.be.true;
+    });
+  });
+
+  describe('#removeConfigCategory()', function () {
+    it('properties should be hidden', function () {
+      var properties = [
+        Em.Object.create({
+          category: 'comp1',
+          isVisible: true
+        })
+      ];
+      controller.removeConfigCategory(properties, [], 'comp1');
+      expect(properties[0].isVisible).to.be.false;
+    });
+    it('category should be removed', function () {
+      var configCategories = [
+        Em.Object.create({
+          name: 'comp1'
+        })
+      ];
+      controller.removeConfigCategory([], configCategories, 'comp1');
+      expect(configCategories).to.be.empty;
+    });
+  });
 });

+ 1 - 0
ambari-web/test/controllers/main/admin/security/add/step4_test.js

@@ -22,6 +22,7 @@ require('controllers/main/admin/security/security_progress_controller');
 require('controllers/main/admin/security/add/step4');
 require('utils/polling');
 require('models/cluster_states');
+require('models/service');
 
 describe('App.MainAdminSecurityAddStep4Controller', function () {