You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by on...@apache.org on 2014/05/12 19:24:10 UTC

[10/12] AMBARI-5737. Tests folder structure should be equal to app folder structure. (onechiporenko)

http://git-wip-us.apache.org/repos/asf/ambari/blob/1d0fe34b/ambari-web/test/controllers/wizard/step5_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/wizard/step5_test.js b/ambari-web/test/controllers/wizard/step5_test.js
new file mode 100644
index 0000000..72f347b
--- /dev/null
+++ b/ambari-web/test/controllers/wizard/step5_test.js
@@ -0,0 +1,1040 @@
+/**
+ * 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 Ember = require('ember');
+var App = require('app');
+require('controllers/wizard/step5_controller');
+var c;
+describe('App.WizardStep5Controller', function () {
+  beforeEach(function() {
+    c = App.WizardStep5Controller.create();
+  });
+  var controller = App.WizardStep5Controller.create();
+  controller.set('content', {});
+  var cpu = 2, memory = 4;
+
+  var schemes = Em.A([
+    {'description': 'empty condition'},
+    {
+      'description': 'second host if amount more than 1',
+      "else": 1
+    },
+    {
+      'description': 'first host if amount less than 3, third host if amount less than 6, fourth host if amount more than 5',
+      "3": 0,
+      "6": 2,
+      "else": 3
+    },
+    {
+      'description': 'second host if amount less than 3, second host if amount less than 6, third host if amount less than 31, sixth host if amount more than 30',
+      "3": 1,
+      "6": 1,
+      "31": 2,
+      "else": 5
+    }
+  ]);
+
+  var test_config = [
+    {
+      title: '1 host',
+      hosts: ['host0'],
+      equals: [0, 0, 0, 0]
+    },
+    {
+      title: '2 hosts',
+      hosts: ['host0', 'host1'],
+      equals: [0, 1, 0, 1]
+    },
+    {
+      title: '3 hosts',
+      hosts: ['host0', 'host1', 'host2'],
+      equals: [0, 1, 2, 1]
+    },
+    {
+      title: '5 hosts',
+      hosts: ['host0', 'host1', 'host2', 'host3', 'host4'],
+      equals: [0, 1, 2, 1]
+    },
+    {
+      title: '6 hosts',
+      hosts: ['host0', 'host1', 'host2', 'host3', 'host4', 'host6'],
+      equals: [0, 1, 3, 2]
+    },
+    {
+      title: '10 hosts',
+      hosts: ['host0', 'host1', 'host2', 'host3', 'host4', 'host5', 'host6', 'host7', 'host8', 'host9'],
+      equals: [0, 1, 3, 2]
+    },
+    {
+      title: '31 hosts',
+      hosts: ['host0', 'host1', 'host2', 'host3', 'host4', 'host5', 'host6', 'host7', 'host8', 'host9', 'host10', 'host11', 'host12', 'host13', 'host14', 'host15', 'host16', 'host17', 'host18', 'host19', 'host20', 'host21', 'host22', 'host23', 'host24', 'host25', 'host26', 'host27', 'host28', 'host29', 'host30'],
+      equals: [0, 1, 3, 5]
+    }
+  ];
+
+  schemes.forEach(function(scheme, index) {
+    describe('#getHostForComponent() condition: ' + scheme.description, function() {
+
+      delete scheme['description'];
+
+      test_config.forEach(function(test) {
+        it(test.title, function () {
+          controller.get('hosts').clear();
+          test.hosts.forEach(function(_host) {
+            controller.get('hosts').pushObject(Em.Object.create({
+              host_name: _host,
+              cpu: cpu,
+              memory: memory
+            }));
+          });
+          expect(controller.getHostForComponent(test.hosts.length, scheme).host_name).to.equal(test.hosts[test.equals[index]]);
+        });
+      });
+    });
+  });
+
+  describe('#getZooKeeperServer', function() {
+    it('should be array with three host names if hosts number more than three', function() {
+      var hosts = [
+        {host_name: 'host1'},
+        {host_name: 'host2'},
+        {host_name: 'host3'}
+      ];
+
+      controller.set('hosts', hosts);
+      expect(controller.getZooKeeperServer(hosts.length)).to.eql(['host1', 'host2', 'host3']);
+    });
+
+    it('should be array with one host names if hosts number less than three', function() {
+      var hosts = [
+        {host_name: 'host1'},
+        {host_name: 'host2'}
+      ];
+
+      controller.set('hosts', hosts);
+      expect(controller.getZooKeeperServer(hosts.length)).to.eql(['host1']);
+    });
+  });
+
+  describe('#getServerHost', function() {
+    it('should be host name if one host ', function() {
+      var hosts = [
+        {host_name: 'host1'}
+      ];
+
+      controller.set('hosts', hosts);
+      expect(controller.getServerHost(hosts.length)).to.eql('host1');
+    });
+
+    it('should be host name if hosts number more than one', function() {
+      var hosts = [
+        {host_name: 'host1'},
+        {host_name: 'host2'}
+      ];
+
+      controller.set('hosts', hosts);
+      expect(controller.getServerHost(hosts.length)).to.eql('host1');
+    });
+
+    it('should be host name different from localhost if hosts number more than one', function() {
+      var hosts = [
+        {host_name: location.hostname},
+        {host_name: 'host2'}
+      ];
+      //first host_name is empty string, because of location.hostname = "" in console,
+      //to implement current test case
+
+      controller.set('hosts', hosts);
+      expect(controller.getServerHost(hosts.length)).to.eql('host2');
+    });
+  });
+
+
+  controller.set('content', {});
+
+  describe('#isReassignWizard', function() {
+    it('true if content.controllerName is reassignMasterController', function() {
+      controller.set('content.controllerName', 'reassignMasterController');
+      expect(controller.get('isReassignWizard')).to.equal(true);
+    });
+    it('false if content.controllerName is not reassignMasterController', function() {
+      controller.set('content.controllerName', 'mainController');
+      expect(controller.get('isReassignWizard')).to.equal(false);
+    });
+  });
+
+  describe('#isAddServiceWizard', function() {
+    it('true if content.controllerName is addServiceController', function() {
+      controller.set('content.controllerName', 'addServiceController');
+      expect(controller.get('isAddServiceWizard')).to.equal(true);
+    });
+    it('false if content.controllerName is not addServiceController', function() {
+      controller.set('content.controllerName', 'mainController');
+      expect(controller.get('isAddServiceWizard')).to.equal(false);
+    });
+  });
+
+  describe('#isReassignHive', function() {
+
+    var tests = Em.A([
+      {
+        servicesMasters: Em.A([{component_name: 'HIVE_SERVER'}]),
+        controllerName: 'reassignMasterController',
+        e: true
+      },
+      {
+        servicesMasters: Em.A([{component_name: 'HIVE_SERVER'}]),
+        controllerName: 'addServiceController',
+        e: false
+      },
+      {
+        servicesMasters: Em.A([{component_name: 'ZOOKEEPER_SERVER'}]),
+        controllerName: 'reassignMasterController',
+        e: false
+      },
+      {
+        servicesMasters: Em.A([{component_name: 'ZOOKEEPER_SERVER'}]),
+        controllerName: 'addServiceController',
+        e: false
+      }
+    ]);
+
+    tests.forEach(function(test) {
+      it(test.controllerName + ' ' + test.servicesMasters.mapProperty('component_name').join(','), function() {
+        controller.set('content.controllerName', test.controllerName);
+        controller.set('servicesMasters', test.servicesMasters);
+        expect(controller.get('isReassignHive')).to.equal(test.e);
+      });
+    });
+
+  });
+
+  describe('#sortHosts', function() {
+
+    var tests = Em.A([
+      {
+        hosts: [
+          Em.Object.create({memory: 4, cpu: 1, host_name: 'host1', id: 1}),
+          Em.Object.create({memory: 3, cpu: 1, host_name: 'host2', id: 2}),
+          Em.Object.create({memory: 2, cpu: 1, host_name: 'host3', id: 3}),
+          Em.Object.create({memory: 1, cpu: 1, host_name: 'host4', id: 4})
+        ],
+        m: 'memory',
+        e: [1,2,3,4]
+      },
+      {
+        hosts: [
+          Em.Object.create({memory: 1, cpu: 4, host_name: 'host1', id: 1}),
+          Em.Object.create({memory: 1, cpu: 3, host_name: 'host2', id: 2}),
+          Em.Object.create({memory: 1, cpu: 2, host_name: 'host3', id: 3}),
+          Em.Object.create({memory: 1, cpu: 1, host_name: 'host4', id: 4})
+        ],
+        m: 'cpu',
+        e: [1,2,3,4]
+      },
+      {
+        hosts: [
+          Em.Object.create({memory: 1, cpu: 1, host_name: 'host4', id: 1}),
+          Em.Object.create({memory: 1, cpu: 1, host_name: 'host2', id: 2}),
+          Em.Object.create({memory: 1, cpu: 1, host_name: 'host3', id: 3}),
+          Em.Object.create({memory: 1, cpu: 1, host_name: 'host1', id: 4})
+        ],
+        m: 'host_name',
+        e: [4,2,3,1]
+      },
+      {
+        hosts: [
+          Em.Object.create({memory: 2, cpu: 1, host_name: 'host1', id: 1}),
+          Em.Object.create({memory: 1, cpu: 2, host_name: 'host3', id: 2}),
+          Em.Object.create({memory: 1, cpu: 1, host_name: 'host4', id: 3}),
+          Em.Object.create({memory: 1, cpu: 1, host_name: 'host2', id: 4})
+        ],
+        m: 'mix',
+        e: [1,2,4,3]
+      }
+    ]);
+
+    tests.forEach(function(test) {
+      it(test.m, function() {
+        var hosts = Em.copy(test.hosts);
+        controller.sortHosts(hosts);
+        expect(Em.A(hosts).mapProperty('id')).to.eql(test.e);
+      });
+    });
+
+  });
+
+  describe('#renderHostInfo', function() {
+
+    var tests = Em.A([
+      {
+        hosts: {
+          h1: {memory: 4, cpu: 1, name: 'host1', bootStatus: 'INIT'},
+          h2: {memory: 3, cpu: 1, name: 'host2', bootStatus: 'INIT'},
+          h3: {memory: 2, cpu: 1, name: 'host3', bootStatus: 'INIT'},
+          h4: {memory: 1, cpu: 1, name: 'host4', bootStatus: 'INIT'}
+        },
+        m: 'no one host is REGISTERED',
+        e: []
+      },
+      {
+        hosts: {
+          h1: {memory: 4, cpu: 1, name: 'host1', bootStatus: 'REGISTERED'},
+          h2: {memory: 3, cpu: 1, name: 'host2', bootStatus: 'REGISTERED'},
+          h3: {memory: 2, cpu: 1, name: 'host3', bootStatus: 'REGISTERED'},
+          h4: {memory: 1, cpu: 1, name: 'host4', bootStatus: 'REGISTERED'}
+        },
+        m: 'all hosts are REGISTERED, memory',
+        e: ['host1', 'host2', 'host3', 'host4']
+      },
+      {
+        hosts: {
+          h1: {memory: 1, cpu: 4, name: 'host1', bootStatus: 'REGISTERED'},
+          h2: {memory: 1, cpu: 3, name: 'host2', bootStatus: 'REGISTERED'},
+          h3: {memory: 1, cpu: 2, name: 'host3', bootStatus: 'REGISTERED'},
+          h4: {memory: 1, cpu: 1, name: 'host4', bootStatus: 'REGISTERED'}
+        },
+        m: 'all hosts are REGISTERED, cpu',
+        e: ['host1', 'host2', 'host3', 'host4']
+      },
+      {
+        hosts: {
+          h1: {memory: 1, cpu: 1, name: 'host4', bootStatus: 'REGISTERED'},
+          h2: {memory: 1, cpu: 1, name: 'host2', bootStatus: 'REGISTERED'},
+          h3: {memory: 1, cpu: 1, name: 'host3', bootStatus: 'REGISTERED'},
+          h4: {memory: 1, cpu: 1, name: 'host1', bootStatus: 'REGISTERED'}
+        },
+        m: 'all hosts are REGISTERED, host_name',
+        e: ['host1', 'host2', 'host3', 'host4']
+      },
+      {
+        hosts: {
+          h1: {memory: 2, cpu: 1, name: 'host1', bootStatus: 'REGISTERED'},
+          h2: {memory: 1, cpu: 2, name: 'host3', bootStatus: 'INIT'},
+          h3: {memory: 1, cpu: 1, name: 'host4', bootStatus: 'REGISTERED'},
+          h4: {memory: 1, cpu: 1, name: 'host2', bootStatus: 'INIT'}
+        },
+        m: 'mix',
+        e: ['host1', 'host4']
+      }
+    ]);
+
+    tests.forEach(function(test) {
+      it(test.m, function() {
+        controller.set('content', {hosts: test.hosts});
+        controller.renderHostInfo();
+        var r = controller.get('hosts');
+        expect(Em.A(r).mapProperty('host_name')).to.eql(test.e);
+      });
+    });
+
+  });
+
+  describe('#hasHiveServer', function() {
+
+    var tests = Em.A([
+      {
+        selectedServicesMasters: Em.A([{component_name: 'HIVE_SERVER'}]),
+        controllerName: 'reassignMasterController',
+        e: false
+      },
+      {
+        selectedServicesMasters: Em.A([{component_name: 'HIVE_SERVER'}]),
+        controllerName: 'addServiceController',
+        e: true
+      },
+      {
+        selectedServicesMasters: Em.A([{component_name: 'ANOTHER'}]),
+        controllerName: 'addServiceController',
+        e: false
+      },
+      {
+        selectedServicesMasters: Em.A([{component_name: 'ANOTHER'}]),
+        controllerName: 'reassignMasterController',
+        e: false
+      }
+    ]);
+
+    tests.forEach(function(test) {
+      it(test.controllerName + ' ' + test.selectedServicesMasters.mapProperty('component_name').join(','), function() {
+        controller.set('content.controllerName', test.controllerName);
+        controller.set('selectedServicesMasters', test.selectedServicesMasters);
+        expect(controller.get('hasHiveServer')).to.equal(test.e);
+      });
+    });
+
+  });
+
+  describe('#selectHost', function() {
+
+    var tests = Em.A([
+      {componentName: 'KERBEROS_SERVER', hostsCount: 1, e: 'host1'},
+      {componentName: 'KERBEROS_SERVER', hostsCount: 3, e: 'host2'},
+      {componentName: 'KERBEROS_SERVER', hostsCount: 6, e: 'host4'},
+      {componentName: 'KERBEROS_SERVER', hostsCount: 31, e: 'host6'},
+      {componentName: 'KERBEROS_SERVER', hostsCount: 32, e: 'host6'},
+      {componentName: 'NAMENODE', hostsCount: 1, e: 'host1'},
+      {componentName: 'NAMENODE', hostsCount: 2, e: 'host1'},
+      {componentName: 'SECONDARY_NAMENODE', hostsCount: 1, e: 'host1'},
+      {componentName: 'SECONDARY_NAMENODE', hostsCount: 2, e: 'host2'},
+      {componentName: 'JOBTRACKER', hostsCount: 1, e: 'host1'},
+      {componentName: 'JOBTRACKER', hostsCount: 3, e: 'host2'},
+      {componentName: 'JOBTRACKER', hostsCount: 6, e: 'host2'},
+      {componentName: 'JOBTRACKER', hostsCount: 31, e: 'host3'},
+      {componentName: 'JOBTRACKER', hostsCount: 32, e: 'host3'},
+      {componentName: 'HISTORYSERVER', hostsCount: 1, e: 'host1'},
+      {componentName: 'HISTORYSERVER', hostsCount: 3, e: 'host2'},
+      {componentName: 'HISTORYSERVER', hostsCount: 6, e: 'host2'},
+      {componentName: 'HISTORYSERVER', hostsCount: 31, e: 'host3'},
+      {componentName: 'HISTORYSERVER', hostsCount: 32, e: 'host3'},
+      {componentName: 'RESOURCEMANAGER', hostsCount: 1, e: 'host1'},
+      {componentName: 'RESOURCEMANAGER', hostsCount: 3, e: 'host2'},
+      {componentName: 'RESOURCEMANAGER', hostsCount: 6, e: 'host2'},
+      {componentName: 'RESOURCEMANAGER', hostsCount: 31, e: 'host3'},
+      {componentName: 'RESOURCEMANAGER', hostsCount: 32, e: 'host3'},
+      {componentName: 'HBASE_MASTER', hostsCount: 1, e: ['host1']},
+      {componentName: 'HBASE_MASTER', hostsCount: 3, e: ['host1']},
+      {componentName: 'HBASE_MASTER', hostsCount: 6, e: ['host3']},
+      {componentName: 'HBASE_MASTER', hostsCount: 31, e: ['host4']},
+      {componentName: 'HBASE_MASTER', hostsCount: 32, e: ['host4']},
+      {componentName: 'OOZIE_SERVER', hostsCount: 1, e: 'host1'},
+      {componentName: 'OOZIE_SERVER', hostsCount: 3, e: 'host2'},
+      {componentName: 'OOZIE_SERVER', hostsCount: 6, e: 'host3'},
+      {componentName: 'OOZIE_SERVER', hostsCount: 31, e: 'host4'},
+      {componentName: 'OOZIE_SERVER', hostsCount: 32, e: 'host4'},
+      {componentName: 'HIVE_SERVER', hostsCount: 1, e: 'host1'},
+      {componentName: 'HIVE_SERVER', hostsCount: 3, e: 'host2'},
+      {componentName: 'HIVE_SERVER', hostsCount: 6, e: 'host3'},
+      {componentName: 'HIVE_SERVER', hostsCount: 31, e: 'host5'},
+      {componentName: 'HIVE_SERVER', hostsCount: 32, e: 'host5'},
+      {componentName: 'HIVE_METASTORE', hostsCount: 1, e: 'host1'},
+      {componentName: 'HIVE_METASTORE', hostsCount: 3, e: 'host2'},
+      {componentName: 'HIVE_METASTORE', hostsCount: 6, e: 'host3'},
+      {componentName: 'HIVE_METASTORE', hostsCount: 31, e: 'host5'},
+      {componentName: 'HIVE_METASTORE', hostsCount: 32, e: 'host5'},
+      {componentName: 'WEBHCAT_SERVER', hostsCount: 1, e: 'host1'},
+      {componentName: 'WEBHCAT_SERVER', hostsCount: 3, e: 'host2'},
+      {componentName: 'WEBHCAT_SERVER', hostsCount: 6, e: 'host3'},
+      {componentName: 'WEBHCAT_SERVER', hostsCount: 31, e: 'host5'},
+      {componentName: 'WEBHCAT_SERVER', hostsCount: 32, e: 'host5'},
+      {componentName: 'APP_TIMELINE_SERVER', hostsCount: 1, e: 'host1'},
+      {componentName: 'APP_TIMELINE_SERVER', hostsCount: 3, e: 'host2'},
+      {componentName: 'APP_TIMELINE_SERVER', hostsCount: 6, e: 'host2'},
+      {componentName: 'APP_TIMELINE_SERVER', hostsCount: 31, e: 'host3'},
+      {componentName: 'APP_TIMELINE_SERVER', hostsCount: 32, e: 'host3'},
+      {componentName: 'FALCON_SERVER', hostsCount: 1, e: 'host1'},
+      {componentName: 'FALCON_SERVER', hostsCount: 3, e: 'host2'},
+      {componentName: 'FALCON_SERVER', hostsCount: 6, e: 'host3'},
+      {componentName: 'FALCON_SERVER', hostsCount: 31, e: 'host4'},
+      {componentName: 'FALCON_SERVER', hostsCount: 32, e: 'host4'},
+    ]);
+
+    tests.forEach(function(test) {
+      it(test.componentName + ' ' + test.hostsCount, function() {
+        controller.set('hosts', d3.range(1, test.hostsCount + 1).map(function(i) { return {host_name: 'host' + i.toString()};}));
+        expect(controller.selectHost(test.componentName)).to.eql(test.e);
+      });
+    });
+
+    describe('getServerHost should be called for', function() {
+      Em.A(['STORM_UI_SERVER','DRPC_SERVER','STORM_REST_API','NIMBUS','GANGLIA_SERVER','NAGIOS_SERVER','HUE_SERVER']).forEach(function(componentName) {
+        it(componentName, function() {
+          sinon.spy(controller, 'getServerHost');
+          controller.selectHost(componentName);
+          expect(controller.getServerHost.calledOnce).to.equal(true);
+          controller.getServerHost.restore();
+        });
+      });
+    });
+
+  });
+
+  describe('#last', function() {
+
+    var tests = Em.A([
+      {
+        selectedServicesMasters: Em.A([
+          {component_name: 'c1', indx: 1},
+          {component_name: 'c2', indx: 2},
+          {component_name: 'c1', indx: 2}
+        ]),
+        m: 'Components exists',
+        c: 'c1',
+        e: 2
+      },
+      {
+        selectedServicesMasters: Em.A([
+          {component_name: 'c1', indx: 1},
+          {component_name: 'c2', indx: 2},
+          {component_name: 'c1', indx: 2}
+        ]),
+        m: 'Components don\'t exists',
+        c: 'c3',
+        e: null
+      }
+    ]);
+
+    tests.forEach(function(test) {
+      it(test.m, function() {
+        controller.set('selectedServicesMasters', test.selectedServicesMasters);
+        if (!Em.isNone(test.e)) {
+          expect(controller.last(test.c).indx).to.equal(test.e);
+        }
+        else {
+          expect(Em.isNone(controller.last(test.c))).to.equal(true);
+        }
+      })
+    });
+
+  });
+
+  describe('#isSubmitDisabled', function() {
+    it('should be false if it\'s not a isReassignWizard', function() {
+      c.set('controllerName', 'addServiceController');
+      expect(c.get('isSubmitDisabled')).to.equal(false);
+    });
+  });
+
+  describe('#remainingHosts', function() {
+    it('should show count of hosts without masters', function() {
+      c.reopen({masterHostMapping: [{}]});
+      c.set('hosts', [{},{},{}]);
+      expect(c.get('remainingHosts')).to.equal(2);
+    });
+  });
+
+  describe('#clearStep', function() {
+    var tests = Em.A([
+      {p: 'hosts'},
+      {p: 'selectedServicesMasters'},
+      {p: 'servicesMasters'}
+    ]);
+    tests.forEach(function(test) {
+      it('should cleanup ' + test.p, function() {
+        c.set(test.p, [Em.Object.create({}),Em.Object.create({})]);
+        c.clearStep();
+        expect(c.get(test.p).length).to.equal(0);
+      });
+    });
+  });
+
+  describe('#updateComponent', function() {
+    var tests = Em.A([
+      {
+        componentName: 'HBASE_SERVER',
+        services: Em.A([
+          Em.Object.create({isInstalled: true, serviceName: 'HBASE'})
+        ]),
+        selectedServicesMasters: Em.A([
+          Em.Object.create({showAddControl: false, showRemoveControl: true, component_name: 'HBASE_SERVER'}),
+          Em.Object.create({showAddControl: true, showRemoveControl: false, component_name: 'HBASE_SERVER'})
+        ]),
+        hosts: Em.A([
+          Em.Object.create({})
+        ]),
+        controllerName: 'addServiceController',
+        m: 'service is installed',
+        e: {
+          showAddControl: true,
+          showRemoveControl: false
+        }
+      },
+      {
+        componentName: 'HBASE_SERVER',
+        services: Em.A([
+          Em.Object.create({isInstalled: false, serviceName: 'HBASE'})
+        ]),
+        selectedServicesMasters: Em.A([
+          Em.Object.create({showAddControl: true, showRemoveControl: false, component_name: 'HBASE_SERVER'})
+        ]),
+        hosts: Em.A([
+          Em.Object.create({})
+        ]),
+        controllerName: 'addServiceController',
+        m: 'service not installed, but all host already have provided component',
+        e: {
+          showAddControl: true,
+          showRemoveControl: false
+        }
+      },
+      {
+        componentName: 'HBASE_SERVER',
+        services: Em.A([
+          Em.Object.create({isInstalled: false, serviceName: 'HBASE'})
+        ]),
+        selectedServicesMasters: Em.A([
+          Em.Object.create({showAddControl: false, showRemoveControl: true, component_name: 'HBASE_SERVER'})
+        ]),
+        hosts: Em.A([
+          Em.Object.create({}),
+          Em.Object.create({})
+        ]),
+        controllerName: 'addServiceController',
+        m: 'service not installed, not all host already have provided component',
+        e: {
+          showAddControl: true,
+          showRemoveControl: true
+        }
+      },
+      {
+        componentName: 'HBASE_SERVER',
+        services: Em.A([
+          Em.Object.create({isInstalled: false, serviceName: 'HBASE'})
+        ]),
+        selectedServicesMasters: Em.A([
+          Em.Object.create({showAddControl: false, showRemoveControl: true, component_name: 'HBASE_SERVER'})
+        ]),
+        hosts: Em.A([
+          Em.Object.create({}),
+          Em.Object.create({})
+        ]),
+        controllerName: 'reassignMasterController',
+        m: 'service not installed, not all host already have provided component, but is reassignMasterController',
+        e: {
+          showAddControl: false,
+          showRemoveControl: false
+        }
+      }
+    ]);
+
+    tests.forEach(function(test) {
+      it(test.m, function() {
+        c.reopen({
+          content: Em.Object.create({
+            services: test.services,
+            controllerName: test.controllerName
+          }),
+          selectedServicesMasters: test.selectedServicesMasters
+        });
+        c.updateComponent(test.componentName);
+        Em.keys(test.e).forEach(function(k) {
+          expect(c.last(test.componentName).get(k)).to.equal(test.e[k]);
+        });
+      });
+    });
+  });
+
+  describe('#renderComponents', function() {
+    var tests = Em.A([
+      {
+        masterComponents: Em.A([
+          {component_name: 'ZOOKEEPER_SERVER'}
+        ]),
+        services: Em.A([]),
+        controllerName: 'reassignMasterController',
+        m: 'One component',
+        isHaEnabled: false,
+        component_name: 'ZOOKEEPER_SERVER',
+        e: {
+          selectedServicesMasters: ['ZOOKEEPER_SERVER'],
+          servicesMasters: ['ZOOKEEPER_SERVER'],
+          showRemoveControl: [false],
+          isInstalled: [false],
+          zId: [1]
+        }
+      },
+      {
+        masterComponents: Em.A([
+          {component_name: 'ZOOKEEPER_SERVER'},
+          {component_name: 'SECONDARY_NAMENODE'}
+        ]),
+        services: Em.A([]),
+        controllerName: 'addServiceController',
+        m: 'One component',
+        isHaEnabled: true,
+        component_name: 'ZOOKEEPER_SERVER',
+        e: {
+          selectedServicesMasters: ['ZOOKEEPER_SERVER'],
+          servicesMasters: ['ZOOKEEPER_SERVER'],
+          showRemoveControl: [false],
+          zId: [1]
+        }
+      },
+      {
+        masterComponents: Em.A([
+          {component_name: 'ZOOKEEPER_SERVER'},
+          {component_name: 'ZOOKEEPER_SERVER'}
+        ]),
+        services: Em.A([
+          Em.Object.create({serviceName:'ZOOKEEPER', isInstalled: true})
+        ]),
+        controllerName: 'addServiceController',
+        m: 'Two components, but service is installed',
+        isHaEnabled: false,
+        component_name: 'ZOOKEEPER_SERVER',
+        e: {
+          selectedServicesMasters: ['ZOOKEEPER_SERVER', 'ZOOKEEPER_SERVER'],
+          servicesMasters: ['ZOOKEEPER_SERVER', 'ZOOKEEPER_SERVER'],
+          showRemoveControl: [false, false],
+          zId: [1, 2]
+        }
+      },
+      {
+        masterComponents: Em.A([
+          {component_name: 'ZOOKEEPER_SERVER'},
+          {component_name: 'ZOOKEEPER_SERVER'},
+          {component_name: 'NAMENODE'}
+        ]),
+        services: Em.A([
+        ]),
+        controllerName: 'addServiceController',
+        m: 'Two components, but service is installed',
+        isHaEnabled: false,
+        component_name: 'ZOOKEEPER_SERVER',
+        e: {
+          selectedServicesMasters: ['ZOOKEEPER_SERVER', 'ZOOKEEPER_SERVER', 'NAMENODE'],
+          servicesMasters: ['ZOOKEEPER_SERVER', 'ZOOKEEPER_SERVER', 'NAMENODE'],
+          showRemoveControl: [true, true, undefined],
+          zId: [1, 2, 1]
+        }
+      }
+    ]);
+    tests.forEach(function(test) {
+      beforeEach(function() {
+        App.reopen({isHaEnabled: test.isHaEnabled});
+      });
+      it(test.m, function() {
+        App.set('isHaEnabled', test.isHaEnabled);
+        c.reopen({
+          content: Em.Object.create({
+            services: test.services,
+            controllerName: test.controllerName,
+            reassign: {component_name: test.component_name}
+          })
+        });
+        c.renderComponents(test.masterComponents);
+        expect(c.get('selectedServicesMasters').mapProperty('component_name')).to.eql(test.e.selectedServicesMasters);
+        expect(c.get('servicesMasters').mapProperty('component_name')).to.eql(test.e.servicesMasters);
+        expect(c.get('selectedServicesMasters').mapProperty('showRemoveControl')).to.eql(test.e.showRemoveControl);
+        expect(c.get('selectedServicesMasters').mapProperty('zId')).to.eql(test.e.zId);
+        if (c.get('isReasignController')) {
+          expect(c.get('servicesMasters').mapProperty('isInstalled')).to.eql(test.e.isInstalled);
+        }
+      });
+    });
+  });
+
+  describe('#updateHiveCoHosts', function() {
+    var tests = Em.A([
+      {
+        selectedServicesMasters: Em.A([
+          Em.Object.create({component_name: 'HIVE_SERVER', selectedHost: 'h1'}),
+          Em.Object.create({component_name: 'HIVE_METASTORE', selectedHost: 'h2'}),
+          Em.Object.create({component_name: 'WEBHCAT_SERVER', selectedHost: 'h3'})
+        ]),
+        servicesMasters: Em.A([
+          Em.Object.create({component_name: 'HIVE_SERVER', selectedHost: 'h1'})
+        ]),
+        isReassignHive: false,
+        m: 'should set new host for both',
+        e: ['h1','h1','h1']
+      },
+      {
+        selectedServicesMasters: Em.A([
+          Em.Object.create({component_name: 'HIVE_SERVER', selectedHost: 'h1'}),
+          Em.Object.create({component_name: 'HIVE_METASTORE', selectedHost: 'h2'}),
+          Em.Object.create({component_name: 'WEBHCAT_SERVER', selectedHost: 'h3'})
+        ]),
+        servicesMasters: Em.A([
+          Em.Object.create({component_name: 'HIVE_METASTORE', selectedHost: 'h1'})
+        ]),
+        isReassignHive: false,
+        m: 'should set new host for WEBHCAT_SERVER',
+        e: ['h1','h2','h1']
+      },
+      {
+        selectedServicesMasters: Em.A([
+          Em.Object.create({component_name: 'HIVE_METASTORE', selectedHost: 'h2'}),
+          Em.Object.create({component_name: 'WEBHCAT_SERVER', selectedHost: 'h3'})
+        ]),
+        servicesMasters: Em.A([
+          Em.Object.create({component_name: 'HIVE_METASTORE', selectedHost: 'h1'})
+        ]),
+        isReassignHive: false,
+        m: 'missing HIVE_SERVER',
+        e: ['h2','h3']
+      }
+    ]);
+
+    tests.forEach(function(test) {
+      it(test.m, function() {
+        c.set('selectedServicesMasters', test.selectedServicesMasters);
+        c.set('servicesMasters', test.servicesMasters);
+        c.reopen({isReassignHive: test.isReassignHive});
+        c.updateHiveCoHosts();
+        expect(c.get('selectedServicesMasters').mapProperty('selectedHost')).to.eql(test.e);
+      });
+    });
+
+  });
+
+  describe('#assignHostToMaster', function() {
+    var tests = Em.A([
+      {
+        componentName: 'c1',
+        selectedHost: 'h2',
+        zId: '1',
+        e: {
+          indx: 0
+        }
+      },
+      {
+        componentName: 'c2',
+        selectedHost: 'h3',
+        zId: '2',
+        e: {
+          indx: 3
+        }
+      },
+      {
+        componentName: 'c3',
+        selectedHost: 'h1',
+        e: {
+          indx: 2
+        }
+      },
+      {
+        componentName: 'c2',
+        selectedHost: 'h4',
+        e: {
+          indx: 1
+        }
+      }
+    ]),
+    selectedServicesMasters = Em.A([
+      Em.Object.create({component_name: 'c1', zId: '1', selectedHost: 'h1'}),
+      Em.Object.create({component_name: 'c2', zId: '1', selectedHost: 'h1'}),
+      Em.Object.create({component_name: 'c3', zId: '1', selectedHost: 'h3'}),
+      Em.Object.create({component_name: 'c2', zId: '2', selectedHost: 'h2'})
+    ]);
+
+    tests.forEach(function(test) {
+      it(test.componentName + ' ' + test.selectedHost + ' ' + test.zId, function() {
+        c.set('selectedServicesMasters', selectedServicesMasters);
+        c.assignHostToMaster(test.componentName, test.selectedHost, test.zId);
+        expect(c.get('selectedServicesMasters').objectAt(test.e.indx).get('selectedHost')).to.equal(test.selectedHost);
+      })
+    });
+  });
+
+  describe('#submit', function() {
+    beforeEach(function() {
+      sinon.spy(App.router, 'send');
+    });
+    afterEach(function() {
+      App.router.send.restore();
+    });
+    it('should go next if not isSubmitDisabled', function() {
+      c.reopen({isSubmitDisabled: false});
+      c.submit();
+      expect(App.router.send.calledWith('next')).to.equal(true);
+    });
+    it('shouldn\'t go next if isSubmitDisabled', function() {
+      c.reopen({isSubmitDisabled: true});
+      c.submit();
+      expect(App.router.send.called).to.equal(false);
+    });
+  });
+
+  describe('#removeComponent', function() {
+    var tests = Em.A([
+      {
+        componentName: 'c1',
+        zId: 1,
+        selectedServicesMasters: Em.A([]),
+        hosts: [],
+        m: 'empty selectedServicesMasters',
+        e: false
+      },
+      {
+        componentName: 'ZOOKEPEER_SERVER',
+        zId: 1,
+        selectedServicesMasters: Em.A([
+          Em.Object.create({zId: 1, component_name: 'HBASE_SERVER'})
+        ]),
+        hosts: [],
+        m: 'no such components',
+        e: false
+      },
+      {
+        componentName: 'ZOOKEPEER_SERVER',
+        zId: 1,
+        selectedServicesMasters: Em.A([
+          Em.Object.create({zId: 1, component_name: 'ZOOKEPEER_SERVER'})
+        ]),
+        hosts: [],
+        m: 'component is only 1',
+        e: false
+      },
+      {
+        componentName: 'ZOOKEPEER_SERVER',
+        zId: 2,
+        selectedServicesMasters: Em.A([
+          Em.Object.create({zId: 1, component_name: 'ZOOKEPEER_SERVER', showAddControl: false, showRemoveControl: false}),
+          Em.Object.create({zId: 2, component_name: 'ZOOKEPEER_SERVER', showAddControl: false, showRemoveControl: false})
+        ]),
+        hosts: [{},{}],
+        m: 'two components, add allowed, remove not allowed',
+        e: true,
+        showAddControl: true,
+        showRemoveControl: false
+      },
+      {
+        componentName: 'ZOOKEPEER_SERVER',
+        zId: 2,
+        selectedServicesMasters: Em.A([
+          Em.Object.create({zId: 1, component_name: 'ZOOKEPEER_SERVER', showAddControl: false, showRemoveControl: false}),
+          Em.Object.create({zId: 2, component_name: 'ZOOKEPEER_SERVER', showAddControl: false, showRemoveControl: false})
+        ]),
+        hosts: [{}],
+        m: 'two components, add not allowed, remove not allowed',
+        e: true,
+        showAddControl: false,
+        showRemoveControl: false
+      },
+      {
+        componentName: 'ZOOKEPEER_SERVER',
+        zId: 2,
+        selectedServicesMasters: Em.A([
+          Em.Object.create({zId: 1, component_name: 'ZOOKEPEER_SERVER', showAddControl: false, showRemoveControl: false}),
+          Em.Object.create({zId: 2, component_name: 'ZOOKEPEER_SERVER', showAddControl: false, showRemoveControl: false}),
+          Em.Object.create({zId: 3, component_name: 'ZOOKEPEER_SERVER', showAddControl: false, showRemoveControl: true})
+        ]),
+        hosts: [{},{}],
+        m: 'three components, add not allowed, remove allowed',
+        e: true,
+        showAddControl: false,
+        showRemoveControl: true
+      },
+      {
+        componentName: 'ZOOKEPEER_SERVER',
+        zId: 2,
+        selectedServicesMasters: Em.A([
+          Em.Object.create({zId: 1, component_name: 'ZOOKEPEER_SERVER', showAddControl: false, showRemoveControl: false}),
+          Em.Object.create({zId: 2, component_name: 'ZOOKEPEER_SERVER', showAddControl: false, showRemoveControl: false}),
+          Em.Object.create({zId: 3, component_name: 'ZOOKEPEER_SERVER', showAddControl: false, showRemoveControl: true})
+        ]),
+        hosts: [{},{}, {}],
+        m: 'three components, add allowed, remove allowed',
+        e: true,
+        showAddControl: true,
+        showRemoveControl: true
+      }
+    ]);
+    tests.forEach(function(test) {
+      it(test.m, function() {
+        c.set('selectedServicesMasters', test.selectedServicesMasters);
+        c.set('hosts', test.hosts);
+        expect(c.removeComponent(test.componentName, test.zId)).to.equal(test.e);
+        if(test.e) {
+          expect(c.get('selectedServicesMasters.lastObject.showRemoveControl')).to.equal(test.showRemoveControl);
+          expect(c.get('selectedServicesMasters.lastObject.showAddControl')).to.equal(test.showAddControl);
+        }
+      })
+    });
+  });
+
+  describe('#addComponent', function() {
+    var tests = Em.A([
+      {
+        componentName: 'c1',
+        selectedServicesMasters: Em.A([]),
+        hosts: [],
+        m: 'empty selectedServicesMasters',
+        e: false
+      },
+      {
+        componentName: 'ZOOKEPEER_SERVER',
+        selectedServicesMasters: Em.A([
+          Em.Object.create({zId: 1, component_name: 'HBASE_SERVER'})
+        ]),
+        hosts: [],
+        m: 'no such components',
+        e: false
+      },
+      {
+        componentName: 'ZOOKEPEER_SERVER',
+        selectedServicesMasters: Em.A([
+          Em.Object.create({zId: 1, component_name: 'ZOOKEPEER_SERVER'})
+        ]),
+        hosts: [],
+        m: 'one component, 0 hosts',
+        e: false
+      },
+      {
+        componentName: 'ZOOKEPEER_SERVER',
+        selectedServicesMasters: Em.A([
+          Em.Object.create({zId: 1, component_name: 'ZOOKEPEER_SERVER', showAddControl: false, showRemoveControl: false}),
+          Em.Object.create({zId: 2, component_name: 'ZOOKEPEER_SERVER', showAddControl: false, showRemoveControl: false})
+        ]),
+        hosts: [Em.Object.create({}), Em.Object.create({})],
+        m: 'two components, two hosts',
+        e: false
+      },
+      {
+        componentName: 'ZOOKEPEER_SERVER',
+        selectedServicesMasters: Em.A([
+          Em.Object.create({zId: 1, component_name: 'ZOOKEPEER_SERVER', showAddControl: false, showRemoveControl: false}),
+          Em.Object.create({zId: 2, component_name: 'ZOOKEPEER_SERVER', showAddControl: false, showRemoveControl: false})
+        ]),
+        hosts: [Em.Object.create({}), Em.Object.create({}), Em.Object.create({})],
+        m: 'two components, 3 hosts',
+        e: true
+      }
+    ]);
+    tests.forEach(function(test) {
+      it(test.m, function() {
+        c.set('selectedServicesMasters', test.selectedServicesMasters);
+        c.set('hosts', test.hosts);
+        expect(c.addComponent(test.componentName)).to.equal(test.e);
+      });
+    });
+  });
+
+  describe('#loadStep', function() {
+    var methods = Em.A(['clearStep', 'renderHostInfo', 'renderComponents', 'loadComponents']);
+    describe('should call several methods', function() {
+      beforeEach(function() {
+        methods.forEach(function(m) {
+          sinon.spy(c, m);
+        });
+        c.reopen({content: {services: Em.A([])}});
+      });
+      afterEach(function() {
+        methods.forEach(function(m) {
+          c[m].restore();
+        });
+      });
+      methods.forEach(function(m) {
+        it(m, function() {
+          c.loadStep();
+          expect(c[m].calledOnce).to.equal(true);
+        });
+      });
+    });
+    it('should update HBASE if App.supports.multipleHBaseMasters is true', function() {
+      App.set('supports.multipleHBaseMasters', true);
+      sinon.spy(c, 'updateComponent');
+      c.reopen({content: {services: Em.A([])}});
+      c.loadStep();
+      expect(c.updateComponent.calledTwice).to.equal(true);
+      c.updateComponent.restore();
+    });
+  });
+
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/1d0fe34b/ambari-web/test/controllers/wizard/step6_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/wizard/step6_test.js b/ambari-web/test/controllers/wizard/step6_test.js
new file mode 100644
index 0000000..536503f
--- /dev/null
+++ b/ambari-web/test/controllers/wizard/step6_test.js
@@ -0,0 +1,1356 @@
+/**
+ * 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 Ember = require('ember');
+var App = require('app');
+require('utils/helper');
+require('controllers/wizard/step6_controller');
+var controller,
+  services = [
+    Em.Object.create({
+      serviceName: 'MAPREDUCE',
+      isSelected: true
+    }),
+    Em.Object.create({
+      serviceName: 'YARN',
+      isSelected: true
+    }),
+    Em.Object.create({
+      serviceName: 'HBASE',
+      isSelected: true
+    }),
+    Em.Object.create({
+      serviceName: 'HDFS',
+      isSelected: true
+    }),
+    Em.Object.create({
+      serviceName: 'STORM',
+      isSelected: true
+    }),
+    Em.Object.create({
+      serviceName: 'FLUME',
+      isSelected: true
+    })
+  ];
+describe('App.WizardStep6Controller', function () {
+
+  beforeEach(function () {
+    controller = App.WizardStep6Controller.create();
+    controller.set('content', {
+      hosts: {},
+      masterComponentHosts: {},
+      services: services
+    });
+    sinon.stub(controller, 'getComponentDisplayName', function (c) {
+      return App.format.components[c];
+    });
+
+    var h = {}, m = [];
+    Em.A(['host0', 'host1', 'host2', 'host3']).forEach(function (hostName) {
+      var obj = Em.Object.create({
+        name: hostName,
+        hostName: hostName,
+        bootStatus: 'REGISTERED'
+      });
+      h[hostName] = obj;
+      m.push(obj);
+    });
+
+    controller.set('content.hosts', h);
+    controller.set('content.masterComponentHosts', m);
+    controller.set('isMasters', false);
+
+  });
+
+  afterEach(function () {
+    controller.getComponentDisplayName.restore();
+  });
+
+  describe('#loadStep', function () {
+    Em.A([
+        {
+          isMasters: false,
+          services: [
+            Em.Object.create({
+              serviceName: 'MAPREDUCE',
+              isSelected: true
+            })
+          ],
+          e: {
+            l: 2,
+            allChecked: false,
+            noChecked: true
+          }
+        },
+        {
+          isMasters: false,
+          services: [
+            Em.Object.create({
+              serviceName: 'MAPREDUCE',
+              isSelected: true
+            }),
+            Em.Object.create({
+              serviceName: 'YARN',
+              isSelected: true
+            })
+          ],
+          e: {
+            l: 3,
+            allChecked: false,
+            noChecked: true
+          }
+        },
+        {
+          isMasters: false,
+          services: [
+            Em.Object.create({
+              serviceName: 'MAPREDUCE',
+              isSelected: true
+            }),
+            Em.Object.create({
+              serviceName: 'YARN',
+              isSelected: true
+            }),
+            Em.Object.create({
+              serviceName: 'HBASE',
+              isSelected: true
+            })
+          ],
+          e: {
+            l: 4,
+            allChecked: false,
+            noChecked: true
+          }
+        },
+        {
+          isMasters: false,
+          services: [
+            Em.Object.create({
+              serviceName: 'MAPREDUCE',
+              isSelected: true
+            }),
+            Em.Object.create({
+              serviceName: 'YARN',
+              isSelected: true
+            }),
+            Em.Object.create({
+              serviceName: 'HBASE',
+              isSelected: true
+            }),
+            Em.Object.create({
+              serviceName: 'HDFS',
+              isSelected: true
+            })
+          ],
+          e: {
+            l: 5,
+            allChecked: false,
+            noChecked: true
+          }
+        },
+        {
+          isMasters: false,
+          services: [
+            Em.Object.create({
+              serviceName: 'MAPREDUCE',
+              isSelected: true
+            }),
+            Em.Object.create({
+              serviceName: 'YARN',
+              isSelected: true
+            }),
+            Em.Object.create({
+              serviceName: 'HBASE',
+              isSelected: true
+            }),
+            Em.Object.create({
+              serviceName: 'HDFS',
+              isSelected: true
+            }),
+            Em.Object.create({
+              serviceName: 'STORM',
+              isSelected: true
+            })
+          ],
+          e: {
+            l: 6,
+            allChecked: false,
+            noChecked: true
+          }
+        },
+        {
+          isMasters: false,
+          services: [
+            Em.Object.create({
+              serviceName: 'MAPREDUCE',
+              isSelected: true
+            }),
+            Em.Object.create({
+              serviceName: 'YARN',
+              isSelected: true
+            }),
+            Em.Object.create({
+              serviceName: 'HBASE',
+              isSelected: true
+            }),
+            Em.Object.create({
+              serviceName: 'HDFS',
+              isSelected: true
+            }),
+            Em.Object.create({
+              serviceName: 'STORM',
+              isSelected: true
+            }),
+            Em.Object.create({
+              serviceName: 'FLUME',
+              isSelected: true
+            })
+          ],
+          e: {
+            l: 7,
+            allChecked: false,
+            noChecked: true
+          }
+        },
+        {
+          isMasters: true,
+          multipleHBaseMasters: true,
+          services: [
+            Em.Object.create({
+              serviceName: 'HBASE',
+              isSelected: true
+            })
+          ],
+          e: {
+            l: 1,
+            allChecked: false,
+            noChecked: true
+          }
+        },
+        {
+          isMasters: true,
+          multipleHBaseMasters: false,
+          services: [
+            Em.Object.create({
+              serviceName: 'HBASE',
+              isSelected: true
+            })
+          ],
+          e: {
+            l: 0,
+            allChecked: false,
+            noChecked: true
+          }
+        },
+        {
+          isMasters: true,
+          services: [
+            Em.Object.create({
+              serviceName: 'ZOOKEEPER',
+              isSelected: true
+            })
+          ],
+          e: {
+            l: 1,
+            allChecked: false,
+            noChecked: true
+          }
+        }
+      ]).forEach(function (test) {
+        it(test.isMasters.toString() + ' ' + test.services.mapProperty('serviceName').join(', '), function () {
+          if (test.hasOwnProperty('multipleHBaseMasters')) {
+            App.set('supports.multipleHBaseMasters', test.multipleHBaseMasters);
+          }
+          controller.set('content.services', test.services);
+          controller.set('isMasters', test.isMasters);
+          sinon.stub(controller, 'render', Em.K);
+          controller.loadStep();
+          expect(controller.get('headers.length')).to.equal(test.e.l);
+          expect(controller.get('headers').everyProperty('allChecked', test.e.allChecked)).to.equal(true);
+          expect(controller.get('headers').everyProperty('noChecked', test.e.noChecked)).to.equal(true);
+          controller.clearStep();
+          controller.render.restore();
+        });
+      });
+
+    Em.A([
+        {
+          p: {
+            isMasters: true,
+            skipMasterStep: true
+          },
+          e: true
+        },
+        {
+          p: {
+            isMasters: false,
+            skipMasterStep: true
+          },
+          e: false
+        },
+        {
+          p: {
+            isMasters: true,
+            skipMasterStep: false
+          },
+          e: false
+        },
+        {
+          p: {
+            isMasters: false,
+            skipMasterStep: false
+          },
+          e: false
+        }
+      ]).forEach(function (test) {
+        it('should skip this step if isMasters is ' + test.p.isMasters + ' and content.skipMasterStep is ' + test.p.skipMasterStep, function () {
+          controller.set('isMasters', test.p.isMasters);
+          controller.set('content.skipMasterStep', test.p.skipMasterStep);
+          sinon.stub(App.router, 'send', Em.K);
+          controller.loadStep();
+          expect(App.router.send.calledWith('next')).to.equal(test.e);
+          App.router.send.restore();
+        });
+      });
+
+    Em.A([
+        {
+          p: {
+            isMasters: true,
+            skipSlavesStep: true
+          },
+          e: false
+        },
+        {
+          p: {
+            isMasters: false,
+            skipSlavesStep: true
+          },
+          e: true
+        },
+        {
+          p: {
+            isMasters: true,
+            skipSlavesStep: false
+          },
+          e: false
+        },
+        {
+          p: {
+            isMasters: false,
+            skipSlavesStep: false
+          },
+          e: false
+        }
+      ]).forEach(function (test) {
+        it('should skip this step if isMasters is ' + test.p.isMasters + ' and content.skipSlavesStep is ' + test.p.skipSlavesStep, function () {
+          controller.set('isMasters', test.p.isMasters);
+          controller.set('content.skipSlavesStep', test.p.skipSlavesStep);
+          sinon.stub(App.router, 'send', Em.K);
+          controller.loadStep();
+          expect(App.router.send.calledWith('next')).to.equal(test.e);
+          App.router.send.restore();
+        });
+      });
+
+  });
+
+  describe('#isAddHostWizard', function () {
+    it('true if content.controllerName is addHostController', function () {
+      controller.set('content.controllerName', 'addHostController');
+      expect(controller.get('isAddHostWizard')).to.equal(true);
+    });
+    it('false if content.controllerName is not addHostController', function () {
+      controller.set('content.controllerName', 'mainController');
+      expect(controller.get('isAddHostWizard')).to.equal(false);
+    });
+  });
+
+  describe('#isInstallerWizard', function () {
+    it('true if content.controllerName is addHostController', function () {
+      controller.set('content.controllerName', 'installerController');
+      expect(controller.get('isInstallerWizard')).to.equal(true);
+    });
+    it('false if content.controllerName is not addHostController', function () {
+      controller.set('content.controllerName', 'mainController');
+      expect(controller.get('isInstallerWizard')).to.equal(false);
+    });
+  });
+
+  describe('#isAddServiceWizard', function () {
+    it('true if content.controllerName is addServiceController', function () {
+      controller.set('content.controllerName', 'addServiceController');
+      expect(controller.get('isAddServiceWizard')).to.equal(true);
+    });
+    it('false if content.controllerName is not addServiceController', function () {
+      controller.set('content.controllerName', 'mainController');
+      expect(controller.get('isAddServiceWizard')).to.equal(false);
+    });
+  });
+
+  describe('#setAllNodes', function () {
+
+    var test_config = Em.A([
+      {
+        title: 'DataNode',
+        name: 'DATANODE',
+        state: false
+      },
+      {
+        title: 'DataNode',
+        name: 'DATANODE',
+        state: true
+      },
+      {
+        title: 'TaskTracker',
+        name: 'TASKTRACKER',
+        state: false
+      },
+      {
+        title: 'TaskTracker',
+        name: 'TASKTRACKER',
+        state: true
+      }
+    ]);
+
+    test_config.forEach(function (test) {
+      it((test.state ? 'Select' : 'Deselect') + ' all ' + test.title, function () {
+        controller.loadStep();
+        controller.setAllNodes(test.name, test.state);
+        var hosts = controller.get('hosts');
+        hosts.forEach(function (host) {
+          var cb = host.get('checkboxes').filterProperty('isInstalled', false).findProperty('component', test.name);
+          if (cb) {
+            expect(cb.get('checked')).to.equal(test.state);
+          }
+        });
+      });
+    });
+
+
+  });
+
+  describe('#isServiceSelected', function () {
+    describe('selected', function () {
+      services.forEach(function (service) {
+        it(service.serviceName + ' is selected', function () {
+          expect(controller.isServiceSelected(service.serviceName)).to.equal(true);
+        });
+      });
+    });
+    var unselectedService = 'FAKESERVICE';
+    it(unselectedService + ' is not selected', function () {
+      expect(controller.isServiceSelected(unselectedService)).to.equal(false);
+    });
+  });
+
+  describe('#validateEachComponent', function () {
+    beforeEach(function () {
+      controller.loadStep();
+    });
+    it('Nothing checked', function () {
+      controller.get('hosts').forEach(function (host) {
+        host.get('checkboxes').setEach('checked', false);
+      });
+      expect(controller.validateEachComponent('')).to.equal(false);
+    });
+    it('One slave is not selected for no one host', function () {
+      controller.get('hosts').forEach(function (host) {
+        host.get('checkboxes').forEach(function (checkbox, index) {
+          checkbox.set('checked', index === 0);
+        });
+      });
+      expect(controller.validateEachComponent('')).to.equal(false);
+    });
+    it('All checked', function () {
+      controller.get('hosts').forEach(function (host) {
+        host.get('checkboxes').forEach(function (checkbox) {
+          checkbox.set('checked', true);
+        });
+      });
+      expect(controller.validateEachComponent('')).to.equal(true);
+    });
+  });
+
+  describe('#validateEachHost', function () {
+    beforeEach(function () {
+      controller.loadStep();
+    });
+    it('Nothing checked', function () {
+      controller.get('hosts').forEach(function (host) {
+        host.get('checkboxes').setEach('checked', false);
+      });
+      expect(controller.validateEachHost('')).to.equal(false);
+    });
+    it('One host doesn\'t have assigned slaves', function () {
+      controller.get('hosts').forEach(function (host, index) {
+        host.get('checkboxes').setEach('checked', index === 0);
+      });
+      expect(controller.validateEachHost('')).to.equal(false);
+    });
+    it('All checked', function () {
+      controller.get('hosts').forEach(function (host) {
+        host.get('checkboxes').setEach('checked', true);
+      });
+      expect(controller.validateEachHost('')).to.equal(true);
+    });
+  });
+
+  describe('#clearStep', function () {
+    beforeEach(function () {
+      sinon.stub(controller, 'clearError', Em.K);
+    });
+    afterEach(function () {
+      controller.clearError.restore();
+    });
+    it('should call clearError', function () {
+      controller.clearStep();
+      expect(controller.clearError.calledOnce).to.equal(true);
+    });
+    it('should clear hosts', function () {
+      controller.set('hosts', [
+        {},
+        {}
+      ]);
+      controller.clearStep();
+      expect(controller.get('hosts')).to.eql([]);
+    });
+    it('should clear headers', function () {
+      controller.set('headers', [
+        {},
+        {}
+      ]);
+      controller.clearStep();
+      expect(controller.get('headers')).to.eql([]);
+    });
+    it('should set isLoaded to false', function () {
+      controller.set('isLoaded', true);
+      controller.clearStep();
+      expect(controller.get('isLoaded')).to.equal(false);
+    });
+  });
+
+  describe('#selectAllNodes', function () {
+    beforeEach(function () {
+      sinon.stub(controller, 'setAllNodes', Em.K);
+    });
+    afterEach(function () {
+      controller.setAllNodes.restore();
+    });
+    it('should call setAllNodes', function () {
+      controller.selectAllNodes({context: {name: 'name'}});
+      expect(controller.setAllNodes.calledWith('name', true)).to.equal(true);
+    });
+    it('shouldn\'t call setAllNodes', function () {
+      controller.selectAllNodes();
+      expect(controller.setAllNodes.called).to.equal(false);
+    });
+  });
+
+  describe('#deselectAllNodes', function () {
+    beforeEach(function () {
+      sinon.stub(controller, 'setAllNodes', Em.K);
+    });
+    afterEach(function () {
+      controller.setAllNodes.restore();
+    });
+    it('should call setAllNodes', function () {
+      controller.deselectAllNodes({context: {name: 'name'}});
+      expect(controller.setAllNodes.calledWith('name', false)).to.equal(true);
+    });
+    it('shouldn\'t call setAllNodes', function () {
+      controller.deselectAllNodes();
+      expect(controller.setAllNodes.called).to.equal(false);
+    });
+  });
+
+  describe('#checkCallback', function () {
+    beforeEach(function () {
+      sinon.stub(controller, 'clearError', Em.K);
+    });
+    afterEach(function () {
+      controller.clearError.restore();
+    });
+    it('should call clearError', function () {
+      controller.checkCallback('');
+      expect(controller.clearError.calledOnce).to.equal(true);
+    });
+    Em.A([
+        {
+          m: 'all checked, isInstalled false',
+          headers: Em.A([
+            Em.Object.create({name: 'c1'})
+          ]),
+          hosts: Em.A([
+            Em.Object.create({
+              checkboxes: Em.A([
+                Em.Object.create({
+                  component: 'c1',
+                  isInstalled: false,
+                  checked: true
+                })
+              ])
+            })
+          ]),
+          component: 'c1',
+          e: {
+            allChecked: true,
+            noChecked: false
+          }
+        },
+        {
+          m: 'all checked, isInstalled true',
+          headers: Em.A([
+            Em.Object.create({name: 'c1'})
+          ]),
+          hosts: Em.A([
+            Em.Object.create({
+              checkboxes: Em.A([
+                Em.Object.create({
+                  component: 'c1',
+                  isInstalled: true,
+                  checked: true
+                })
+              ])
+            })
+          ]),
+          component: 'c1',
+          e: {
+            allChecked: true,
+            noChecked: true
+          }
+        },
+        {
+          m: 'no one checked',
+          headers: Em.A([
+            Em.Object.create({name: 'c1'})
+          ]),
+          hosts: Em.A([
+            Em.Object.create({
+              checkboxes: Em.A([
+                Em.Object.create({
+                  component: 'c1',
+                  isInstalled: false,
+                  checked: false
+                })
+              ])
+            })
+          ]),
+          component: 'c1',
+          e: {
+            allChecked: false,
+            noChecked: true
+          }
+        },
+        {
+          m: 'some checked',
+          headers: Em.A([
+            Em.Object.create({name: 'c1'})
+          ]),
+          hosts: Em.A([
+            Em.Object.create({
+              checkboxes: Em.A([
+                Em.Object.create({
+                  component: 'c1',
+                  isInstalled: false,
+                  checked: true
+                }),
+                Em.Object.create({
+                  component: 'c1',
+                  isInstalled: false,
+                  checked: false
+                })
+              ])
+            })
+          ]),
+          component: 'c1',
+          e: {
+            allChecked: false,
+            noChecked: false
+          }
+        },
+        {
+          m: 'some checked, some isInstalled true',
+          headers: Em.A([
+            Em.Object.create({name: 'c1'})
+          ]),
+          hosts: Em.A([
+            Em.Object.create({
+              checkboxes: Em.A([
+                Em.Object.create({
+                  component: 'c1',
+                  isInstalled: true,
+                  checked: true
+                }),
+                Em.Object.create({
+                  component: 'c1',
+                  isInstalled: true,
+                  checked: true
+                })
+              ])
+            })
+          ]),
+          component: 'c1',
+          e: {
+            allChecked: true,
+            noChecked: true
+          }
+        },
+        {
+          m: 'some checked, some isInstalled true (2)',
+          headers: Em.A([
+            Em.Object.create({name: 'c1'})
+          ]),
+          hosts: Em.A([
+            Em.Object.create({
+              checkboxes: Em.A([
+                Em.Object.create({
+                  component: 'c1',
+                  isInstalled: false,
+                  checked: false
+                }),
+                Em.Object.create({
+                  component: 'c1',
+                  isInstalled: true,
+                  checked: true
+                })
+              ])
+            })
+          ]),
+          component: 'c1',
+          e: {
+            allChecked: false,
+            noChecked: true
+          }
+        }
+      ]).forEach(function (test) {
+        it(test.m, function () {
+          controller.clearStep();
+          controller.set('headers', test.headers);
+          controller.set('hosts', test.hosts);
+          controller.checkCallback(test.component);
+          var header = controller.get('headers').findProperty('name', test.component);
+          expect(header.get('allChecked')).to.equal(test.e.allChecked);
+          expect(header.get('noChecked')).to.equal(test.e.noChecked);
+        });
+      });
+  });
+
+  describe('#getHostNames', function () {
+    var tests = Em.A([
+      {
+        hosts: {
+          h1: {bootStatus: 'REGISTERED', name: 'h1'},
+          h2: {bootStatus: 'REGISTERED', name: 'h2'},
+          h3: {bootStatus: 'REGISTERED', name: 'h3'}
+        },
+        m: 'All REGISTERED',
+        e: ['h1', 'h2', 'h3']
+      },
+      {
+        hosts: {
+          h1: {bootStatus: 'REGISTERED', name: 'h1'},
+          h2: {bootStatus: 'FAILED', name: 'h2'},
+          h3: {bootStatus: 'REGISTERED', name: 'h3'}
+        },
+        m: 'Some REGISTERED',
+        e: ['h1', 'h3']
+      },
+      {
+        hosts: {
+          h1: {bootStatus: 'FAILED', name: 'h1'},
+          h2: {bootStatus: 'FAILED', name: 'h2'},
+          h3: {bootStatus: 'FAILED', name: 'h3'}
+        },
+        m: 'No one REGISTERED',
+        e: []
+      },
+      {
+        hosts: {},
+        m: 'Empty hosts',
+        e: []
+      }
+    ]);
+    tests.forEach(function (test) {
+      it(test.m, function () {
+        controller.set('content.hosts', test.hosts);
+        var r = controller.getHostNames();
+        expect(r).to.eql(test.e);
+      });
+    });
+  });
+
+  describe('#validate', function () {
+    var tests = Em.A([
+      {
+        controllerName: 'addHostController',
+        method: 'validateEachHost',
+        r: true,
+        e: true
+      },
+      {
+        controllerName: 'addHostController',
+        method: 'validateEachHost',
+        r: false,
+        e: false
+      },
+      {
+        controllerName: 'addServiceController',
+        method: 'validateEachComponent',
+        r: true,
+        e: true
+      },
+      {
+        controllerName: 'addServiceController',
+        method: 'validateEachComponent',
+        r: false,
+        e: false
+      },
+      {
+        controllerName: 'installerController',
+        method: 'validateEachComponent',
+        r: true,
+        e: true
+      },
+      {
+        controllerName: 'installerController',
+        method: 'validateEachComponent',
+        r: false,
+        e: false
+      }
+    ]);
+    tests.forEach(function (test) {
+      it(test.controllerName + ' ' + test.method + ' returns ' + test.r.toString(), function () {
+        sinon.stub(controller, test.method, function () {
+          return test.r
+        });
+        controller.set('content.controllerName', test.controllerName);
+        expect(controller.validate()).to.equal(test.e);
+        controller[test.method].restore();
+      });
+    });
+  });
+
+  describe('#getMasterComponentsForHost', function () {
+    var tests = Em.A([
+      {
+        masterComponentHosts: Em.A([
+          {hostName: 'h1', component: 'c1'}
+        ]),
+        hostName: 'h1',
+        m: 'host exists',
+        e: ['c1']
+      },
+      {
+        masterComponentHosts: Em.A([
+          {hostName: 'h1', component: 'c1'}
+        ]),
+        hostName: 'h2',
+        m: 'host donesn\'t exists',
+        e: []
+      }
+    ]);
+    tests.forEach(function (test) {
+      it(test.m, function () {
+        controller.set('content.masterComponentHosts', test.masterComponentHosts);
+        var r = controller.getMasterComponentsForHost(test.hostName);
+        expect(r).to.eql(test.e);
+      });
+    });
+  });
+
+  describe('#selectMasterComponents', function () {
+    var tests = Em.A([
+      {
+        masterComponentHosts: Em.A([
+          {
+            hostName: 'h1',
+            component: 'c1'
+          }
+        ]),
+        hostsObj: [
+          Em.Object.create({
+            hostName: 'h1',
+            checkboxes: [
+              Em.Object.create({
+                component: 'c1',
+                checked: false
+              })
+            ]
+          })
+        ],
+        e: true,
+        m: 'host and component exist'
+      },
+      {
+        masterComponentHosts: Em.A([
+          {
+            hostName: 'h1',
+            component: 'c2'
+          }
+        ]),
+        hostsObj: [
+          Em.Object.create({
+            hostName: 'h1',
+            checkboxes: [
+              Em.Object.create({
+                component: 'c1',
+                checked: false
+              })
+            ]
+          })
+        ],
+        e: false,
+        m: 'host exists'
+      },
+      {
+        masterComponentHosts: Em.A([
+          {
+            hostName: 'h2',
+            component: 'c2'
+          }
+        ]),
+        hostsObj: [
+          Em.Object.create({
+            hostName: 'h1',
+            checkboxes: [
+              Em.Object.create({
+                component: 'c1',
+                checked: false
+              })
+            ]
+          })
+        ],
+        e: false,
+        m: 'host and component don\'t exist'
+      }
+    ]);
+    tests.forEach(function (test) {
+      it(test.m, function () {
+        controller.set('content.masterComponentHosts', test.masterComponentHosts);
+        var r = controller.selectMasterComponents(test.hostsObj);
+        expect(r.findProperty('hostName', 'h1').get('checkboxes').findProperty('component', 'c1').get('checked')).to.equal(test.e);
+      });
+    });
+  });
+
+  describe('#render', function () {
+    beforeEach(function () {
+      sinon.stub(controller, 'selectMasterComponents', Em.K);
+      sinon.stub(controller, 'renderSlaves', Em.K);
+    });
+    afterEach(function () {
+      controller.selectMasterComponents.restore();
+      controller.renderSlaves.restore();
+    });
+    it('should call selectMasterComponents if isMasters is true', function () {
+      controller.set('isMasters', true);
+      controller.render();
+      expect(controller.selectMasterComponents.calledOnce).to.equal(true);
+      expect(controller.renderSlaves.called).to.equal(false);
+    });
+    it('should call renderSlaves if isMasters is false', function () {
+      controller.set('isMasters', false);
+      controller.render();
+      expect(controller.selectMasterComponents.called).to.equal(false);
+      expect(controller.renderSlaves.calledOnce).to.equal(true);
+    });
+    it('should set isLoaded to true', function () {
+      controller.set('isLoaded', false);
+      controller.render();
+      expect(controller.get('isLoaded')).to.equal(true);
+    });
+  });
+
+  describe('#renderSlaves', function () {
+    Em.A([
+        {
+          controllerName: 'addServiceController',
+          slaveComponents: [],
+          hostsObj: [
+            Em.Object.create({
+              checkboxes: Em.A([
+                Em.Object.create({isInstalled: false, title: 'Client'}),
+                Em.Object.create({isInstalled: false, title: ''}),
+                Em.Object.create({isInstalled: false, title: ''})
+              ]),
+              hasMaster: true
+            })
+          ],
+          m: 'host with masters, empty slaveComponents, controllerName - addServiceController',
+          e: [
+            [false, false, false]
+          ]
+        },
+        {
+          controllerName: 'addServiceController',
+          slaveComponents: [],
+          hostsObj: [
+            Em.Object.create({
+              checkboxes: Em.A([
+                Em.Object.create({isInstalled: false, title: 'Client'}),
+                Em.Object.create({isInstalled: false, title: ''}),
+                Em.Object.create({isInstalled: false, title: ''})
+              ]),
+              hasMaster: false
+            })
+          ],
+          m: 'host without masters, empty slaveComponents, controllerName - addServiceController',
+          e: [
+            [false, true, true]
+          ]
+        },
+        {
+          controllerName: 'addServiceController',
+          slaveComponents: [],
+          services: [
+            Em.Object.create({serviceName: 'HDFS', isSelected: true})
+          ],
+          hostsObj: [
+            Em.Object.create({
+              checkboxes: Em.A([
+                Em.Object.create({isInstalled: false, title: 'Client'}),
+                Em.Object.create({isInstalled: false, title: 'DataNode', checked: true}),
+                Em.Object.create({isInstalled: false, title: ''})
+              ]),
+              hasMaster: false
+            })
+          ],
+          m: 'host without masters, empty slaveComponents, controllerName - addServiceController, one datanode checked',
+          e: [
+            [true, true, true]
+          ]
+        },
+        {
+          controllerName: 'addServiceController',
+          slaveComponents: [],
+          services: [
+            Em.Object.create({serviceName: 'HDFS', isSelected: true})
+          ],
+          hostsObj: [
+            Em.Object.create({
+              checkboxes: Em.A([
+                Em.Object.create({isInstalled: false, title: 'Client'}),
+                Em.Object.create({isInstalled: false, title: 'DataNode', checked: false}),
+                Em.Object.create({isInstalled: false, title: ''})
+              ]),
+              hasMaster: true
+            })
+          ],
+          m: 'host with masters, empty slaveComponents, controllerName - addServiceController, one datanode not checked',
+          e: [
+            [false, false, false]
+          ]
+        },
+        {
+          controllerName: 'installerController',
+          slaveComponents: [],
+          services: [
+            Em.Object.create({serviceName: 'HDFS', isSelected: true})
+          ],
+          hostsObj: [
+            Em.Object.create({
+              checkboxes: Em.A([
+                Em.Object.create({isInstalled: false, title: 'Client'}),
+                Em.Object.create({isInstalled: false, title: 'DataNode', checked: true}),
+                Em.Object.create({isInstalled: false, title: ''})
+              ]),
+              hasMaster: true
+            })
+          ],
+          m: 'host with masters, empty slaveComponents, controllerName - installerController, one datanode checked',
+          e: [
+            [true, true, true]
+          ]
+        },
+        {
+          controllerName: 'installerController',
+          slaveComponents: [],
+          services: [
+            Em.Object.create({serviceName: 'HDFS', isSelected: true})
+          ],
+          hostsObj: [
+            Em.Object.create({
+              checkboxes: Em.A([
+                Em.Object.create({isInstalled: false, title: 'Client'}),
+                Em.Object.create({isInstalled: false, title: 'DataNode', checked: false}),
+                Em.Object.create({isInstalled: false, title: ''})
+              ]),
+              hasMaster: true
+            }),
+            Em.Object.create({
+              checkboxes: Em.A([
+                Em.Object.create({isInstalled: false, title: 'Client'}),
+                Em.Object.create({isInstalled: false, title: 'DataNode', checked: true}),
+                Em.Object.create({isInstalled: false, title: ''})
+              ]),
+              hasMaster: true
+            })
+          ],
+          m: 'hosts with masters, empty slaveComponents, controllerName - installerController, one datanode checked',
+          e: [
+            [false, false, false],
+            [true, true, true]
+          ]
+        },
+        {
+          controllerName: 'installerController',
+          slaveComponents: [],
+          services: [
+            Em.Object.create({serviceName: 'HDFS', isSelected: true})
+          ],
+          hostsObj: [
+            Em.Object.create({
+              checkboxes: Em.A([
+                Em.Object.create({isInstalled: false, title: 'Client'}),
+                Em.Object.create({isInstalled: false, title: 'DataNode', checked: false}),
+                Em.Object.create({isInstalled: false, title: ''})
+              ]),
+              hasMaster: true
+            }),
+            Em.Object.create({
+              checkboxes: Em.A([
+                Em.Object.create({isInstalled: false, title: 'Client'}),
+                Em.Object.create({isInstalled: false, title: 'DataNode', checked: true}),
+                Em.Object.create({isInstalled: false, title: ''})
+              ]),
+              hasMaster: false
+            })
+          ],
+          m: 'some hosts with masters, empty slaveComponents, controllerName - installerController, one datanode checked',
+          e: [
+            [false, false, false],
+            [true, true, true]
+          ]
+        }
+      ]).forEach(function (test) {
+        it(test.m, function () {
+          controller.set('content.slaveComponents', test.slaveComponents);
+          controller.set('content.controllerName', test.controllerName);
+          if (test.services) {
+            controller.set('content.services', test.services);
+          }
+          controller.set('isMasters', false);
+          controller.loadStep();
+          var r = controller.renderSlaves(test.hostsObj);
+          expect(r.map(function (i) {
+            return i.get('checkboxes').map(function (j) {
+              return j.get('checked');
+            });
+          })).to.eql(test.e);
+        });
+      });
+
+    Em.A([
+        {
+          slaveComponents: [
+            {componentName: 'c1', hosts: [
+              {hostName: 'h1', isInstalled: false},
+              {hostName: 'h2', isInstalled: false}
+            ]},
+            {componentName: 'c2', hosts: [
+              {hostName: 'h1', isInstalled: false},
+              {hostName: 'h2', isInstalled: false}
+            ]}
+          ],
+          headers: [
+            Em.Object.create({name: 'c1', label: 'C1'}),
+            Em.Object.create({name: 'c2', label: 'C2'})
+          ],
+          hostsObj: [
+            Em.Object.create({
+              hostName: 'h1',
+              checkboxes: [
+                Em.Object.create({
+                  title: 'C1',
+                  checked: false,
+                  isInstalled: false
+                }),
+                Em.Object.create({
+                  title: 'C2',
+                  checked: false,
+                  isInstalled: false
+                })
+              ]
+            }),
+            Em.Object.create({
+              hostName: 'h2',
+              checkboxes: [
+                Em.Object.create({
+                  title: 'C1',
+                  checked: false,
+                  isInstalled: false
+                }),
+                Em.Object.create({
+                  title: 'C2',
+                  checked: false,
+                  isInstalled: false
+                })
+              ]
+            })
+          ],
+          m: 'all Checked, nothing installed before',
+          e: {
+            checked: [
+              [true, true],
+              [true, true]
+            ],
+            isInstalled: [
+              [false, false],
+              [false, false]
+            ]
+          }
+        },
+        {
+          slaveComponents: [
+            {componentName: 'c1', hosts: [
+              {hostName: 'h1', isInstalled: true},
+              {hostName: 'h2', isInstalled: true}
+            ]},
+            {componentName: 'c2', hosts: [
+              {hostName: 'h1', isInstalled: true},
+              {hostName: 'h2', isInstalled: true}
+            ]}
+          ],
+          headers: [
+            Em.Object.create({name: 'c1', label: 'C1'}),
+            Em.Object.create({name: 'c2', label: 'C2'})
+          ],
+          hostsObj: [
+            Em.Object.create({
+              hostName: 'h1',
+              checkboxes: [
+                Em.Object.create({
+                  title: 'C1',
+                  checked: false,
+                  isInstalled: false
+                }),
+                Em.Object.create({
+                  title: 'C2',
+                  checked: false,
+                  isInstalled: false
+                })
+              ]
+            }),
+            Em.Object.create({
+              hostName: 'h2',
+              checkboxes: [
+                Em.Object.create({
+                  title: 'C1',
+                  checked: false,
+                  isInstalled: false
+                }),
+                Em.Object.create({
+                  title: 'C2',
+                  checked: false,
+                  isInstalled: false
+                })
+              ]
+            })
+          ],
+          m: 'all Checked, all installed before',
+          e: {
+            checked: [
+              [true, true],
+              [true, true]
+            ],
+            isInstalled: [
+              [true, true],
+              [true, true]
+            ]
+          }
+        },
+        {
+          slaveComponents: [
+            {componentName: 'c1', hosts: [
+              {hostName: 'h1', isInstalled: true}
+            ]},
+            {componentName: 'c2', hosts: [
+              {hostName: 'h2', isInstalled: true}
+            ]}
+          ],
+          headers: [
+            Em.Object.create({name: 'c1', label: 'C1'}),
+            Em.Object.create({name: 'c2', label: 'C2'})
+          ],
+          hostsObj: [
+            Em.Object.create({
+              hostName: 'h1',
+              checkboxes: [
+                Em.Object.create({
+                  title: 'C1',
+                  checked: false,
+                  isInstalled: false
+                }),
+                Em.Object.create({
+                  title: 'C2',
+                  checked: false,
+                  isInstalled: false
+                })
+              ]
+            }),
+            Em.Object.create({
+              hostName: 'h2',
+              checkboxes: [
+                Em.Object.create({
+                  title: 'C1',
+                  checked: false,
+                  isInstalled: false
+                }),
+                Em.Object.create({
+                  title: 'C2',
+                  checked: false,
+                  isInstalled: false
+                })
+              ]
+            })
+          ],
+          m: 'some Checked, some installed before',
+          e: {
+            checked: [
+              [true, false],
+              [false, true]
+            ],
+            isInstalled: [
+              [true, false],
+              [false, true]
+            ]
+          }
+        }
+      ]).forEach(function (test) {
+        it(test.m, function () {
+          controller.set('content.slaveComponentHosts', test.slaveComponents);
+          controller.set('headers', test.headers);
+          var r = controller.renderSlaves(test.hostsObj);
+          var checked = r.map(function (i) {
+            return i.get('checkboxes').map(function (j) {
+              return j.get('checked')
+            })
+          });
+          var isInstalled = r.map(function (i) {
+            return i.get('checkboxes').map(function (j) {
+              return j.get('isInstalled')
+            })
+          });
+          expect(checked).to.eql(test.e.checked);
+          expect(isInstalled).to.eql(test.e.isInstalled);
+        });
+      });
+  });
+
+});
\ No newline at end of file