Repository: ambari Updated Branches: refs/heads/trunk 4a4a16aa9 -> 8f16d6438
AMBARI-19361 Cover JournalNode HA wizard with unit tests. (atkach) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/8f16d643 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/8f16d643 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/8f16d643 Branch: refs/heads/trunk Commit: 8f16d643867772ba491f85477ee03454e7177b62 Parents: 4a4a16a Author: Andrii Tkach <[email protected]> Authored: Wed Jan 4 17:27:10 2017 +0200 Committer: Andrii Tkach <[email protected]> Committed: Wed Jan 4 17:27:10 2017 +0200 ---------------------------------------------------------------------- ambari-web/app/assets/test/tests.js | 8 + .../journalNode/progress_controller.js | 3 +- .../journalNode/step1_controller.js | 25 +- .../journalNode/step2_controller.js | 15 +- .../journalNode/step4_controller.js | 17 +- .../journalNode/step6_controller.js | 4 +- .../journalNode/step7_controller.js | 2 +- .../journalNode/wizard_controller.js | 44 +- .../global/background_operations_test.js | 9 - .../journalNode/progress_controller_test.js | 67 +++ .../journalNode/step1_controller_test.js | 245 +++++++++++ .../journalNode/step2_controller_test.js | 281 +++++++++++++ .../journalNode/step4_controller_test.js | 220 ++++++++++ .../journalNode/step6_controller_test.js | 74 ++++ .../journalNode/step7_controller_test.js | 46 +++ .../journalNode/step8_controller_test.js | 61 +++ .../journalNode/wizard_controller_test.js | 404 +++++++++++++++++++ 17 files changed, 1463 insertions(+), 62 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/8f16d643/ambari-web/app/assets/test/tests.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/assets/test/tests.js b/ambari-web/app/assets/test/tests.js index 4263016..604d96b 100644 --- a/ambari-web/app/assets/test/tests.js +++ b/ambari-web/app/assets/test/tests.js @@ -81,6 +81,14 @@ var files = [ 'test/controllers/main/admin/highAvailability/hawq/addStandby/step3_controller_test', 'test/controllers/main/admin/highAvailability/hawq/removeStandby/step2_controller_test', 'test/controllers/main/admin/highAvailability/hawq/activateStandby/step2_controller_test', + 'test/controllers/main/admin/highAvailability/journalNode/progress_controller_test', + 'test/controllers/main/admin/highAvailability/journalNode/step1_controller_test', + 'test/controllers/main/admin/highAvailability/journalNode/step2_controller_test', + 'test/controllers/main/admin/highAvailability/journalNode/step4_controller_test', + 'test/controllers/main/admin/highAvailability/journalNode/step6_controller_test', + 'test/controllers/main/admin/highAvailability/journalNode/step7_controller_test', + 'test/controllers/main/admin/highAvailability/journalNode/step8_controller_test', + 'test/controllers/main/admin/highAvailability/journalNode/wizard_controller_test', 'test/controllers/main/dashboard/config_history_controller_test', 'test/controllers/main/charts/heatmap_test', 'test/controllers/main/charts/heatmap_metrics/heatmap_metric_test', http://git-wip-us.apache.org/repos/asf/ambari/blob/8f16d643/ambari-web/app/controllers/main/admin/highAvailability/journalNode/progress_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/main/admin/highAvailability/journalNode/progress_controller.js b/ambari-web/app/controllers/main/admin/highAvailability/journalNode/progress_controller.js index 436a8bd..2959d67 100644 --- a/ambari-web/app/controllers/main/admin/highAvailability/journalNode/progress_controller.js +++ b/ambari-web/app/controllers/main/admin/highAvailability/journalNode/progress_controller.js @@ -32,7 +32,8 @@ App.ManageJournalNodeProgressPageController = App.ManageJournalNodeWizardControl * @param note String */ reconfigureSites: function(siteNames, data, note) { - var tagName = App.get('testMode') ? 'version1' : 'version' + (new Date).getTime(); + var tagName = 'version' + App.dateTime(); + return siteNames.map(function(_siteName) { var config = data.items.findProperty('type', _siteName); var configToSave = { http://git-wip-us.apache.org/repos/asf/ambari/blob/8f16d643/ambari-web/app/controllers/main/admin/highAvailability/journalNode/step1_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/main/admin/highAvailability/journalNode/step1_controller.js b/ambari-web/app/controllers/main/admin/highAvailability/journalNode/step1_controller.js index e1252b7..b54986b 100644 --- a/ambari-web/app/controllers/main/admin/highAvailability/journalNode/step1_controller.js +++ b/ambari-web/app/controllers/main/admin/highAvailability/journalNode/step1_controller.js @@ -22,7 +22,7 @@ require('controllers/wizard/step5_controller'); App.ManageJournalNodeWizardStep1Controller = Em.Controller.extend(App.BlueprintMixin, App.AssignMasterComponents, { - name:"manageJournalNodeWizardStep1Controller", + name: "manageJournalNodeWizardStep1Controller", useServerValidation: false, @@ -38,7 +38,7 @@ App.ManageJournalNodeWizardStep1Controller = Em.Controller.extend(App.BlueprintM * On initial rendering, load equivalent number of existing JournalNodes to masterToShow * @param masterComponents */ - renderComponents: function(masterComponents) { + renderComponents: function (masterComponents) { //check if we are restoring components assignment by checking existing of JOURNALNODE component in array var restoringComponents = masterComponents.someProperty('component_name', 'JOURNALNODE'); masterComponents = restoringComponents ? masterComponents : masterComponents.concat(this.generateJournalNodeComponents()); @@ -54,7 +54,10 @@ App.ManageJournalNodeWizardStep1Controller = Em.Controller.extend(App.BlueprintM generateJournalNodeComponents: function () { var journalNodes = []; App.HostComponent.find().filterProperty('componentName', 'JOURNALNODE').forEach(function (jn) { - var jnComponent = this.createComponentInstallationObject(Em.Object.create({serviceName: jn.get('service.serviceName'), componentName: jn.get('componentName')}), jn.get('hostName')); + var jnComponent = this.createComponentInstallationObject(Em.Object.create({ + serviceName: jn.get('service.serviceName'), + componentName: jn.get('componentName') + }), jn.get('hostName')); jnComponent.isInstalled = true; journalNodes.push(jnComponent); }, this); @@ -64,13 +67,13 @@ App.ManageJournalNodeWizardStep1Controller = Em.Controller.extend(App.BlueprintM /** * Enable/Disable show/hide operation for each JournalNode */ - showHideJournalNodesAddRemoveControl: function() { + showHideJournalNodesAddRemoveControl: function () { var masterComponents = this.get('selectedServicesMasters'); var jns = masterComponents.filterProperty('component_name', 'JOURNALNODE'); - var maxNumMasters = this.getMaxNumberOfMasters('JOURNALNODE') + var maxNumMasters = this.getMaxNumberOfMasters('JOURNALNODE'); var showRemoveControl = jns.get('length') > this.get('JOURNALNODES_COUNT_MINIMUM'); var showAddControl = jns.get('length') < maxNumMasters; - jns.forEach(function(item) { + jns.forEach(function (item) { item.set('showAddControl', false); item.set('showRemoveControl', showRemoveControl); }); @@ -80,10 +83,10 @@ App.ManageJournalNodeWizardStep1Controller = Em.Controller.extend(App.BlueprintM /** * Mark existing JournalNodes 'isInstalled' and 'showCurrentPrefix' */ - updateJournalNodeInfo: function() { + updateJournalNodeInfo: function () { var jns = this.get('selectedServicesMasters').filterProperty('component_name', 'JOURNALNODE'); var hosts = App.HostComponent.find().filterProperty('componentName', 'JOURNALNODE').mapProperty('hostName'); - hosts.forEach(function(host) { + hosts.forEach(function (host) { var jn = jns.findProperty('selectedHost', host); if (jn) { jn.set('isInstalled', true); @@ -96,7 +99,7 @@ App.ManageJournalNodeWizardStep1Controller = Em.Controller.extend(App.BlueprintM * Callback after load controller data (hosts, host components etc) * @method loadStepCallback */ - loadStepCallback: function(components, self) { + loadStepCallback: function (components, self) { self.renderComponents(components); self.get('addableComponents').forEach(function (componentName) { @@ -108,10 +111,10 @@ App.ManageJournalNodeWizardStep1Controller = Em.Controller.extend(App.BlueprintM /** * Next button is disabled when there is any change to the original JournalNode hosts */ - nextButtonDisabled: function() { + nextButtonDisabled: function () { var currentHosts = this.get('selectedServicesMasters').filterProperty('component_name', 'JOURNALNODE').mapProperty('selectedHost'); var originalHosts = App.HostComponent.find().filterProperty('componentName', 'JOURNALNODE').mapProperty('hostName'); - return currentHosts.sort().join() == originalHosts.sort().join(); + return currentHosts.sort().join() === originalHosts.sort().join(); }.property('hostNameCheckTrigger', 'nextButtonCheckTrigger') }); http://git-wip-us.apache.org/repos/asf/ambari/blob/8f16d643/ambari-web/app/controllers/main/admin/highAvailability/journalNode/step2_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/main/admin/highAvailability/journalNode/step2_controller.js b/ambari-web/app/controllers/main/admin/highAvailability/journalNode/step2_controller.js index d1cb198..108c97a 100644 --- a/ambari-web/app/controllers/main/admin/highAvailability/journalNode/step2_controller.js +++ b/ambari-web/app/controllers/main/admin/highAvailability/journalNode/step2_controller.js @@ -41,6 +41,8 @@ App.ManageJournalNodeWizardStep2Controller = Em.Controller.extend({ versionLoaded: true, hideDependenciesInfoBar: true, + isNextDisabled: Em.computed.not('isLoaded'), + clearStep: function () { this.get('stepConfigs').clear(); this.set('serverConfigData', {}); @@ -65,7 +67,7 @@ App.ManageJournalNodeWizardStep2Controller = Em.Controller.extend({ var urlParams = []; var hdfsSiteTag = data.Clusters.desired_configs['hdfs-site'].tag; urlParams.push('(type=hdfs-site&tag=' + hdfsSiteTag + ')'); - this.set("hdfsSiteTag", {name : "hdfsSiteTag", value : hdfsSiteTag}); + this.set("hdfsSiteTag", {name: "hdfsSiteTag", value: hdfsSiteTag}); App.ajax.send({ name: 'admin.get.all_configurations', @@ -79,7 +81,7 @@ App.ManageJournalNodeWizardStep2Controller = Em.Controller.extend({ }, onLoadConfigs: function (data) { - this.set('serverConfigData',data); + this.set('serverConfigData', data); this.set('content.nameServiceId', data.items[0].properties['dfs.nameservices']); this.tweakServiceConfigs(this.get('moveJNConfig.configs')); this.renderServiceConfigs(this.get('moveJNConfig')); @@ -111,7 +113,7 @@ App.ManageJournalNodeWizardStep2Controller = Em.Controller.extend({ return localDB; }, - tweakServiceConfigs: function(configs) { + tweakServiceConfigs: function (configs) { var localDB = this._prepareLocalDB(); var dependencies = this._prepareDependencies(); @@ -142,7 +144,7 @@ App.ManageJournalNodeWizardStep2Controller = Em.Controller.extend({ this.get('stepConfigs').pushObject(serviceConfig); this.set('selectedService', this.get('stepConfigs').objectAt(0)); - this.once = true; + this.set('once', true); }, /** @@ -156,8 +158,5 @@ App.ManageJournalNodeWizardStep2Controller = Em.Controller.extend({ componentConfig.configs.pushObject(serviceConfigProperty); serviceConfigProperty.set('isEditable', serviceConfigProperty.get('isReconfigurable')); }, this); - }, - - isNextDisabled: Em.computed.not('isLoaded') - + } }); http://git-wip-us.apache.org/repos/asf/ambari/blob/8f16d643/ambari-web/app/controllers/main/admin/highAvailability/journalNode/step4_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/main/admin/highAvailability/journalNode/step4_controller.js b/ambari-web/app/controllers/main/admin/highAvailability/journalNode/step4_controller.js index 1938527..5bcf78a 100644 --- a/ambari-web/app/controllers/main/admin/highAvailability/journalNode/step4_controller.js +++ b/ambari-web/app/controllers/main/admin/highAvailability/journalNode/step4_controller.js @@ -25,12 +25,12 @@ App.ManageJournalNodeWizardStep4Controller = App.ManageJournalNodeProgressPageCo commands: ['stopStandbyNameNode', 'stopServices', 'installJournalNodes', 'deleteJournalNodes', 'startJournalNodes', 'reconfigureHDFS'], - hdfsSiteTag : "", + hdfsSiteTag: "", - stopStandbyNameNode: function() { + stopStandbyNameNode: function () { // save who's active and who's standby at this point in time - var sbNN = this.get('content.standByNN'); - this.updateComponent('NAMENODE', sbNN.host_name, 'HDFS', 'INSTALLED'); + var hostName = this.get('content.standByNN.host_name'); + this.updateComponent('NAMENODE', hostName, 'HDFS', 'INSTALLED'); }, installJournalNodes: function () { @@ -45,7 +45,7 @@ App.ManageJournalNodeWizardStep4Controller = App.ManageJournalNodeProgressPageCo deleteJournalNodes: function () { var hosts = App.router.get('manageJournalNodeWizardController').getJournalNodesToDelete(); if (hosts && hosts.length > 0) { - hosts.forEach(function(host) { + hosts.forEach(function (host) { this.deleteComponent('JOURNALNODE', host); }, this); } else { @@ -59,15 +59,14 @@ App.ManageJournalNodeWizardStep4Controller = App.ManageJournalNodeProgressPageCo }, reconfigureHDFS: function () { - var data = this.get('content.serviceConfigProperties'); - this.updateConfigProperties(data); + this.updateConfigProperties(this.get('content.serviceConfigProperties')); }, /** * Update service configurations * @param {Object} data - config object to update */ - updateConfigProperties: function(data) { + updateConfigProperties: function (data) { var siteNames = ['hdfs-site']; var configData = this.reconfigureSites(siteNames, data, Em.I18n.t('admin.manageJournalNode.step4.save.configuration.note').format(App.format.role('NAMENODE', false))); App.ajax.send({ @@ -77,7 +76,7 @@ App.ManageJournalNodeWizardStep4Controller = App.ManageJournalNodeProgressPageCo desired_config: configData }, success: 'installHDFSClients', - error: 'onTaskError', + error: 'onTaskError' }); }, http://git-wip-us.apache.org/repos/asf/ambari/blob/8f16d643/ambari-web/app/controllers/main/admin/highAvailability/journalNode/step6_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/main/admin/highAvailability/journalNode/step6_controller.js b/ambari-web/app/controllers/main/admin/highAvailability/journalNode/step6_controller.js index 262fe93..288d1c6 100644 --- a/ambari-web/app/controllers/main/admin/highAvailability/journalNode/step6_controller.js +++ b/ambari-web/app/controllers/main/admin/highAvailability/journalNode/step6_controller.js @@ -31,7 +31,7 @@ App.ManageJournalNodeWizardStep6Controller = App.ManageJournalNodeProgressPageCo }, startActiveNameNode: function () { - var activeNN = this.get('content.activeNN'); - this.updateComponent('NAMENODE', activeNN.host_name, "HDFS", "Start"); + var hostName = this.get('content.activeNN.host_name'); + this.updateComponent('NAMENODE', hostName, "HDFS", "Start"); } }); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/8f16d643/ambari-web/app/controllers/main/admin/highAvailability/journalNode/step7_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/main/admin/highAvailability/journalNode/step7_controller.js b/ambari-web/app/controllers/main/admin/highAvailability/journalNode/step7_controller.js index add2070..0467ce9 100644 --- a/ambari-web/app/controllers/main/admin/highAvailability/journalNode/step7_controller.js +++ b/ambari-web/app/controllers/main/admin/highAvailability/journalNode/step7_controller.js @@ -20,7 +20,7 @@ var App = require('app'); App.ManageJournalNodeWizardStep7Controller = Em.Controller.extend({ - name:"manageJournalNodeWizardStep7Controller", + name: "manageJournalNodeWizardStep7Controller", done: function () { App.router.send("next"); http://git-wip-us.apache.org/repos/asf/ambari/blob/8f16d643/ambari-web/app/controllers/main/admin/highAvailability/journalNode/wizard_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/main/admin/highAvailability/journalNode/wizard_controller.js b/ambari-web/app/controllers/main/admin/highAvailability/journalNode/wizard_controller.js index fe9a15b..77472bc 100644 --- a/ambari-web/app/controllers/main/admin/highAvailability/journalNode/wizard_controller.js +++ b/ambari-web/app/controllers/main/admin/highAvailability/journalNode/wizard_controller.js @@ -39,9 +39,9 @@ App.ManageJournalNodeWizardController = App.WizardController.extend({ masterComponentHosts: null, serviceConfigProperties: [], serviceName: 'MISC', - hdfsUser:"hdfs", + hdfsUser: "hdfs", nameServiceId: '', - failedTask : null, + failedTask: null, requestIds: null }), @@ -59,7 +59,7 @@ App.ManageJournalNodeWizardController = App.WizardController.extend({ * return new object extended from clusterStatusTemplate * @return Object */ - getCluster: function(){ + getCluster: function () { return jQuery.extend({}, this.get('clusterStatusTemplate'), {name: App.router.getClusterName()}); }, @@ -98,7 +98,7 @@ App.ManageJournalNodeWizardController = App.WizardController.extend({ } } ], - 2 : [ + 2: [ { type: 'sync', callback: function () { @@ -123,7 +123,10 @@ App.ManageJournalNodeWizardController = App.WizardController.extend({ var result = []; var masterComponentHosts = this.get('content.masterComponentHosts'); if (masterComponentHosts) { - result = masterComponentHosts.filterProperty('component', 'JOURNALNODE').filterProperty('isInstalled', false).mapProperty('hostName'); + result = masterComponentHosts + .filterProperty('component', 'JOURNALNODE') + .filterProperty('isInstalled', false) + .mapProperty('hostName'); } return result; }, @@ -134,22 +137,22 @@ App.ManageJournalNodeWizardController = App.WizardController.extend({ if (masterComponentHosts) { var currentJNs = masterComponentHosts.filterProperty('component', 'JOURNALNODE'); var existingHosts = App.HostComponent.find().filterProperty('componentName', 'JOURNALNODE').mapProperty('hostName'); - result = existingHosts.filter(function(host) { - return currentJNs.filterProperty('hostName', host).length == 0; + result = existingHosts.filter(function (host) { + return currentJNs.filterProperty('hostName', host).length === 0; }); } return result; }, isDeleteOnly: function () { - return this.get('currentStep') > 1 && this.getJournalNodesToAdd().length == 0 && this.getJournalNodesToDelete().length > 0; + return this.get('currentStep') > 1 && this.getJournalNodesToAdd().length === 0 && this.getJournalNodesToDelete().length > 0; }.property('content.masterComponentHosts', 'App.router.clusterController.isHostsLoaded', 'currentStep'), /** * Save config properties * @param stepController ManageJournalNodeWizardStep3Controller */ - saveServiceConfigProperties: function(stepController) { + saveServiceConfigProperties: function (stepController) { var serviceConfigProperties = []; var data = stepController.get('serverConfigData'); @@ -168,12 +171,11 @@ App.ManageJournalNodeWizardController = App.WizardController.extend({ * Load serviceConfigProperties to model */ loadServiceConfigProperties: function () { - var serviceConfigProperties = this.getDBProperty('serviceConfigProperties'); - this.set('content.serviceConfigProperties', serviceConfigProperties); + this.set('content.serviceConfigProperties', this.getDBProperty('serviceConfigProperties')); }, - saveNNs: function(activeNN, standByNN) { + saveNNs: function () { var activeNN = App.HostComponent.find().findProperty('displayNameAdvanced', 'Active NameNode'); var standByNN = App.HostComponent.find().findProperty('displayNameAdvanced', 'Standby NameNode'); this.set('content.activeNN', activeNN); @@ -182,7 +184,7 @@ App.ManageJournalNodeWizardController = App.WizardController.extend({ this.setDBProperty('standByNN', standByNN); }, - loadNNs: function() { + loadNNs: function () { var activeNN = this.getDBProperty('activeNN'); var standByNN = this.getDBProperty('standByNN'); this.set('content.activeNN', activeNN); @@ -190,23 +192,23 @@ App.ManageJournalNodeWizardController = App.WizardController.extend({ }, - saveConfigTag: function(tag){ + saveConfigTag: function (tag) { App.db.setManageJournalNodeWizardConfigTag(tag); - this.set('content.'+[tag.name], tag.value); + this.set('content.' + tag.name, tag.value); }, - - - loadConfigTag: function(tag){ + + + loadConfigTag: function (tag) { var tagVal = App.db.getManageJournalNodeWizardConfigTag(tag); - this.set('content.'+tag, tagVal); + this.set('content.' + tag, tagVal); }, - saveNameServiceId: function(nameServiceId){ + saveNameServiceId: function (nameServiceId) { this.setDBProperty('nameServiceId', nameServiceId); this.set('content.nameServiceId', nameServiceId); }, - loadNameServiceId: function(){ + loadNameServiceId: function () { var nameServiceId = this.getDBProperty('nameServiceId'); this.set('content.nameServiceId', nameServiceId); }, http://git-wip-us.apache.org/repos/asf/ambari/blob/8f16d643/ambari-web/test/controllers/global/background_operations_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/controllers/global/background_operations_test.js b/ambari-web/test/controllers/global/background_operations_test.js index 5517b1e..8d982bb 100644 --- a/ambari-web/test/controllers/global/background_operations_test.js +++ b/ambari-web/test/controllers/global/background_operations_test.js @@ -730,15 +730,6 @@ describe('App.BackgroundOperationsController', function () { expect(controller.isInitLoading()).to.be.false; }); - it("should return false when no request found", function() { - controller.set('levelInfo', Em.Object.create({ - name: 'HOSTS_LIST', - requestId: 1 - })); - controller.set('services', []); - expect(controller.isInitLoading()).to.be.false; - }); - it("should return false when request has hosts", function() { controller.set('levelInfo', Em.Object.create({ name: 'HOSTS_LIST', http://git-wip-us.apache.org/repos/asf/ambari/blob/8f16d643/ambari-web/test/controllers/main/admin/highAvailability/journalNode/progress_controller_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/controllers/main/admin/highAvailability/journalNode/progress_controller_test.js b/ambari-web/test/controllers/main/admin/highAvailability/journalNode/progress_controller_test.js new file mode 100644 index 0000000..868f832 --- /dev/null +++ b/ambari-web/test/controllers/main/admin/highAvailability/journalNode/progress_controller_test.js @@ -0,0 +1,67 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +var App = require('app'); +require('controllers/main/admin/highAvailability/journalNode/progress_controller'); + + +describe('App.ManageJournalNodeProgressPageController', function () { + var controller; + + beforeEach(function() { + controller = App.ManageJournalNodeProgressPageController.create(); + }); + + describe('#reconfigureSites', function() { + + beforeEach(function() { + sinon.stub(App, 'dateTime').returns(1); + }); + + afterEach(function() { + App.dateTime.restore(); + }); + + it('should return array of sites', function() { + var siteNames = ['site1', 'site2']; + var data = {items: [ + { + type: 'site1', + properties: {}, + properties_attributes: {} + } + ]}; + expect(controller.reconfigureSites(siteNames, data, 'note')).to.be.eql([ + { + "properties": {}, + "properties_attributes": {}, + "service_config_version_note": "note", + "tag": "version1", + "type": "site1" + }, + { + "properties": undefined, + "service_config_version_note": "note", + "tag": "version1", + "type": "site2" + } + ]); + }); + }); +}); http://git-wip-us.apache.org/repos/asf/ambari/blob/8f16d643/ambari-web/test/controllers/main/admin/highAvailability/journalNode/step1_controller_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/controllers/main/admin/highAvailability/journalNode/step1_controller_test.js b/ambari-web/test/controllers/main/admin/highAvailability/journalNode/step1_controller_test.js new file mode 100644 index 0000000..17f5ed2 --- /dev/null +++ b/ambari-web/test/controllers/main/admin/highAvailability/journalNode/step1_controller_test.js @@ -0,0 +1,245 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +var App = require('app'); +require('controllers/main/admin/highAvailability/journalNode/step1_controller'); + + +describe('App.ManageJournalNodeWizardStep1Controller', function () { + var controller; + + beforeEach(function () { + controller = App.ManageJournalNodeWizardStep1Controller.create({ + getMaxNumberOfMasters: function () { + return 3; + }, + updateComponent: Em.K, + addableComponents: ['C1'] + }); + }); + + describe('#renderComponents', function () { + + beforeEach(function () { + sinon.stub(controller, 'updateJournalNodeInfo'); + sinon.stub(controller, 'showHideJournalNodesAddRemoveControl'); + }); + + afterEach(function () { + controller.updateJournalNodeInfo.restore(); + controller.showHideJournalNodesAddRemoveControl.restore(); + }); + + it('updateJournalNodeInfo should be called', function () { + controller.renderComponents([]); + expect(controller.updateJournalNodeInfo.calledOnce).to.be.true; + }); + + it('showHideJournalNodesAddRemoveControl should be called', function () { + controller.renderComponents([]); + expect(controller.showHideJournalNodesAddRemoveControl.calledOnce).to.be.true; + }); + + it('nextButtonCheckTrigger should be false', function () { + controller.set('nextButtonCheckTrigger', true); + controller.renderComponents([]); + expect(controller.get('nextButtonCheckTrigger')).to.be.false; + }); + }); + + describe('#generateJournalNodeComponents', function () { + + beforeEach(function () { + sinon.stub(App.HostComponent, 'find').returns([ + Em.Object.create({ + componentName: 'JOURNALNODE', + service: { + serviceName: 'S1' + }, + hostName: 'host1' + }) + ]); + sinon.stub(controller, 'createComponentInstallationObject', function (obj) { + return obj; + }); + }); + + afterEach(function () { + App.HostComponent.find.restore(); + controller.createComponentInstallationObject.restore(); + }); + + it('should return array with JOURNALNODE components', function () { + expect(controller.generateJournalNodeComponents()).to.be.eql([ + Em.Object.create({ + componentName: 'JOURNALNODE', + serviceName: 'S1', + isInstalled: true + }) + ]); + }); + }); + + describe('#showHideJournalNodesAddRemoveControl', function () { + + it('showAddControl should be false and showRemoveControl should be false for first journalnode', function () { + var journalNodes = [ + Em.Object.create({component_name: 'JOURNALNODE'}), + Em.Object.create({component_name: 'JOURNALNODE'}), + Em.Object.create({component_name: 'JOURNALNODE'}) + ]; + controller.set('selectedServicesMasters', journalNodes); + controller.showHideJournalNodesAddRemoveControl(); + expect(journalNodes[0].get('showAddControl')).to.be.false; + expect(journalNodes[0].get('showRemoveControl')).to.be.false; + }); + + it('showAddControl should be false and showRemoveControl should be true for first journalnode', function () { + var journalNodes = [ + Em.Object.create({component_name: 'JOURNALNODE'}), + Em.Object.create({component_name: 'JOURNALNODE'}), + Em.Object.create({component_name: 'JOURNALNODE'}), + Em.Object.create({component_name: 'JOURNALNODE'}) + ]; + controller.set('selectedServicesMasters', journalNodes); + controller.showHideJournalNodesAddRemoveControl(); + expect(journalNodes[0].get('showAddControl')).to.be.false; + expect(journalNodes[0].get('showRemoveControl')).to.be.true; + }); + + it('showAddControl should be true and showRemoveControl should be false for second journalnode', function () { + var journalNodes = [ + Em.Object.create({component_name: 'JOURNALNODE'}), + Em.Object.create({component_name: 'JOURNALNODE'}) + ]; + controller.set('selectedServicesMasters', journalNodes); + controller.showHideJournalNodesAddRemoveControl(); + expect(journalNodes[1].get('showAddControl')).to.be.true; + expect(journalNodes[1].get('showRemoveControl')).to.be.false; + }); + }); + + describe('#updateJournalNodeInfo', function() { + + beforeEach(function() { + sinon.stub(App.HostComponent, 'find').returns([ + Em.Object.create({ + componentName: 'JOURNALNODE', + hostName: 'host1' + }) + ]); + }); + + afterEach(function() { + App.HostComponent.find.restore(); + }); + + it('isInstalled and showCurrentPrefix should be true for installed hosts', function() { + var journalNodes = [ + Em.Object.create({ + component_name: 'JOURNALNODE', + selectedHost: 'host1' + }), + Em.Object.create({ + component_name: 'JOURNALNODE', + selectedHost: 'host2' + }) + ]; + controller.set('selectedServicesMasters', journalNodes); + controller.updateJournalNodeInfo(); + expect(journalNodes[0]).to.be.eql(Em.Object.create({ + "component_name": "JOURNALNODE", + "isInstalled": true, + "selectedHost": "host1", + "showCurrentPrefix": true + })); + expect(journalNodes[1]).to.be.eql(Em.Object.create({ + component_name: 'JOURNALNODE', + selectedHost: 'host2' + })); + }); + }); + + describe('#loadStepCallback', function() { + + beforeEach(function() { + sinon.stub(controller, 'renderComponents'); + sinon.stub(controller, 'updateComponent'); + }); + + afterEach(function() { + controller.renderComponents.restore(); + controller.updateComponent.restore(); + }); + + it('renderComponents should be called', function() { + controller.loadStepCallback([], controller); + expect(controller.renderComponents.calledWith([])).to.be.true; + }); + + it('updateComponent should be called', function() { + controller.set('addableComponents', ['C1']); + controller.loadStepCallback([], controller); + expect(controller.updateComponent.calledWith('C1')).to.be.true; + }); + + it('isLoaded should be true', function() { + controller.loadStepCallback([], controller); + expect(controller.get('isLoaded')).to.be.true; + }); + }); + + describe('#nextButtonDisabled', function() { + + beforeEach(function() { + sinon.stub(App.HostComponent, 'find').returns([ + Em.Object.create({ + componentName: 'JOURNALNODE', + hostName: 'host1' + }) + ]); + }); + + afterEach(function() { + App.HostComponent.find.restore(); + }); + + it('should return true when hosts identical', function() { + controller.set('selectedServicesMasters', [ + Em.Object.create({ + component_name: 'JOURNALNODE', + selectedHost: 'host1' + }) + ]); + controller.propertyDidChange('nextButtonDisabled'); + expect(controller.get('nextButtonDisabled')).to.be.true; + }); + + it('should return false when hosts have been changed', function() { + controller.set('selectedServicesMasters', [ + Em.Object.create({ + component_name: 'JOURNALNODE', + selectedHost: 'host2' + }) + ]); + controller.propertyDidChange('nextButtonDisabled'); + expect(controller.get('nextButtonDisabled')).to.be.false; + }); + }); +}); http://git-wip-us.apache.org/repos/asf/ambari/blob/8f16d643/ambari-web/test/controllers/main/admin/highAvailability/journalNode/step2_controller_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/controllers/main/admin/highAvailability/journalNode/step2_controller_test.js b/ambari-web/test/controllers/main/admin/highAvailability/journalNode/step2_controller_test.js new file mode 100644 index 0000000..17230bb --- /dev/null +++ b/ambari-web/test/controllers/main/admin/highAvailability/journalNode/step2_controller_test.js @@ -0,0 +1,281 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +var App = require('app'); +require('controllers/main/admin/highAvailability/journalNode/step1_controller'); +var testHelpers = require('test/helpers'); + +describe('App.ManageJournalNodeWizardStep2Controller', function () { + var controller; + + beforeEach(function () { + controller = App.ManageJournalNodeWizardStep2Controller.create({ + content: Em.Object.create() + }); + }); + + describe('#clearStep', function() { + + it('stepConfigs should be empty', function() { + controller.clearStep(); + expect(controller.get('stepConfigs')).to.be.empty; + }); + + it('serverConfigData should be empty', function() { + controller.clearStep(); + expect(controller.get('serverConfigData')).to.be.empty; + }); + }); + + describe('#loadStep', function() { + + beforeEach(function() { + sinon.stub(controller, 'clearStep'); + sinon.stub(controller, 'loadConfigsTags'); + }); + + afterEach(function() { + controller.clearStep.restore(); + controller.loadConfigsTags.restore(); + }); + + it('loadConfigsTags should be called', function() { + controller.loadStep(); + expect(controller.loadConfigsTags.calledOnce).to.be.true; + }); + + it('clearStep should be called', function() { + controller.loadStep(); + expect(controller.clearStep.calledOnce).to.be.true; + }); + }); + + describe('#loadConfigsTags', function() { + + it('App.ajax.send should be called', function() { + controller.loadConfigsTags(); + var args = testHelpers.findAjaxRequest('name', 'config.tags'); + expect(args[0]).to.exists; + }); + }); + + describe('#onLoadConfigsTags', function() { + var data = { + Clusters: { + desired_configs: { + 'hdfs-site': { + tag: 'tag1' + } + } + } + }; + + it('App.ajax.send should be called', function() { + controller.onLoadConfigsTags(data); + var args = testHelpers.findAjaxRequest('name', 'admin.get.all_configurations'); + expect(args[0]).to.be.eql({ + name: 'admin.get.all_configurations', + sender: controller, + data: { + urlParams: '(type=hdfs-site&tag=tag1)' + }, + success: 'onLoadConfigs', + error: 'onTaskError' + }); + }); + + it('hdfsSiteTag should be set', function() { + controller.onLoadConfigsTags(data); + expect(controller.get('hdfsSiteTag')).to.be.eql({name: "hdfsSiteTag", value: 'tag1'}); + }); + }); + + describe('#onLoadConfigs', function() { + var data = { + items: [ + { + properties: { + 'dfs.nameservices': 'id' + } + } + ] + }; + + beforeEach(function() { + sinon.stub(controller, 'tweakServiceConfigs'); + sinon.stub(controller, 'renderServiceConfigs'); + }); + + afterEach(function() { + controller.tweakServiceConfigs.restore(); + controller.renderServiceConfigs.restore(); + }); + + it('renderServiceConfigs should be called', function() { + controller.onLoadConfigs(data); + expect(controller.renderServiceConfigs.calledOnce).to.be.true; + }); + + it('tweakServiceConfigs should be called', function() { + controller.onLoadConfigs(data); + expect(controller.tweakServiceConfigs.calledOnce).to.be.true; + }); + + it('serviceConfigData should be an object', function() { + controller.onLoadConfigs(data); + expect(controller.get('serverConfigData')).to.be.eql(data); + }); + + it('nameServiceId should be "id"', function() { + controller.onLoadConfigs(data); + expect(controller.get('content.nameServiceId')).to.be.equal('id'); + }); + + it('isLoaded should be true', function() { + controller.onLoadConfigs(data); + expect(controller.get('isLoaded')).to.be.true; + }); + }); + + describe('#_prepareDependencies', function() { + + it('should return configs object', function() { + controller.set('serverConfigData', {items: []}); + controller.set('content.nameServiceId', 'id1'); + expect(controller._prepareDependencies()).to.be.eql({ + namespaceId: 'id1', + serverConfigs: [] + }); + }); + }); + + describe('#_prepareLocalDB', function() { + + beforeEach(function() { + sinon.stub(App.Service, 'find').returns([ + Em.Object.create({ + serviceName: 'S1' + }) + ]); + }); + + afterEach(function() { + App.Service.find.restore(); + }); + + it('should return localDB object', function() { + controller.set('content', Em.Object.create({ + masterComponentHosts: [], + slaveComponentHosts: [], + hosts: [] + })); + expect(controller._prepareLocalDB()).to.be.eql({ + masterComponentHosts: [], + slaveComponentHosts: [], + hosts: [], + installedServices: ['S1'] + }); + }); + }); + + describe('#tweakServiceConfigs', function() { + + beforeEach(function() { + sinon.stub(controller, '_prepareLocalDB').returns({}); + sinon.stub(controller, '_prepareDependencies').returns({}); + sinon.stub(App.NnHaConfigInitializer, 'initialValue'); + }); + + afterEach(function() { + controller._prepareLocalDB.restore(); + controller._prepareDependencies.restore(); + App.NnHaConfigInitializer.initialValue.restore(); + }); + + it('App.NnHaConfigInitializer.initialValue should be called', function() { + controller.tweakServiceConfigs([{}]); + expect(App.NnHaConfigInitializer.initialValue.calledOnce).to.be.true; + }); + + it('should return array of configs', function() { + expect(controller.tweakServiceConfigs([{}])).to.be.eql([{ + isOverridable: false + }]); + }); + }); + + describe('#renderServiceConfigs', function() { + var _serviceConfig = { + configCategories: [ + { + name: 'S1' + } + ] + }; + + beforeEach(function() { + sinon.stub(App.Service, 'find').returns([ + { + serviceName: 'S1' + } + ]); + sinon.stub(controller, 'loadComponentConfigs'); + controller.set('stepConfigs', []); + controller.renderServiceConfigs(_serviceConfig); + }); + + afterEach(function() { + controller.loadComponentConfigs.restore(); + App.Service.find.restore(); + }); + + it('stepConfigs should not be empty', function() { + expect(controller.get('stepConfigs')).to.not.be.empty; + }); + + it('selectedService should be object', function() { + expect(controller.get('selectedService')).to.be.an.object; + }); + + it('once should be true', function() { + expect(controller.get('once')).to.be.true; + }); + + it('loadComponentConfigs should be called', function() { + expect(controller.loadComponentConfigs.calledOnce).to.be.true; + }); + }); + + describe('#loadComponentConfigs', function() { + var componentConfig = { + configs: [] + }; + + it('configs should not be empty', function() { + controller.loadComponentConfigs({configs: [{}]}, componentConfig); + expect(componentConfig.configs).to.not.be.empty; + }); + + it('isEditable should be true', function() { + controller.loadComponentConfigs({configs: [{isReconfigurable: true}]}, componentConfig); + expect(componentConfig.configs[0].get('isEditable')).to.be.true; + }); + }); +}); + http://git-wip-us.apache.org/repos/asf/ambari/blob/8f16d643/ambari-web/test/controllers/main/admin/highAvailability/journalNode/step4_controller_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/controllers/main/admin/highAvailability/journalNode/step4_controller_test.js b/ambari-web/test/controllers/main/admin/highAvailability/journalNode/step4_controller_test.js new file mode 100644 index 0000000..ba92b54 --- /dev/null +++ b/ambari-web/test/controllers/main/admin/highAvailability/journalNode/step4_controller_test.js @@ -0,0 +1,220 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +var App = require('app'); +require('controllers/main/admin/highAvailability/journalNode/step1_controller'); +var testHelpers = require('test/helpers'); + +describe('App.ManageJournalNodeWizardStep4Controller', function () { + var controller; + + beforeEach(function () { + controller = App.ManageJournalNodeWizardStep4Controller.create({ + content: Em.Object.create() + }); + }); + + describe('#stopStandbyNameNode', function() { + + beforeEach(function() { + sinon.stub(controller, 'updateComponent'); + }); + + afterEach(function() { + controller.updateComponent.restore(); + }); + + it('updateComponent should be called', function() { + controller.set('content.standByNN', { + host_name: 'host1' + }); + controller.stopStandbyNameNode(); + expect(controller.updateComponent.calledWith('NAMENODE', 'host1', 'HDFS', 'INSTALLED')).to.be.true; + }); + }); + + describe('#installJournalNodes', function() { + var wizardController = { + getJournalNodesToAdd: Em.K + }; + + beforeEach(function() { + this.mock = sinon.stub(wizardController, 'getJournalNodesToAdd'); + sinon.stub(App.router, 'get').returns(wizardController); + sinon.stub(controller, 'createInstallComponentTask'); + sinon.stub(controller, 'onTaskCompleted'); + }); + + afterEach(function() { + App.router.get.restore(); + this.mock.restore(); + controller.createInstallComponentTask.restore(); + controller.onTaskCompleted.restore(); + }); + + it('onTaskCompleted should be called when no journalnodes to add', function() { + this.mock.returns([]); + controller.installJournalNodes(); + expect(controller.onTaskCompleted.calledOnce).to.be.true; + expect(controller.createInstallComponentTask.called).to.be.false; + }); + + it('createInstallComponentTask should be called when there are journalnodes to add', function() { + this.mock.returns(['host1']); + controller.installJournalNodes(); + expect(controller.onTaskCompleted.called).to.be.false; + expect(controller.createInstallComponentTask.calledWith('JOURNALNODE', ['host1'], "HDFS")).to.be.true; + }); + }); + + describe('#deleteJournalNodes', function() { + var wizardController = { + getJournalNodesToDelete: Em.K + }; + + beforeEach(function() { + this.mock = sinon.stub(wizardController, 'getJournalNodesToDelete'); + sinon.stub(App.router, 'get').returns(wizardController); + sinon.stub(controller, 'deleteComponent'); + sinon.stub(controller, 'onTaskCompleted'); + }); + + afterEach(function() { + App.router.get.restore(); + this.mock.restore(); + controller.deleteComponent.restore(); + controller.onTaskCompleted.restore(); + }); + + it('onTaskCompleted should be called when no journalnodes to delete', function() { + this.mock.returns([]); + controller.deleteJournalNodes(); + expect(controller.onTaskCompleted.calledOnce).to.be.true; + expect(controller.deleteComponent.called).to.be.false; + }); + + it('deleteComponent should be called when there are journalnodes to delete', function() { + this.mock.returns(['host1']); + controller.deleteJournalNodes(); + expect(controller.onTaskCompleted.called).to.be.false; + expect(controller.deleteComponent.calledWith('JOURNALNODE', 'host1')).to.be.true; + }); + }); + + describe('#startJournalNodes', function() { + + beforeEach(function() { + sinon.stub(controller, 'updateComponent'); + }); + + afterEach(function() { + controller.updateComponent.restore(); + }); + + it('updateComponent should be called', function() { + controller.set('content.masterComponentHosts', [ + { + component: 'JOURNALNODE', + hostName: 'host1' + } + ]); + controller.startJournalNodes(); + expect(controller.updateComponent.calledWith('JOURNALNODE', ['host1'], "HDFS", "Start")).to.be.true; + }); + }); + + describe('#reconfigureHDFS', function() { + + beforeEach(function() { + sinon.stub(controller, 'updateConfigProperties'); + }); + + afterEach(function() { + controller.updateConfigProperties.restore(); + }); + + it('updateConfigProperties should be called', function() { + controller.set('content.serviceConfigProperties', [ + {} + ]); + controller.reconfigureHDFS(); + expect(controller.updateConfigProperties.calledWith([{}])).to.be.true; + }); + }); + + describe('#updateConfigProperties', function() { + + beforeEach(function() { + sinon.stub(controller, 'reconfigureSites').returns({}); + }); + + afterEach(function() { + controller.reconfigureSites.restore(); + }); + + it('App.ajax.send should be called', function() { + controller.updateConfigProperties(); + var args = testHelpers.findAjaxRequest('name', 'common.service.configurations'); + expect(args[0]).to.be.eql({ + name: 'common.service.configurations', + sender: controller, + data: { + desired_config: {} + }, + success: 'installHDFSClients', + error: 'onTaskError' + }); + }); + }); + + describe('#installHDFSClients', function() { + + beforeEach(function() { + sinon.stub(controller, 'createInstallComponentTask'); + sinon.stub(App.clusterStatus, 'setClusterStatus'); + controller.set('content.masterComponentHosts', [ + { + component: 'NAMENODE', + hostName: 'host1' + }, + { + component: 'JOURNALNODE', + hostName: 'host2' + } + ]); + }); + + afterEach(function() { + controller.createInstallComponentTask.restore(); + App.clusterStatus.setClusterStatus.restore(); + }); + + it('App.clusterStatus.setClusterStatus should be called', function() { + controller.installHDFSClients(); + expect(App.clusterStatus.setClusterStatus.calledOnce).to.be.true; + }); + + it('createInstallComponentTask should be called', function() { + controller.installHDFSClients(); + expect(controller.createInstallComponentTask.calledWith('HDFS_CLIENT', ['host1', 'host2'], 'HDFS')).to.be.true; + }); + }); + +}); + http://git-wip-us.apache.org/repos/asf/ambari/blob/8f16d643/ambari-web/test/controllers/main/admin/highAvailability/journalNode/step6_controller_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/controllers/main/admin/highAvailability/journalNode/step6_controller_test.js b/ambari-web/test/controllers/main/admin/highAvailability/journalNode/step6_controller_test.js new file mode 100644 index 0000000..8351628 --- /dev/null +++ b/ambari-web/test/controllers/main/admin/highAvailability/journalNode/step6_controller_test.js @@ -0,0 +1,74 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +var App = require('app'); +require('controllers/main/admin/highAvailability/journalNode/step1_controller'); + +describe('App.ManageJournalNodeWizardStep6Controller', function () { + var controller; + + beforeEach(function () { + controller = App.ManageJournalNodeWizardStep6Controller.create({ + content: Em.Object.create() + }); + }); + + describe('#startZooKeeperServers', function() { + + beforeEach(function() { + sinon.stub(controller, 'updateComponent'); + }); + + afterEach(function() { + controller.updateComponent.restore(); + }); + + it('updateComponent should be called', function() { + controller.set('content.masterComponentHosts', [ + { + component: 'ZOOKEEPER_SERVER', + hostName: 'host1' + } + ]); + controller.startZooKeeperServers(); + expect(controller.updateComponent.calledWith('ZOOKEEPER_SERVER', ['host1'], "ZOOKEEPER", "Start")).to.be.true; + }); + }); + + describe('#startActiveNameNode', function() { + + beforeEach(function() { + sinon.stub(controller, 'updateComponent'); + }); + + afterEach(function() { + controller.updateComponent.restore(); + }); + + it('updateComponent should be called', function() { + controller.set('content.activeNN', { + host_name: 'host1' + }); + controller.startActiveNameNode(); + expect(controller.updateComponent.calledWith('NAMENODE', 'host1', "HDFS", "Start")).to.be.true; + }); + }); + +}); + http://git-wip-us.apache.org/repos/asf/ambari/blob/8f16d643/ambari-web/test/controllers/main/admin/highAvailability/journalNode/step7_controller_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/controllers/main/admin/highAvailability/journalNode/step7_controller_test.js b/ambari-web/test/controllers/main/admin/highAvailability/journalNode/step7_controller_test.js new file mode 100644 index 0000000..386d64e --- /dev/null +++ b/ambari-web/test/controllers/main/admin/highAvailability/journalNode/step7_controller_test.js @@ -0,0 +1,46 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +var App = require('app'); +require('controllers/main/admin/highAvailability/journalNode/step7_controller'); + + +describe('App.ManageJournalNodeWizardStep7Controller', function () { + var controller; + + beforeEach(function () { + controller = App.ManageJournalNodeWizardStep7Controller.create(); + }); + + describe('#done', function() { + + beforeEach(function() { + sinon.stub(App.router, 'send'); + }); + + afterEach(function() { + App.router.send.restore(); + }); + + it('App.router.send should be called', function() { + controller.done(); + expect(App.router.send.calledWith('next')).to.be.true; + }); + }); +}); http://git-wip-us.apache.org/repos/asf/ambari/blob/8f16d643/ambari-web/test/controllers/main/admin/highAvailability/journalNode/step8_controller_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/controllers/main/admin/highAvailability/journalNode/step8_controller_test.js b/ambari-web/test/controllers/main/admin/highAvailability/journalNode/step8_controller_test.js new file mode 100644 index 0000000..9642d4a --- /dev/null +++ b/ambari-web/test/controllers/main/admin/highAvailability/journalNode/step8_controller_test.js @@ -0,0 +1,61 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +var App = require('app'); +require('controllers/main/admin/highAvailability/journalNode/step8_controller'); + +describe('App.ManageJournalNodeWizardStep8Controller', function () { + var controller; + + beforeEach(function () { + controller = App.ManageJournalNodeWizardStep8Controller.create(); + }); + + describe('#stopHDFS', function() { + + beforeEach(function() { + sinon.stub(controller, 'stopServices'); + }); + + afterEach(function() { + controller.stopServices.restore(); + }); + + it('stopServices should be called', function() { + controller.stopHDFS(); + expect(controller.stopServices.calledWith(['HDFS'], true)).to.be.true; + }); + }); + + describe('#startAllServices', function() { + + beforeEach(function() { + sinon.stub(controller, 'startServices'); + }); + + afterEach(function() { + controller.startServices.restore(); + }); + + it('stopServices should be called', function() { + controller.startAllServices(); + expect(controller.startServices.calledWith(false)).to.be.true; + }); + }); +}); http://git-wip-us.apache.org/repos/asf/ambari/blob/8f16d643/ambari-web/test/controllers/main/admin/highAvailability/journalNode/wizard_controller_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/controllers/main/admin/highAvailability/journalNode/wizard_controller_test.js b/ambari-web/test/controllers/main/admin/highAvailability/journalNode/wizard_controller_test.js new file mode 100644 index 0000000..fe8778f --- /dev/null +++ b/ambari-web/test/controllers/main/admin/highAvailability/journalNode/wizard_controller_test.js @@ -0,0 +1,404 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +var App = require('app'); +require('controllers/main/admin/highAvailability/journalNode/wizard_controller'); + + +describe('App.ManageJournalNodeWizardController', function () { + var controller; + + beforeEach(function () { + controller = App.ManageJournalNodeWizardController.create({ + content: Em.Object.create(), + currentStep: 0 + }); + }); + + describe('#setCurrentStep', function() { + + beforeEach(function() { + sinon.stub(App.clusterStatus, 'setClusterStatus'); + }); + + afterEach(function() { + App.clusterStatus.setClusterStatus.restore(); + }); + + it('setCurrentStep should be called', function() { + controller.setCurrentStep(1, true); + expect(App.clusterStatus.setClusterStatus.calledOnce).to.be.true; + }); + }); + + describe('#getCluster', function() { + + beforeEach(function() { + sinon.stub(App.router, 'getClusterName').returns('c1'); + }); + afterEach(function() { + App.router.getClusterName.restore(); + }); + + it('should return cluster object', function() { + controller.set('clusterStatusTemplate', {}); + expect(controller.getCluster()).to.be.eql({ + name: 'c1' + }); + }); + }); + + describe('#getJournalNodesToAdd', function() { + + it('should return journalnodes hosts array', function() { + controller.set('content.masterComponentHosts', [ + Em.Object.create({ + component: 'JOURNALNODE', + isInstalled: false, + hostName: 'host1' + }) + ]); + expect(controller.getJournalNodesToAdd()).to.be.eql(['host1']); + }); + + it('should return empty array', function() { + controller.set('content.masterComponentHosts', null); + expect(controller.getJournalNodesToAdd()).to.be.empty; + }); + }); + + describe('#getJournalNodesToDelete', function() { + + beforeEach(function() { + sinon.stub(App.HostComponent, 'find').returns([ + Em.Object.create({ + componentName: 'JOURNALNODE', + hostName: 'host2' + }), + Em.Object.create({ + componentName: 'JOURNALNODE', + hostName: 'host1' + }) + ]); + }); + + afterEach(function() { + App.HostComponent.find.restore(); + }); + + it('should return empty array', function() { + controller.set('content.masterComponentHosts', null); + expect(controller.getJournalNodesToDelete()).to.be.empty; + }); + + it('should return journalnodes hosts array', function() { + controller.set('content.masterComponentHosts', [ + Em.Object.create({ + component: 'JOURNALNODE', + isInstalled: false, + hostName: 'host1' + }) + ]); + expect(controller.getJournalNodesToDelete()).to.be.eql([ + 'host2' + ]); + }); + }); + + describe('#isDeleteOnly', function() { + + beforeEach(function() { + this.mockAdd = sinon.stub(controller, 'getJournalNodesToAdd').returns([]); + this.mockDelete = sinon.stub(controller, 'getJournalNodesToDelete').returns([]); + }); + afterEach(function() { + this.mockDelete.restore(); + this.mockAdd.restore(); + }); + + it('should return false when currentStep less than 2nd', function() { + controller.set('currentStep', 1); + expect(controller.get('isDeleteOnly')).to.be.false; + }); + + it('should return false when there are nodes to add', function() { + this.mockAdd.returns(['host1']); + controller.set('currentStep', 2); + controller.propertyDidChange('isDeleteOnly'); + expect(controller.get('isDeleteOnly')).to.be.false; + }); + + it('should return false when there are no nodes to delete', function() { + this.mockAdd.returns([]); + this.mockDelete.returns([]); + controller.set('currentStep', 2); + controller.propertyDidChange('isDeleteOnly'); + expect(controller.get('isDeleteOnly')).to.be.false; + }); + + it('should return true when there are nodes to delete', function() { + this.mockAdd.returns([]); + this.mockDelete.returns(['host1']); + controller.set('currentStep', 2); + controller.propertyDidChange('isDeleteOnly'); + expect(controller.get('isDeleteOnly')).to.be.true; + }); + }); + + describe('#saveServiceConfigProperties', function() { + + beforeEach(function() { + sinon.stub(controller, 'setDBProperty'); + }); + + afterEach(function() { + controller.setDBProperty.restore(); + }); + + it('serviceConfigProperties should be set', function() { + var stepCtrl = Em.Object.create({ + serverConfigData: { + items: [{ + type: 'file1', + properties: { + c1: 'val1' + } + }] + }, + stepConfigs: [ + Em.Object.create({ + configs: [ + Em.Object.create({ + name: 'c1', + value: 'val1', + filename: 'file1' + }) + ] + }) + ] + }); + controller.saveServiceConfigProperties(stepCtrl); + expect(JSON.stringify(controller.get('content.serviceConfigProperties'))).to.be.eql(JSON.stringify({ + "items": [ + { + "type": "file1", + "properties": { + "c1": "val1" + } + } + ] + })); + expect(controller.setDBProperty.calledWith('serviceConfigProperties', { + "items": [ + { + "type": "file1", + "properties": { + "c1": "val1" + } + } + ] + })).to.be.true; + }); + }); + + describe('#loadServiceConfigProperties', function() { + + beforeEach(function() { + sinon.stub(controller, 'getDBProperty').returns({}); + }); + + it('serviceConfigProperties should be set', function() { + controller.loadServiceConfigProperties(); + expect(controller.get('content.serviceConfigProperties')).to.be.eql({}); + }); + }); + + describe('#saveNNs', function() { + + beforeEach(function() { + sinon.stub(App.HostComponent, 'find').returns([ + { + displayNameAdvanced: 'Active NameNode' + }, + { + displayNameAdvanced: 'Standby NameNode' + } + ]); + sinon.stub(controller, 'setDBProperty'); + }); + + afterEach(function() { + controller.setDBProperty.restore(); + App.HostComponent.find.restore(); + }); + + it('NameNodes should be set', function() { + controller.saveNNs(); + expect(controller.get('content.activeNN')).to.be.eql({ + displayNameAdvanced: 'Active NameNode' + }); + expect(controller.get('content.standByNN')).to.be.eql({ + displayNameAdvanced: 'Standby NameNode' + }); + }); + + it('setDBProperty should be called', function() { + controller.saveNNs(); + expect(controller.setDBProperty.calledWith('activeNN', { + displayNameAdvanced: 'Active NameNode' + })).to.be.true; + expect(controller.setDBProperty.calledWith('standByNN', { + displayNameAdvanced: 'Standby NameNode' + })).to.be.true; + }); + }); + + describe('#loadNNs', function() { + + beforeEach(function() { + sinon.stub(controller, 'getDBProperty').returns({}); + }); + + it('NameNodes should be set', function() { + controller.loadNNs(); + expect(controller.get('content.activeNN')).to.be.eql({}); + expect(controller.get('content.standByNN')).to.be.eql({}); + }); + }); + + describe('#loadConfigTag', function() { + + beforeEach(function() { + sinon.stub(App.db, 'getManageJournalNodeWizardConfigTag').returns('val1'); + }); + + it('should load config tag', function() { + controller.loadConfigTag('tag1'); + expect(App.db.getManageJournalNodeWizardConfigTag.calledWith('tag1')).to.be.true; + expect(controller.get('content.tag1')).to.be.equal('val1'); + }); + }); + + describe('#saveConfigTag', function() { + + beforeEach(function() { + sinon.stub(App.db, 'setManageJournalNodeWizardConfigTag'); + }); + + it('should save config tag', function() { + controller.saveConfigTag({name: 'tag1', value: 'val1'}); + expect(App.db.setManageJournalNodeWizardConfigTag.calledWith({name: 'tag1', value: 'val1'})).to.be.true; + expect(controller.get('content.tag1')).to.be.equal('val1'); + }); + }); + + describe('#saveNameServiceId', function() { + + beforeEach(function() { + sinon.stub(controller, 'setDBProperty'); + }); + + it('nameServiceId should be set', function() { + controller.saveNameServiceId('id1'); + expect(controller.setDBProperty.calledWith('nameServiceId', 'id1')).to.be.true; + expect(controller.get('content.nameServiceId')).to.be.equal('id1'); + }); + }); + + describe('#loadNameServiceId', function() { + + beforeEach(function() { + sinon.stub(controller, 'getDBProperty').returns('id1'); + }); + + it('nameServiceId should be set', function() { + controller.loadNameServiceId(); + expect(controller.get('content.nameServiceId')).to.be.equal('id1'); + }); + }); + + describe('#clearAllSteps', function() { + + beforeEach(function() { + sinon.stub(controller, 'clearInstallOptions'); + sinon.stub(controller, 'getCluster').returns({name: 'c1'}); + }); + + it('cluster should be set and clearInstallOptions should be called', function() { + controller.clearAllSteps(); + expect(controller.get('content.cluster')).to.be.eql({name: 'c1'}); + expect(controller.clearInstallOptions.calledOnce).to.be.true; + }); + }); + + describe('#clearTasksData', function() { + + beforeEach(function() { + sinon.stub(controller, 'saveTasksStatuses'); + sinon.stub(controller, 'saveRequestIds'); + sinon.stub(controller, 'saveTasksRequestIds'); + controller.clearTasksData(); + }); + + afterEach(function() { + controller.saveTasksRequestIds.restore(); + controller.saveRequestIds.restore(); + controller.saveTasksStatuses.restore(); + }); + + it('saveTasksStatuses should be called', function() { + expect(controller.saveTasksStatuses.calledWith(undefined)).to.be.true; + }); + + it('saveRequestIds should be called', function() { + expect(controller.saveRequestIds.calledWith(undefined)).to.be.true; + }); + + it('saveTasksRequestIds should be called', function() { + expect(controller.saveTasksRequestIds.calledWith(undefined)).to.be.true; + }); + }); + + describe('#finish', function() { + var mock = { + updateAll: Em.K + }; + + beforeEach(function() { + sinon.stub(App.router, 'get').returns(mock); + sinon.spy(mock, 'updateAll'); + sinon.stub(controller, 'resetDbNamespace'); + controller.finish(); + }); + + afterEach(function() { + controller.resetDbNamespace.restore(); + mock.updateAll.restore(); + App.router.get.restore(); + }); + + it('resetDbNamespace should be called', function() { + expect(controller.resetDbNamespace.calledOnce).to.be.true; + }); + + it('updateAll should be called', function() { + expect(mock.updateAll.calledOnce).to.be.true; + }); + }); +});
