http://git-wip-us.apache.org/repos/asf/ambari/blob/304bd060/ambari-web/app/templates/main/service/reassign/step3.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/main/service/reassign/step3.hbs b/ambari-web/app/templates/main/service/reassign/step3.hbs index 1ffe989..1b9c8ff 100644 --- a/ambari-web/app/templates/main/service/reassign/step3.hbs +++ b/ambari-web/app/templates/main/service/reassign/step3.hbs @@ -27,17 +27,37 @@ </div> {{/if}} <div id="step8-content" class="well pre-scrollable"> - <div id="printReview"> - <a class="btn btn-info pull-right" {{action printReview target="view"}}>{{t common.print}}</a> <br/> - </div> <div id="step8-info"> - <p><b>{{t services.reassign.step3.component}}</b> {{controller.content.reassign.display_name}}</p> - - <p><b>{{t services.reassign.step3.sourceHost}}</b> {{view.sourceHost}}</p> - - <p><b>{{t services.reassign.step3.targetHost}}</b> {{view.targetHost}}</p> + <table id="reassign-review-table"> + <tr> + <td><b>{{t services.reassign.step3.component}}</b></td> + <td colspan="2">{{controller.content.reassign.display_name}}</td> + </tr> + <tr> + <td><b>{{t services.reassign.step3.sourceHost}}</b></td> + <td>{{view.sourceHost}}</td> + <td><span class="to-be-disabled-red"><i class="icon-minus"></i> {{t admin.highAvailability.wizard.step3.toBeDeleted}}</span></td> + </tr> + <tr> + <td><b>{{t services.reassign.step3.targetHost}}</b></td> + <td>{{view.targetHost}}</td> + <td><span class="to-be-installed-green"><i class="icon-plus"></i> {{t admin.highAvailability.wizard.step3.toBeInstalled}}</span></td> + </tr> + </table> </div> </div> +{{#if wizardController.isComponentWithReconfiguration}} + {{#if isLoaded}} + {{#if stepConfigs.length}} + <div id="serviceConfig"> + {{t services.reassign.step3.configs}} + {{view App.ServiceConfigView}} + </div> + {{/if}} + {{else}} + {{view App.SpinnerView}} + {{/if}} +{{/if}} <div class="btn-area"> <a class="btn pull-left" {{action back href="true"}}>← {{t common.back}}</a> <a class="btn btn-success pull-right"
http://git-wip-us.apache.org/repos/asf/ambari/blob/304bd060/ambari-web/app/views/main/admin/highAvailability/rangerAdmin/step3_view.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/main/admin/highAvailability/rangerAdmin/step3_view.js b/ambari-web/app/views/main/admin/highAvailability/rangerAdmin/step3_view.js index 8aa0125..1c55608 100644 --- a/ambari-web/app/views/main/admin/highAvailability/rangerAdmin/step3_view.js +++ b/ambari-web/app/views/main/admin/highAvailability/rangerAdmin/step3_view.js @@ -21,6 +21,10 @@ var App = require('app'); App.RAHighAvailabilityWizardStep3View = Em.View.extend({ - templateName: require('templates/main/admin/highAvailability/rangerAdmin/step3') + templateName: require('templates/main/admin/highAvailability/rangerAdmin/step3'), + + didInsertElement: function () { + this.get('controller').loadStep(); + } }); http://git-wip-us.apache.org/repos/asf/ambari/blob/304bd060/ambari-web/app/views/main/host/summary.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/main/host/summary.js b/ambari-web/app/views/main/host/summary.js index 80c4890..89332de 100644 --- a/ambari-web/app/views/main/host/summary.js +++ b/ambari-web/app/views/main/host/summary.js @@ -215,11 +215,7 @@ App.MainHostSummaryView = Em.View.extend(App.TimeRangeMixin, { */ addableComponentObject: Em.Object.extend({ componentName: '', - subComponentNames: null, displayName: function () { - if (this.get('componentName') === 'CLIENTS') { - return this.t('common.clients'); - } return App.format.role(this.get('componentName'), false); }.property('componentName') }), http://git-wip-us.apache.org/repos/asf/ambari/blob/304bd060/ambari-web/app/views/main/service/reassign/step3_view.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/main/service/reassign/step3_view.js b/ambari-web/app/views/main/service/reassign/step3_view.js index 003fcb6..b6a379e 100644 --- a/ambari-web/app/views/main/service/reassign/step3_view.js +++ b/ambari-web/app/views/main/service/reassign/step3_view.js @@ -27,8 +27,8 @@ App.ReassignMasterWizardStep3View = Em.View.extend({ targetHost: Em.computed.alias('controller.content.reassignHosts.target'), - printReview: function () { - $("#step8-info").jqprint(); + didInsertElement: function () { + this.get('controller').loadStep(); }, jdbcSetupMessage: function() { http://git-wip-us.apache.org/repos/asf/ambari/blob/304bd060/ambari-web/app/views/main/service/reassign/step5_view.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/main/service/reassign/step5_view.js b/ambari-web/app/views/main/service/reassign/step5_view.js index c5fc3c8..e10dc14 100644 --- a/ambari-web/app/views/main/service/reassign/step5_view.js +++ b/ambari-web/app/views/main/service/reassign/step5_view.js @@ -42,8 +42,8 @@ App.ReassignMasterWizardStep5View = Em.View.extend({ } if (this.get('controller.content.reassign.component_name') === 'APP_TIMELINE_SERVER') { - user = this.get('controller.content.serviceProperties.yarn-env.yarn_user'); - path = this.get('controller.content.serviceProperties.yarn-site')['yarn.timeline-service.leveldb-timeline-store.path']; + user = this.get('controller.content.configs.yarn-env.yarn_user'); + path = this.get('controller.content.configs.yarn-site')['yarn.timeline-service.leveldb-timeline-store.path']; } return Em.I18n.t('services.reassign.step5.body.' + this.get('controller.content.reassign.component_name').toLowerCase() + ha). http://git-wip-us.apache.org/repos/asf/ambari/blob/304bd060/ambari-web/test/controllers/main/admin/highAvailability/rangerAdmin/step3_controller_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/controllers/main/admin/highAvailability/rangerAdmin/step3_controller_test.js b/ambari-web/test/controllers/main/admin/highAvailability/rangerAdmin/step3_controller_test.js new file mode 100644 index 0000000..4dc3539 --- /dev/null +++ b/ambari-web/test/controllers/main/admin/highAvailability/rangerAdmin/step3_controller_test.js @@ -0,0 +1,104 @@ +/** + * 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/rangerAdmin/step3_controller'); +require('controllers/main/admin/highAvailability/rangerAdmin/wizard_controller'); +require('controllers/main'); + +describe('App.RAHighAvailabilityWizardStep3Controller', function () { + + var controller; + + beforeEach(function () { + controller = App.RAHighAvailabilityWizardStep3Controller.create(); + }); + + describe('#loadStep', function () { + + var dfd, + testCases = [ + { + path: 'isLoaded', + result: true + }, + { + path: 'selectedService.configs.length', + result: 1, + massage: 'configs length' + }, + { + path: 'selectedService.configs.firstObject.name', + result: 'policymgr_external_url', + message: 'property name' + }, + { + path: 'selectedService.configs.firstObject.category', + result: 'RANGER', + message: 'config category' + }, + { + path: 'selectedService.configs.firstObject.value', + result: 'http://localhost:1111', + message: 'property value' + } + ], + service = Em.Object.create({ + serviceName: 'RANGER', + displayName: 'Ranger' + }); + + beforeEach(function () { + dfd = $.Deferred(); + sinon.stub(App.get('router.mainController'), 'isLoading').returns(dfd); + sinon.stub(App.Service, 'find').returns([service]); + sinon.stub(App.config, 'get').withArgs('serviceByConfigTypeMap').returns({ + 'admin-properties': service + }); + sinon.stub(App.configsCollection, 'getConfigByName').returns({ + name: 'policymgr_external_url' + }); + controller.setProperties({ + wizardController: App.get('router.rAHighAvailabilityWizardController'), + content: { + loadBalancerURL: 'http://localhost:1111' + } + }); + controller.loadStep(); + dfd.resolve(); + }); + + afterEach(function () { + App.get('router.mainController.isLoading').restore(); + App.Service.find.restore(); + App.config.get.restore(); + App.configsCollection.getConfigByName.restore(); + }); + + testCases.forEach(function (testCase) { + + it(testCase.message || testCase.path, function () { + expect(controller.get(testCase.path)).to.equal(testCase.result); + }); + + }); + + }); + +}); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/304bd060/ambari-web/test/controllers/main/host/details_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/controllers/main/host/details_test.js b/ambari-web/test/controllers/main/host/details_test.js index 9efece0..57c81dd 100644 --- a/ambari-web/test/controllers/main/host/details_test.js +++ b/ambari-web/test/controllers/main/host/details_test.js @@ -500,125 +500,72 @@ describe('App.MainHostDetailsController', function () { }); describe('#addComponent()', function () { + var cases = [ + { + componentName: 'ZOOKEEPER_SERVER', + showAddComponentPopupCallCount: 1, + showConfirmationPopupCallCount: 0 + }, + { + componentName: 'RESOURCEMANAGER', + showAddComponentPopupCallCount: 1, + showConfirmationPopupCallCount: 0 + }, + { + componentName: 'JOURNALNODE', + showAddComponentPopupCallCount: 0, + showConfirmationPopupCallCount: 1 + }, + { + componentName: 'HIVE_CLIENT', + showAddComponentPopupCallCount: 1, + showConfirmationPopupCallCount: 0 + } + ]; beforeEach(function () { - sinon.spy(App, "showConfirmationPopup"); - sinon.stub(controller, "addClientComponent", Em.K); - sinon.stub(controller, "installHostComponentCall", Em.K); sinon.stub(controller, "checkComponentDependencies", Em.K); + sinon.stub(controller, "showAddComponentPopup", Em.K); + sinon.stub(controller, "clearConfigsChanges", Em.K); + sinon.stub(App, "showConfirmationPopup", Em.K); controller.set('content', { hostComponents: [Em.Object.create({ componentName: "HDFS_CLIENT" })] }); - controller.reopen({ - securityEnabled: false - }); }); afterEach(function () { - App.showConfirmationPopup.restore(); - controller.addClientComponent.restore(); - controller.installHostComponentCall.restore(); controller.checkComponentDependencies.restore(); + controller.showAddComponentPopup.restore(); + controller.clearConfigsChanges.restore(); + App.showConfirmationPopup.restore(); }); - it('add ZOOKEEPER_SERVER', function () { - var event = { - context: Em.Object.create({ - componentName: 'ZOOKEEPER_SERVER' - }) - }; - controller.addComponent(event); - expect(App.showConfirmationPopup.calledOnce).to.be.true; - }); - it('add WEBHCAT_SERVER', function () { - var event = { - context: Em.Object.create({ - componentName: 'WEBHCAT_SERVER' - }) - }; - controller.addComponent(event); - expect(App.showConfirmationPopup.calledOnce).to.be.true; - }); - it('add slave component', function () { - var event = { - context: Em.Object.create({ - componentName: 'HIVE_CLIENT' - }) - }; - controller.set('securityEnabled', false); - controller.addComponent(event); - expect(controller.addClientComponent.calledWith(Em.Object.create({ - componentName: 'HIVE_CLIENT' - }))).to.be.true; - }); - }); + cases.forEach(function (testCase) { - describe('#formatClientsMessage()', function () { - var testCases = [ - { - title: 'subComponentNames is null', - client: Em.Object.create({ - subComponentNames: null, - displayName: 'CLIENTS' - }), - result: 'CLIENTS' - }, - { - title: 'subComponentNames is empty', - client: Em.Object.create({ - subComponentNames: [], - displayName: 'CLIENTS' - }), - result: 'CLIENTS' - }, - { - title: 'displayName is null', - client: Em.Object.create({ - subComponentNames: ['DATANODE'], - displayName: null - }), - result: ' (DataNode)' - }, - { - title: 'displayName is CLIENTS', - client: Em.Object.create({ - subComponentNames: ['DATANODE'], - displayName: 'CLIENTS' - }), - result: 'CLIENTS (DataNode)' - } - ]; - testCases.forEach(function (test) { - it(test.title, function () { - expect(controller.formatClientsMessage(test.client)).to.equal(test.result); - }); - }); - }); + describe('add ' + testCase.componentName, function () { - describe('#addClientComponent()', function () { + beforeEach(function () { + var event = { + context: Em.Object.create({ + componentName: testCase.componentName + }) + }; + controller.addComponent(event); + }); - var component = Em.Object.create({ - componentName: ' Comp1' - }); + it('controller.showAddComponentPopup', function () { + expect(controller.showAddComponentPopup.callCount).to.equal(testCase.showAddComponentPopupCallCount); + }); - beforeEach(function () { - sinon.spy(controller, 'showAddComponentPopup'); - sinon.stub(controller, 'installHostComponentCall', Em.K); - }); + it('App.showConfirmationPopup', function () { + expect(App.showConfirmationPopup.callCount).to.equal(testCase.showConfirmationPopupCallCount); + }); - afterEach(function () { - controller.showAddComponentPopup.restore(); - controller.installHostComponentCall.restore(); - }); + }); - it('any CLIENT component', function () { - controller.set('content.hostName', 'host1'); - var popup = controller.addClientComponent(component); - expect(controller.showAddComponentPopup.calledOnce).to.be.true; - popup.onPrimary(); - expect(controller.installHostComponentCall.calledWith('host1', component)).to.be.true; }); + }); describe("#loadOozieConfigs()", function() { @@ -647,7 +594,7 @@ describe('App.MainHostDetailsController', function () { tag: 'tag' } } - }}); + }}, null, {}); var args = testHelpers.findAjaxRequest('name', 'admin.get.all_configurations'); expect(args[0]).exists; expect(args[0].sender).to.be.eql(controller); @@ -672,6 +619,7 @@ describe('App.MainHostDetailsController', function () { sinon.stub(controller, 'getStormNimbusHosts').returns("host1"); sinon.stub(controller, 'updateZkConfigs', Em.K); sinon.stub(controller, 'saveConfigsBatch', Em.K); + sinon.stub(controller, 'saveLoadedConfigs', Em.K); controller.set('nimbusHost', 'host2'); controller.onLoadStormConfigs(data); }); @@ -679,6 +627,7 @@ describe('App.MainHostDetailsController', function () { controller.getStormNimbusHosts.restore(); controller.updateZkConfigs.restore(); controller.saveConfigsBatch.restore(); + controller.saveLoadedConfigs.restore(); }); it("updateZkConfigs called with valid arguments", function() { expect(controller.updateZkConfigs.calledWith({'storm-site': { @@ -718,7 +667,7 @@ describe('App.MainHostDetailsController', function () { tag: 'tag' } } - }}); + }}, null, {}); var args = testHelpers.findAjaxRequest('name', 'admin.get.all_configurations'); expect(args[0]).exists; expect(args[0].sender).to.be.eql(controller); @@ -742,7 +691,7 @@ describe('App.MainHostDetailsController', function () { tag: 'tag' } } - }}); + }}, null, {}); var args = testHelpers.findAjaxRequest('name', 'admin.get.all_configurations'); expect(args[0]).exists; expect(args[0].sender).to.be.eql(controller); @@ -812,10 +761,8 @@ describe('App.MainHostDetailsController', function () { describe('#showAddComponentPopup()', function () { - var message = 'Comp1'; - beforeEach(function () { - sinon.spy(App.ModalPopup, 'show'); + sinon.stub(App.ModalPopup, 'show'); }); afterEach(function () { @@ -823,9 +770,8 @@ describe('App.MainHostDetailsController', function () { }); it('should display add component confirmation', function () { - var popup = controller.showAddComponentPopup(message, false, Em.K); + controller.showAddComponentPopup(Em.Object.create()); expect(App.ModalPopup.show.calledOnce).to.be.true; - expect(popup.get('addComponentMsg')).to.eql(Em.I18n.t('hosts.host.addComponent.msg').format(message)); }); }); @@ -1008,7 +954,7 @@ describe('App.MainHostDetailsController', function () { }); it('url params is empty', function () { - expect(controller.loadConfigsSuccessCallback()).to.be.false; + expect(controller.loadConfigsSuccessCallback(null, null, {})).to.be.false; var args = testHelpers.findAjaxRequest('name', 'reassign.load_configs'); expect(args).not.exists; }); @@ -1017,6 +963,12 @@ describe('App.MainHostDetailsController', function () { var args = testHelpers.findAjaxRequest('name', 'reassign.load_configs'); expect(args).exists; }); + it('isConfigsLoadingInProgress is false', function () { + mockUrlParams = []; + controller.set('isConfigsLoadingInProgress', true); + controller.loadConfigsSuccessCallback(null, null, {}); + expect(controller.get('isConfigsLoadingInProgress')).to.be.false; + }); }); describe('#saveZkConfigs()', function () { @@ -1074,6 +1026,7 @@ describe('App.MainHostDetailsController', function () { beforeEach(function () { sinon.stub(controller, 'saveConfigsBatch', Em.K); sinon.stub(controller, 'updateZkConfigs', Em.K); + sinon.stub(controller, 'saveLoadedConfigs', Em.K); sinon.stub(App.Service, 'find', function() { return [ Em.Object.create({ serviceName: 'HIVE' }), @@ -1090,77 +1043,78 @@ describe('App.MainHostDetailsController', function () { App.Service.find.restore(); controller.updateZkConfigs.restore(); controller.saveConfigsBatch.restore(); + controller.saveLoadedConfigs.restore(); }); - it('configs for YARN', function () { - var expected = { - properties: { - 'yarn-site': { - p: 'ys' - } - }, - properties_attributes: { - 'yarn-site': { - p: 'pa_ys' - } + it('configs for YARN', function () { + var expected = { + properties: { + 'yarn-site': { + p: 'ys' } - }; - expect(this.groups[1]).to.be.eql(expected); - }); + }, + properties_attributes: { + 'yarn-site': { + p: 'pa_ys' + } + } + }; + expect(this.groups[1]).to.be.eql(expected); + }); - it('configs for HIVE', function () { - var expected = { - "properties": { - "hive-site": { - "hs": "hs" - }, - "webhcat-site": { - "ws": "ws" - } + it('configs for HIVE', function () { + var expected = { + "properties": { + "hive-site": { + "hs": "hs" }, - "properties_attributes": { - "hive-site": { - "hs": "pa_hs" - }, - "webhcat-site": { - "ws": "pa_ws" - } + "webhcat-site": { + "ws": "ws" } - }; - expect(this.groups[0]).to.be.eql(expected); - }); - - it('configs for HBASE', function () { - var expected = { - "properties": { - "hbase-site": { - "hbs": "hbs" - } + }, + "properties_attributes": { + "hive-site": { + "hs": "pa_hs" }, - "properties_attributes": { - "hbase-site": { - "hbs": "pa_hbs" - } + "webhcat-site": { + "ws": "pa_ws" } - }; - expect(this.groups[2]).to.be.eql(expected); - }); + } + }; + expect(this.groups[0]).to.be.eql(expected); + }); - it('configs for ACCUMULO', function () { - var expected = { - "properties": { - "accumulo-site": { - "as": "as" - } - }, - "properties_attributes": { - "accumulo-site": { - "as": "pa_as" - } + it('configs for HBASE', function () { + var expected = { + "properties": { + "hbase-site": { + "hbs": "hbs" } - }; - expect(this.groups[3]).to.be.eql(expected); - }); + }, + "properties_attributes": { + "hbase-site": { + "hbs": "pa_hbs" + } + } + }; + expect(this.groups[2]).to.be.eql(expected); + }); + + it('configs for ACCUMULO', function () { + var expected = { + "properties": { + "accumulo-site": { + "as": "as" + } + }, + "properties_attributes": { + "accumulo-site": { + "as": "pa_as" + } + } + }; + expect(this.groups[3]).to.be.eql(expected); + }); }); @@ -1928,9 +1882,9 @@ describe('App.MainHostDetailsController', function () { expect(App.showConfirmationPopup.calledOnce).to.be.true; popup.onPrimary(); expect(controller.sendComponentCommand.calledWith( - controller.get('serviceNonClientActiveComponents'), - Em.I18n.t('hosts.host.maintainance.startAllComponents.context'), - App.HostComponentStatus.started) + controller.get('serviceNonClientActiveComponents'), + Em.I18n.t('hosts.host.maintainance.startAllComponents.context'), + App.HostComponentStatus.started) ).to.be.true; }); }); @@ -1966,9 +1920,9 @@ describe('App.MainHostDetailsController', function () { expect(App.showConfirmationPopup.calledOnce).to.be.true; popup.onPrimary(); expect(controller.sendComponentCommand.calledWith( - controller.get('serviceNonClientActiveComponents'), - Em.I18n.t('hosts.host.maintainance.stopAllComponents.context'), - App.HostComponentStatus.stopped) + controller.get('serviceNonClientActiveComponents'), + Em.I18n.t('hosts.host.maintainance.stopAllComponents.context'), + App.HostComponentStatus.stopped) ).to.be.true; }); it('serviceNonClientActiveComponents is correct, NAMENODE started', function () { @@ -2556,8 +2510,8 @@ describe('App.MainHostDetailsController', function () { describe('#_doDeleteHostComponent()', function () { it('single component', function () { controller.set('content.hostName', 'host1'); - var component = Em.Object.create({componentName: 'COMP'}); - controller._doDeleteHostComponent(component); + var componentName = 'COMP'; + controller._doDeleteHostComponent(componentName); var args = testHelpers.findAjaxRequest('name', 'common.delete.host_component'); expect(args[0]).exists; expect(args[0].data).to.be.eql({ @@ -2578,73 +2532,28 @@ describe('App.MainHostDetailsController', function () { }); describe('#_doDeleteHostComponentSuccessCallback()', function () { + var data = { + componentName: 'COMPONENT', + hostName: 'h1' + }; + beforeEach(function () { sinon.stub(controller, 'removeHostComponentModel', Em.K); - sinon.stub(controller, 'isServiceMetricsLoaded', function (callback) { - callback(); - }); - sinon.stub(controller, 'loadConfigs', Em.K); + controller.set('_deletedHostComponentResult', {}); + controller._doDeleteHostComponentSuccessCallback({}, {}, data); }); afterEach(function () { controller.removeHostComponentModel.restore(); - controller.isServiceMetricsLoaded.restore(); - controller.loadConfigs.restore(); }); - it('ZOOKEEPER_SERVER component', function () { - var data = { - componentName: 'ZOOKEEPER_SERVER' - }; - controller._doDeleteHostComponentSuccessCallback({}, {}, data); - expect(controller.get('_deletedHostComponentResult')).to.be.null; - expect(controller.get('fromDeleteZkServer')).to.be.true; - expect(controller.loadConfigs.calledOnce).to.be.true; - }); - it('Not ZOOKEEPER_SERVER component', function () { - var data = { - componentName: 'COMP' - }; - controller.set('fromDeleteZkServer', false); - controller._doDeleteHostComponentSuccessCallback({}, {}, data); + it('should reset `_deletedHostComponentResult`', function () { expect(controller.get('_deletedHostComponentResult')).to.be.null; - expect(controller.get('fromDeleteZkServer')).to.be.false; }); + it('should call `removeHostComponentModel` with correct params', function () { - var data = { - componentName: 'COMPONENT', - hostName: 'h1' - }; - controller._doDeleteHostComponentSuccessCallback({}, {}, data); expect(controller.removeHostComponentModel.calledWith('COMPONENT', 'h1')).to.be.true; }); - it('HIVE_METASTORE component', function () { - var data = { - componentName: 'HIVE_METASTORE' - }; - controller._doDeleteHostComponentSuccessCallback({}, {}, data); - expect(controller.get('_deletedHostComponentResult')).to.be.null; - expect(controller.get('deleteHiveMetaStore')).to.be.true; - expect(controller.loadConfigs.calledWith('loadHiveConfigs')).to.be.true; - }); - it('NIMBUS component', function () { - var data = { - componentName: 'NIMBUS' - }; - controller._doDeleteHostComponentSuccessCallback({}, {}, data); - expect(controller.get('_deletedHostComponentResult')).to.be.null; - expect(controller.get('deleteNimbusHost')).to.be.true; - expect(controller.loadConfigs.calledWith('loadStormConfigs')).to.be.true; - }); - it('RANGER_KMS_SERVER component', function () { - var data = { - componentName: 'RANGER_KMS_SERVER' - }; - controller._doDeleteHostComponentSuccessCallback({}, {}, data); - expect(controller.get('_deletedHostComponentResult')).to.be.null; - expect(controller.get('deleteRangerKMSServer')).to.be.true; - expect(controller.loadConfigs.calledWith('loadRangerConfigs')).to.be.true; - }); }); describe('#upgradeComponentSuccessCallback()', function () { @@ -2679,62 +2588,6 @@ describe('App.MainHostDetailsController', function () { }); }); - describe('#checkZkConfigs()', function () { - beforeEach(function () { - sinon.stub(controller, 'removeObserver'); - sinon.stub(controller, 'loadConfigs'); - sinon.stub(controller, 'isServiceMetricsLoaded', Em.clb); - this.stub = sinon.stub(App.router, 'get'); - }); - afterEach(function () { - controller.loadConfigs.restore(); - controller.removeObserver.restore(); - controller.isServiceMetricsLoaded.restore(); - this.stub.restore(); - }); - - it('No operations of ZOOKEEPER_SERVER', function () { - this.stub.withArgs('backgroundOperationsController.services').returns([]); - controller.checkZkConfigs(); - expect(controller.removeObserver.called).to.be.false; - expect(controller.loadConfigs.called).to.be.false; - }); - - it('Operation of ZOOKEEPER_SERVER running', function () { - this.stub.withArgs('backgroundOperationsController.services').returns([Em.Object.create({ - id: 1, - isRunning: true - })]); - controller.set('zkRequestId', 1); - controller.checkZkConfigs(); - expect(controller.removeObserver.called).to.be.false; - expect(controller.loadConfigs.called).to.be.false; - }); - - describe('Operation of ZOOKEEPER_SERVER finished', function () { - - beforeEach(function () { - this.stub.withArgs('backgroundOperationsController.services').returns([Em.Object.create({ - id: 1 - })]); - this.clock = sinon.useFakeTimers(); - controller.set('zkRequestId', 1); - controller.checkZkConfigs(); - }); - - afterEach(function () { - this.clock.restore(); - }); - - it('loadConfigs is called after `componentsUpdateInterval`', function () { - expect(controller.removeObserver.calledWith('App.router.backgroundOperationsController.serviceTimestamp', controller, controller.checkZkConfigs)).to.be.true; - this.clock.tick(App.get('componentsUpdateInterval')); - expect(controller.loadConfigs.calledOnce).to.be.true; - }); - - }); - }); - describe('#_doDeleteHostComponentErrorCallback()', function () { it('call showBackgroundOperationsPopup', function () { controller._doDeleteHostComponentErrorCallback({}, 'textStatus', {}, {url: 'url'}); @@ -2883,86 +2736,86 @@ describe('App.MainHostDetailsController', function () { describe('#installClients()', function () { var cases = [ - { - context: [ - Em.Object.create({ - componentName: 'c0', - workStatus: 'INSTALLED' - }), - Em.Object.create({ - componentName: 'c1', - workStatus: 'INIT' - }), - Em.Object.create({ - componentName: 'c2', - workStatus: 'INSTALL_FAILED' - }) - ], - dependencies: { - c0: [], - c1: [], - c2: [] - }, - getSecurityTypeCalled: null, //should have same value as getKDCSessionStateCalled, always - getKDCSessionStateCalled: true, - sendComponentCommandCalled: true, - showAlertPopupCalled: false, - title: 'No clients to add, some clients to install' + { + context: [ + Em.Object.create({ + componentName: 'c0', + workStatus: 'INSTALLED' + }), + Em.Object.create({ + componentName: 'c1', + workStatus: 'INIT' + }), + Em.Object.create({ + componentName: 'c2', + workStatus: 'INSTALL_FAILED' + }) + ], + dependencies: { + c0: [], + c1: [], + c2: [] }, - { - context: [ - Em.Object.create({ - componentName: 'c3', - displayName: 'c3' - }) - ], - dependencies: { - c3: [] - }, - getSecurityTypeCalled: null, //should have same value as getKDCSessionStateCalled, always - getKDCSessionStateCalled: true, - sendComponentCommandCalled: false, - showAlertPopupCalled: false, - title: 'No clients to install, some clients to add' + getSecurityTypeCalled: null, //should have same value as getKDCSessionStateCalled, always + getKDCSessionStateCalled: true, + sendComponentCommandCalled: true, + showAlertPopupCalled: false, + title: 'No clients to add, some clients to install' + }, + { + context: [ + Em.Object.create({ + componentName: 'c3', + displayName: 'c3' + }) + ], + dependencies: { + c3: [] }, - { - context: [ - Em.Object.create({ - componentName: 'c4', - displayName: 'c4' - }) - ], - dependencies: { - c4: ['c5'] - }, - getSecurityTypeCalled: null, //should have same value as getKDCSessionStateCalled, always - getKDCSessionStateCalled: false, - sendComponentCommandCalled: false, - showAlertPopupCalled: true, - title: 'Clients to add have unresolved dependencies' + getSecurityTypeCalled: null, //should have same value as getKDCSessionStateCalled, always + getKDCSessionStateCalled: true, + sendComponentCommandCalled: false, + showAlertPopupCalled: false, + title: 'No clients to install, some clients to add' + }, + { + context: [ + Em.Object.create({ + componentName: 'c4', + displayName: 'c4' + }) + ], + dependencies: { + c4: ['c5'] }, - { - context: [ - Em.Object.create({ - componentName: 'c5', - displayName: 'c5' - }), - Em.Object.create({ - componentName: 'c6', - displayName: 'c6' - }) - ], - dependencies: { - c5: ['c6'], - c6: ['c5'] - }, - getSecurityTypeCalled: null, //should have same value as getKDCSessionStateCalled, always - getKDCSessionStateCalled: true, - sendComponentCommandCalled: false, - showAlertPopupCalled: false, - title: 'Clients to add have mutual dependencies' - } - ]; + getSecurityTypeCalled: null, //should have same value as getKDCSessionStateCalled, always + getKDCSessionStateCalled: false, + sendComponentCommandCalled: false, + showAlertPopupCalled: true, + title: 'Clients to add have unresolved dependencies' + }, + { + context: [ + Em.Object.create({ + componentName: 'c5', + displayName: 'c5' + }), + Em.Object.create({ + componentName: 'c6', + displayName: 'c6' + }) + ], + dependencies: { + c5: ['c6'], + c6: ['c5'] + }, + getSecurityTypeCalled: null, //should have same value as getKDCSessionStateCalled, always + getKDCSessionStateCalled: true, + sendComponentCommandCalled: false, + showAlertPopupCalled: false, + title: 'Clients to add have mutual dependencies' + } + ]; beforeEach(function () { sinon.stub(controller, 'sendComponentCommand', Em.K); @@ -3096,9 +2949,7 @@ describe('App.MainHostDetailsController', function () { }); it('_doDeleteHostComponent is called with correct arguments', function () { - expect(controller._doDeleteHostComponent.calledWith(Em.Object.create({ - componentName: 'COMP1' - }))).to.be.true; + expect(controller._doDeleteHostComponent.calledWith('COMP1')).to.be.true; }); it('fromDeleteHost is true', function () { expect(controller.get('fromDeleteHost')).to.be.true; @@ -3429,11 +3280,13 @@ describe('App.MainHostDetailsController', function () { ]; beforeEach(function () { - sinon.spy(controller, 'saveConfigsBatch') + sinon.spy(controller, 'saveConfigsBatch'); + sinon.stub(controller, 'saveLoadedConfigs', Em.K); }); afterEach(function () { controller.saveConfigsBatch.restore(); + controller.saveLoadedConfigs.restore(); }); cases.forEach(function (item) { @@ -3510,43 +3363,6 @@ describe('App.MainHostDetailsController', function () { }); }); - describe("#updateStormConfigs()", function () { - beforeEach(function () { - this.serviceMock = sinon.stub(App.Service, 'find'); - sinon.stub(controller, 'loadConfigs'); - this.mock = sinon.stub(App, 'get') - }); - afterEach(function () { - this.serviceMock.restore(); - this.mock.restore(); - controller.loadConfigs.restore(); - }); - it("storm not installed, hadoop stack is 2.2", function () { - this.serviceMock.returns(Em.Object.create({ - isLoaded: false - })); - this.mock.returns(false); - controller.updateStormConfigs(); - expect(controller.loadConfigs.called).to.be.false; - }); - it("storm installed, hadoop stack is 2.2", function () { - this.serviceMock.returns(Em.Object.create({ - isLoaded: true - })); - this.mock.returns(false); - controller.updateStormConfigs(); - expect(controller.loadConfigs.called).to.be.false; - }); - it("storm installed, hadoop stack is 2.3", function () { - this.serviceMock.returns(Em.Object.create({ - isLoaded: true - })); - this.mock.returns(true); - controller.updateStormConfigs(); - expect(controller.loadConfigs.calledWith('loadStormConfigs')).to.be.true; - }); - }); - describe("#parseNnCheckPointTime", function () { var tests = [ { @@ -3714,10 +3530,13 @@ describe('App.MainHostDetailsController', function () { beforeEach(function() { sinon.stub(controller, 'saveConfigsBatch', Em.K); + sinon.stub(controller, 'saveLoadedConfigs', Em.K); + controller.set('configs', {}); }); afterEach(function() { controller.saveConfigsBatch.restore(); + controller.saveLoadedConfigs.restore(); }); var makeHostComponentModel = function(componentName, hostNames) { @@ -4054,4 +3873,237 @@ describe('App.MainHostDetailsController', function () { }); }); }); + + describe('#setConfigsChangesForDisplay', function () { + + var propertiesToChange = [ + { + propertyName: 'n0', + propertyFileName: 'f0' + }, + { + propertyName: 'n1', + propertyFileName: 'f1' + }, + { + propertyName: 'n2', + propertyFileName: 'f2' + }, + { + propertyName: 'n3', + propertyFileName: 'f3' + } + ], + result = { + recommendedPropertiesToChange: [ + { + propertyName: 'n0', + propertyFileName: 'f0', + saveRecommended: true + }, + { + propertyName: 'n3', + propertyFileName: 'f3', + saveRecommended: true + } + ], + requiredPropertiesToChange: [ + { + propertyName: 'n1', + propertyFileName: 'f1' + }, + { + propertyName: 'n2', + propertyFileName: 'f2' + } + ] + }; + + beforeEach(function () { + controller.setProperties({ + allPropertiesToChange: propertiesToChange, + recommendedPropertiesToChange: [], + requiredPropertiesToChange: [] + }); + sinon.stub(App.configsCollection, 'getConfigByName', function (propertyName) { + var map = { + n0: { + isEditable: true, + isReconfigurable: true + }, + n1: { + isEditable: true, + isReconfigurable: false + }, + n2: { + isEditable: false, + isReconfigurable: false + } + }; + return map[propertyName]; + }); + sinon.stub(App, 'get').withArgs('router.clusterController.isConfigsPropertiesLoaded').returns(true); + controller.set('isConfigsLoadingInProgress', true); + controller.setConfigsChangesForDisplay(); + }); + + afterEach(function () { + App.configsCollection.getConfigByName.restore(); + App.get.restore(); + }); + + it('editable changes', function () { + expect(controller.get('recommendedPropertiesToChange').toArray()).to.eql(result.recommendedPropertiesToChange); + }); + + it('non-editable changes', function () { + expect(controller.get('requiredPropertiesToChange').toArray()).to.eql(result.requiredPropertiesToChange); + }); + + it('isConfigsLoadingInProgress', function () { + expect(controller.get('isConfigsLoadingInProgress')).to.be.false; + }); + + }); + + describe('#clearConfigsChanges', function () { + + beforeEach(function () { + sinon.stub(controller, 'abortRequests', Em.K); + controller.setProperties({ + allPropertiesToChange: [{}], + recommendedPropertiesToChange: [{}], + requiredPropertiesToChange: [{}], + groupedPropertiesToChange: [{}], + isReconfigureRequired: true, + configs: {} + }); + }); + + afterEach(function () { + controller.abortRequests.restore(); + }); + + describe('default case', function () { + + beforeEach(function () { + controller.clearConfigsChanges(); + }); + + it('allPropertiesToChange', function () { + expect(controller.get('allPropertiesToChange')).to.have.length(0); + }); + + it('recommendedPropertiesToChange', function () { + expect(controller.get('recommendedPropertiesToChange')).to.have.length(0); + }); + + it('groupedPropertiesToChange', function () { + expect(controller.get('groupedPropertiesToChange')).to.have.length(0); + }); + + it('isReconfigureRequired', function () { + expect(controller.get('isReconfigureRequired')).to.be.false; + }); + + it('configs', function () { + expect(controller.get('configs')).to.be.null; + }); + + }); + + describe('no loaded configs cleanup', function () { + + beforeEach(function () { + controller.clearConfigsChanges(true); + }); + + it('configs shouldn\'t be cleared', function () { + expect(controller.get('configs')).to.not.be.null; + }); + + }); + + }); + + describe('#saveLoadedConfigs', function () { + + var data = { + items: [ + { + type: 't0', + properties: { + p0: 'v0', + p1: 'v1' + }, + properties_attributes: {} + }, + { + type: 't1', + properties: { + p2: 'v2', + p3: 'v3' + }, + properties_attributes: {} + } + ] + }; + + it('should store data in configs object', function () { + controller.set('configs', null); + controller.saveLoadedConfigs(data); + expect(controller.get('configs')).to.eql(data); + }); + + }); + + describe('#loadComponentRelatedConfigs', function () { + + var testCases = [ + { + isReconfigureRequired: true, + loadConfigsCallCount: 1, + isConfigsLoadingInProgress: true, + message: 'reconfigure required' + }, + { + isReconfigureRequired: false, + loadConfigsCallCount: 0, + isConfigsLoadingInProgress: false, + message: 'no reconfigure required' + } + ]; + + testCases.forEach(function (test) { + + describe(test.message, function () { + + beforeEach(function () { + sinon.stub(controller, 'isServiceMetricsLoaded', Em.clb); + sinon.stub(controller, 'loadConfigs', Em.K); + controller.setProperties({ + isReconfigureRequired: test.isReconfigureRequired, + isConfigsLoadingInProgress: false + }); + controller.loadComponentRelatedConfigs(); + }); + + afterEach(function () { + controller.isServiceMetricsLoaded.restore(); + controller.loadConfigs.restore(); + }); + + it('loadConfigs', function () { + expect(controller.loadConfigs.callCount).to.equal(test.loadConfigsCallCount); + }); + + it('isConfigsLoadingInProgress', function () { + expect(controller.get('isConfigsLoadingInProgress')).to.equal(test.isConfigsLoadingInProgress); + }); + + }); + + }); + + }); }); http://git-wip-us.apache.org/repos/asf/ambari/blob/304bd060/ambari-web/test/controllers/main/service/info/config_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/controllers/main/service/info/config_test.js b/ambari-web/test/controllers/main/service/info/config_test.js index 09772ff..874a104 100644 --- a/ambari-web/test/controllers/main/service/info/config_test.js +++ b/ambari-web/test/controllers/main/service/info/config_test.js @@ -535,20 +535,23 @@ describe("App.MainServiceInfoConfigsController", function () { beforeEach(function () { sinon.stub(Em.run, 'once', Em.K); sinon.stub(mainServiceInfoConfigsController, 'loadSelectedVersion'); - sinon.stub(mainServiceInfoConfigsController, 'clearRecommendationsInfo'); + sinon.spy(mainServiceInfoConfigsController, 'clearRecommendations'); + mainServiceInfoConfigsController.set('groupsToSave', { HDFS: 'my cool group'}); + mainServiceInfoConfigsController.set('recommendations', Em.A([{name: 'prop_1'}])); + mainServiceInfoConfigsController.doCancel(); }); afterEach(function () { Em.run.once.restore(); mainServiceInfoConfigsController.loadSelectedVersion.restore(); - mainServiceInfoConfigsController.clearRecommendationsInfo.restore(); + mainServiceInfoConfigsController.clearRecommendations.restore(); + }); + + it("should launch recommendations cleanup", function() { + expect(mainServiceInfoConfigsController.clearRecommendations.calledOnce).to.be.true; }); it("should clear dependent configs", function() { - mainServiceInfoConfigsController.set('groupsToSave', { HDFS: 'my cool group'}); - mainServiceInfoConfigsController.set('recommendations', Em.A([{name: 'prop_1'}])); - mainServiceInfoConfigsController.doCancel(); expect(App.isEmptyObject(mainServiceInfoConfigsController.get('recommendations'))).to.be.true; - expect(mainServiceInfoConfigsController.clearRecommendationsInfo.calledOnce).to.be.true; }); }); http://git-wip-us.apache.org/repos/asf/ambari/blob/304bd060/ambari-web/test/controllers/main/service/item_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/controllers/main/service/item_test.js b/ambari-web/test/controllers/main/service/item_test.js index 1b21b78..969305d 100644 --- a/ambari-web/test/controllers/main/service/item_test.js +++ b/ambari-web/test/controllers/main/service/item_test.js @@ -1416,6 +1416,7 @@ describe('App.MainServiceItemController', function () { sinon.stub(App.ModalPopup, 'show'); sinon.stub(App.format, 'role', function(name) {return name}); sinon.stub(mainServiceItemController, 'kerberosDeleteWarning'); + sinon.stub(mainServiceItemController, 'showLastWarning'); mainServiceItemController.reopen({ interDependentServices: [] @@ -1475,7 +1476,7 @@ describe('App.MainServiceItemController', function () { this.allowUninstallServices.returns(true); this.mockService.returns([Em.Object.create({workStatus: App.Service.statesMap.stopped}), Em.Object.create({workStatus: App.Service.statesMap.stopped})]); mainServiceItemController.deleteService('S1'); - expect(App.showConfirmationPopup.calledOnce).to.be.true; + expect(mainServiceItemController.showLastWarning.calledOnce).to.be.true; }); it("service has not dependent services, and install failed", function() { @@ -1483,7 +1484,7 @@ describe('App.MainServiceItemController', function () { this.allowUninstallServices.returns(true); this.mockService.returns([Em.Object.create({workStatus: App.Service.statesMap.install_failed}), Em.Object.create({workStatus: App.Service.statesMap.install_failed})]); mainServiceItemController.deleteService('S1'); - expect(App.showConfirmationPopup.calledOnce).to.be.true; + expect(mainServiceItemController.showLastWarning.calledOnce).to.be.true; }); it("service has not dependent services, and not stopped", function() { @@ -1707,29 +1708,27 @@ describe('App.MainServiceItemController', function () { beforeEach(function() { mainServiceItemController = App.MainServiceItemController.create({}); - sinon.stub(mainServiceItemController, 'loadConfigRecommendations', Em.K); + sinon.stub(mainServiceItemController, 'saveConfigs', Em.K); sinon.stub(mainServiceItemController, 'deleteServiceCall', Em.K); - sinon.stub(App.get('router.mainController'), 'isLoading').returns($.Deferred().resolve().promise()); mainServiceItemController.reopen({ interDependentServices: [] }) }); afterEach(function() { - mainServiceItemController.loadConfigRecommendations.restore(); + mainServiceItemController.saveConfigs.restore(); mainServiceItemController.deleteServiceCall.restore(); - App.get('router.mainController').isLoading.restore(); }); - it("loadConfigRecommendations should be called", function() { + it("saveConfigs should be called", function() { mainServiceItemController.deleteServiceCallSuccessCallback([], null, {}); expect(mainServiceItemController.deleteServiceCall.called).to.be.false; - expect(mainServiceItemController.loadConfigRecommendations.calledOnce).to.be.true; + expect(mainServiceItemController.saveConfigs.calledOnce).to.be.true; }); it("deleteServiceCall should be called", function() { mainServiceItemController.deleteServiceCallSuccessCallback([], null, {servicesToDeleteNext: true}); expect(mainServiceItemController.deleteServiceCall.calledOnce).to.be.true; - expect(mainServiceItemController.loadConfigRecommendations.called).to.be.false; + expect(mainServiceItemController.saveConfigs.called).to.be.false; }); }); http://git-wip-us.apache.org/repos/asf/ambari/blob/304bd060/ambari-web/test/controllers/main/service/reassign/step1_controller_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/controllers/main/service/reassign/step1_controller_test.js b/ambari-web/test/controllers/main/service/reassign/step1_controller_test.js index a43d91f..7dbf24a 100644 --- a/ambari-web/test/controllers/main/service/reassign/step1_controller_test.js +++ b/ambari-web/test/controllers/main/service/reassign/step1_controller_test.js @@ -33,7 +33,7 @@ describe('App.ReassignMasterWizardStep1Controller', function () { }); controller.set('_super', Em.K); - describe('#loadConfigTags', function() { + describe('#loadConfigsTags', function() { beforeEach(function() { this.stub = sinon.stub(App.router, 'get'); }); @@ -42,7 +42,7 @@ describe('App.ReassignMasterWizardStep1Controller', function () { this.stub.restore(); }); - it('tests loadConfigTags', function() { + it('tests loadConfigsTags', function() { controller.loadConfigsTags(); var args = testHelpers.findAjaxRequest('name', 'config.tags'); expect(args).exists; @@ -77,8 +77,11 @@ describe('App.ReassignMasterWizardStep1Controller', function () { }); it('tests getDatabaseHost', function() { - controller.set('content.serviceProperties', { - 'javax.jdo.option.ConnectionURL': "jdbc:mysql://c6401/hive?createDatabaseIfNotExist=true" + controller.set('content.configs', { + 'hive-site': { + 'javax.jdo.option.ConnectionURL': 'jdbc:mysql://c6401/hive?createDatabaseIfNotExist=true' + + } }); controller.set('content.reassign.service_id', 'HIVE'); @@ -108,7 +111,8 @@ describe('App.ReassignMasterWizardStep1Controller', function () { sinon.stub(controller, 'getDatabaseHost', Em.K); sinon.stub(controller, 'saveDatabaseType', Em.K); sinon.stub(controller, 'saveServiceProperties', Em.K); - + sinon.stub(controller, 'saveConfigs', Em.K); + reassignCtrl = App.router.reassignMasterController; reassignCtrl.set('content.hasManualSteps', true); }); @@ -117,12 +121,14 @@ describe('App.ReassignMasterWizardStep1Controller', function () { controller.getDatabaseHost.restore(); controller.saveDatabaseType.restore(); controller.saveServiceProperties.restore(); + controller.saveConfigs.restore(); }); it('should not set hasManualSteps to false for oozie with derby db', function() { var data = { items: [ { + type: 'oozie-site', properties: { 'oozie.service.JPAService.jdbc.driver': 'jdbc:derby:${oozie.data.dir}/${oozie.db.schema.name}-db;create=true' } @@ -141,6 +147,7 @@ describe('App.ReassignMasterWizardStep1Controller', function () { var data = { items: [ { + type: 'oozie-site', properties: { 'oozie.service.JPAService.jdbc.driver': 'mysql' } http://git-wip-us.apache.org/repos/asf/ambari/blob/304bd060/ambari-web/test/controllers/main/service/reassign/step3_controller_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/controllers/main/service/reassign/step3_controller_test.js b/ambari-web/test/controllers/main/service/reassign/step3_controller_test.js index e433f47..203d162 100644 --- a/ambari-web/test/controllers/main/service/reassign/step3_controller_test.js +++ b/ambari-web/test/controllers/main/service/reassign/step3_controller_test.js @@ -18,6 +18,8 @@ var App = require('app'); require('controllers/main/service/reassign/step3_controller'); +require('controllers/main/service/reassign_controller'); +var testHelpers = require('test/helpers'); var controller; describe('App.ReassignMasterWizardStep3Controller', function () { @@ -50,4 +52,636 @@ describe('App.ReassignMasterWizardStep3Controller', function () { expect(App.router.send.calledWith("next")).to.be.true; }); }); + + describe('#setAdditionalConfigs()', function () { + + beforeEach(function () { + sinon.stub(App, 'get').withArgs('isHaEnabled').returns(true); + }); + + afterEach(function () { + App.get.restore(); + }); + + it('Component is absent', function () { + controller.set('additionalConfigsMap', []); + var configs = {}; + + expect(controller.setAdditionalConfigs(configs, 'COMP1', '')).to.be.false; + expect(configs).to.eql({}); + }); + + it('configs for Hadoop 2 is present', function () { + controller.set('additionalConfigsMap', [ + { + componentName: 'COMP1', + configs: { + 'test-site': { + 'property1': '<replace-value>:1111' + } + }, + configs_Hadoop2: { + 'test-site': { + 'property2': '<replace-value>:2222' + } + } + } + ]); + var configs = { + 'test-site': {} + }; + + expect(controller.setAdditionalConfigs(configs, 'COMP1', 'host1')).to.be.true; + expect(configs).to.eql({ + 'test-site': { + 'property2': 'host1:2222' + } + }); + }); + + it('ignore some configs for NameNode after HA', function () { + controller.set('additionalConfigsMap', [ + { + componentName: 'NAMENODE', + configs: { + 'test-site': { + 'fs.defaultFS': '<replace-value>:1111', + 'dfs.namenode.rpc-address': '<replace-value>:1111' + } + } + } + ]); + var configs = {'test-site': {}}; + + expect(controller.setAdditionalConfigs(configs, 'NAMENODE', 'host1')).to.be.true; + expect(configs).to.eql({'test-site': {}}); + }); + }); + + describe('#getConfigUrlParams()', function () { + var testCases = [ + { + componentName: 'NAMENODE', + result: [ + "(type=hdfs-site&tag=1)", + "(type=core-site&tag=2)" + ] + }, + { + componentName: 'SECONDARY_NAMENODE', + result: [ + "(type=hdfs-site&tag=1)", + "(type=core-site&tag=2)" + ] + }, + { + componentName: 'JOBTRACKER', + result: [ + "(type=mapred-site&tag=4)" + ] + }, + { + componentName: 'RESOURCEMANAGER', + result: [ + "(type=yarn-site&tag=5)" + ] + }, + { + componentName: 'APP_TIMELINE_SERVER', + result: [ + "(type=yarn-site&tag=5)", + "(type=yarn-env&tag=8)" + ] + }, + { + componentName: 'OOZIE_SERVER', + result: [ + "(type=oozie-site&tag=6)", + "(type=core-site&tag=2)", + "(type=oozie-env&tag=2)" + ] + }, + { + componentName: 'WEBHCAT_SERVER', + result: [ + "(type=hive-env&tag=11)", + "(type=webhcat-site&tag=7)", + "(type=core-site&tag=2)" + ] + }, + { + componentName: 'HIVE_SERVER', + result: [ + '(type=hive-site&tag=10)', + '(type=webhcat-site&tag=7)', + '(type=hive-env&tag=11)', + '(type=core-site&tag=2)' + ] + }, + { + componentName: 'HIVE_METASTORE', + result: [ + '(type=hive-site&tag=10)', + '(type=webhcat-site&tag=7)', + '(type=hive-env&tag=11)', + '(type=core-site&tag=2)' + ] + }, + { + componentName: 'MYSQL_SERVER', + result: [ + '(type=hive-site&tag=10)' + ] + }, + { + componentName: 'HISTORYSERVER', + result: [ + '(type=mapred-site&tag=4)' + ] + } + ]; + + var data = { + Clusters: { + desired_configs: { + 'hdfs-site': {tag: 1}, + 'core-site': {tag: 2}, + 'hbase-site': {tag: 3}, + 'mapred-site': {tag: 4}, + 'yarn-site': {tag: 5}, + 'oozie-site': {tag: 6}, + 'oozie-env': {tag: 2}, + 'webhcat-site': {tag: 7}, + 'yarn-env': {tag: 8}, + 'accumulo-site': {tag: 9}, + 'hive-site': {tag: 10}, + 'hive-env': {tag: 11} + } + } + }; + + var services = []; + + beforeEach(function () { + controller.set('wizardController', App.get('router.reassignMasterController')); + sinon.stub(App.Service, 'find', function () { + return services; + }); + }); + afterEach(function () { + App.Service.find.restore(); + }); + + testCases.forEach(function (test) { + it('get config of ' + test.componentName, function () { + expect(controller.getConfigUrlParams(test.componentName, data)).to.eql(test.result); + }); + }); + it('get config of NAMENODE when HBASE installed', function () { + services = [ + { + serviceName: 'HBASE' + } + ]; + expect(controller.getConfigUrlParams('NAMENODE', data)).to.eql([ + "(type=hdfs-site&tag=1)", + "(type=core-site&tag=2)", + "(type=hbase-site&tag=3)" + ]); + }); + + it('get config of NAMENODE when ACCUMULO installed', function () { + services = [ + { + serviceName: 'ACCUMULO' + } + ]; + expect(controller.getConfigUrlParams('NAMENODE', data)).to.eql([ + "(type=hdfs-site&tag=1)", + "(type=core-site&tag=2)", + "(type=accumulo-site&tag=9)" + ]); + }); + + }); + + describe('#onLoadConfigsTags()', function () { + var dummyData = { + Clusters: { + desired_configs : {} + } + }; + + beforeEach(function () { + sinon.stub(controller, 'getConfigUrlParams', function () { + return []; + }); + controller.set('content', { + reassign: { + component_name: 'COMP1' + } + }); + controller.onLoadConfigsTags(dummyData); + this.args = testHelpers.findAjaxRequest('name', 'reassign.load_configs'); + }); + + afterEach(function () { + controller.getConfigUrlParams.restore(); + }); + + it('request is sent', function () { + expect(this.args).exists; + }); + + it('getConfigUrlParams is called with correct data', function () { + expect(controller.getConfigUrlParams.calledWith('COMP1', dummyData)).to.be.true; + }); + }); + + describe('#setSecureConfigs()', function () { + + beforeEach(function () { + this.stub = sinon.stub(App, 'get'); + }); + + afterEach(function () { + Em.tryInvoke(App.get, 'restore'); + }); + + it('undefined component and security disabled', function () { + var secureConfigs = []; + this.stub.withArgs('isKerberosEnabled').returns(false); + controller.set('secureConfigsMap', []); + expect(controller.setSecureConfigs(secureConfigs, {}, 'COMP1')).to.be.false; + expect(secureConfigs).to.eql([]); + }); + + it('component exist and security disabled', function () { + var secureConfigs = []; + this.stub.withArgs('isKerberosEnabled').returns(false); + controller.set('secureConfigsMap', [{ + componentName: 'COMP1' + }]); + expect(controller.setSecureConfigs(secureConfigs, {}, 'COMP1')).to.be.false; + expect(secureConfigs).to.eql([]); + }); + + it('undefined component and security enabled', function () { + var secureConfigs = []; + this.stub.withArgs('isKerberosEnabled').returns(true); + controller.set('secureConfigsMap', []); + expect(controller.setSecureConfigs(secureConfigs, {}, 'COMP1')).to.be.false; + expect(secureConfigs).to.eql([]); + }); + it('component exist and security enabled', function () { + var secureConfigs = []; + this.stub.withArgs('isKerberosEnabled').returns(true); + var configs = {'s1': { + 'k1': 'kValue', + 'p1': 'pValue' + }}; + controller.set('secureConfigsMap', [{ + componentName: 'COMP1', + configs: [{ + site: 's1', + keytab: 'k1', + principal: 'p1' + }] + }]); + expect(controller.setSecureConfigs(secureConfigs, configs, 'COMP1')).to.be.true; + expect(secureConfigs).to.eql([ + { + "keytab": "kValue", + "principal": "pValue" + } + ]); + }); + }); + + describe('#setDynamicCinfigs()', function () { + + describe('HIVE', function() { + beforeEach(function () { + controller.set('content', Em.Object.create({ + masterComponentHosts: [ + { + component: 'HIVE_METASTORE', + hostName: 'host1' + }, + { + component: 'HIVE_METASTORE', + hostName: 'host3' + }, + { + component: 'HIVE_SERVER', + hostName: 'host4' + } + ], + reassignHosts: { + source: 'host1', + target: 'host2' + } + })); + }); + it("reassign component is HIVE_METASTORE", function() { + var configs = { + 'hive-env': { + 'hive_user': 'hive_user' + }, + 'hive-site': { + 'hive.metastore.uris': '' + }, + 'webhcat-site': { + 'templeton.hive.properties': 'thrift' + }, + 'core-site': { + 'hadoop.proxyuser.hive_user.hosts': '' + } + }; + App.MoveHmConfigInitializer.setup(controller._getHiveInitializerSettings(configs)); + configs = controller.setDynamicConfigs(configs, App.MoveHmConfigInitializer); + expect(configs['hive-site']['hive.metastore.uris']).to.equal('thrift://host3:9083,thrift://host2:9083'); + expect(configs['webhcat-site']['templeton.hive.properties']).to.equal('thrift'); + expect(configs['core-site']['hadoop.proxyuser.hive_user.hosts']).to.equal('host2,host3,host4'); + }); + + it("reassign component is HIVE_SERVER", function() { + controller.get('content.masterComponentHosts').pushObject({component: 'HIVE_SERVER', hostName: 'host1'}); + var configs = { + 'hive-env': { + 'hive_user': 'hive_user' + }, + 'hive-site': { + 'hive.metastore.uris': '' + }, + 'webhcat-site': { + 'templeton.hive.properties': 'thrift' + }, + 'core-site': { + 'hadoop.proxyuser.hive_user.hosts': '' + } + }; + App.MoveHsConfigInitializer.setup(controller._getHiveInitializerSettings(configs)); + configs = controller.setDynamicConfigs(configs, App.MoveHsConfigInitializer); + expect(configs['core-site']['hadoop.proxyuser.hive_user.hosts']).to.equal('host1,host2,host3,host4'); + }); + + it("reassign component is WEBHCAT_SERVER", function() { + controller.get('content.masterComponentHosts').pushObject({component: 'WEBHCAT_SERVER', hostName: 'host1'}); + var configs = { + 'hive-env': { + 'webhcat_user': 'webhcat_user' + }, + 'hive-site': { + 'hive.metastore.uris': '' + }, + 'webhcat-site': { + 'templeton.hive.properties': 'thrift' + }, + 'core-site': { + 'hadoop.proxyuser.webhcat_user.hosts': '' + } + }; + App.MoveWsConfigInitializer.setup(controller._getWsInitializerSettings(configs)); + configs = controller.setDynamicConfigs(configs, App.MoveWsConfigInitializer); + expect(configs['core-site']['hadoop.proxyuser.webhcat_user.hosts']).to.equal('host2'); + }); + }); + + describe('RESOURCEMANAGER', function () { + beforeEach(function () { + sinon.stub(App, 'get').withArgs('isRMHaEnabled').returns(true); + }); + afterEach(function () { + App.get.restore(); + App.MoveRmConfigInitializer.cleanup(); + }); + + it('HA enabled and resource manager 1', function () { + controller.set('content', Em.Object.create({ + reassignHosts: { + source: 'host1', + target: 'host3' + } + })); + var configs = { + 'yarn-site': { + 'yarn.resourcemanager.hostname.rm1': 'host1', + 'yarn.resourcemanager.webapp.address.rm1': 'host1:8088', + 'yarn.resourcemanager.webapp.https.address.rm1': 'host1:8443', + 'yarn.resourcemanager.hostname.rm2': 'host2', + 'yarn.resourcemanager.webapp.address.rm2': 'host2:8088', + 'yarn.resourcemanager.webapp.https.address.rm2': 'host2:8443' + } + }; + var additionalDependencies = controller._getRmAdditionalDependencies(configs); + App.MoveRmConfigInitializer.setup(controller._getRmInitializerSettings(configs)); + configs = controller.setDynamicConfigs(configs, App.MoveRmConfigInitializer, additionalDependencies); + expect(configs['yarn-site']).to.eql({ + 'yarn.resourcemanager.hostname.rm1': 'host3', + 'yarn.resourcemanager.webapp.address.rm1': 'host3:8088', + 'yarn.resourcemanager.webapp.https.address.rm1': 'host3:8443', + 'yarn.resourcemanager.hostname.rm2': 'host2', + 'yarn.resourcemanager.webapp.address.rm2': 'host2:8088', + 'yarn.resourcemanager.webapp.https.address.rm2': 'host2:8443' + }); + }); + + it('HA enabled and resource manager 2', function () { + controller.set('content', Em.Object.create({ + reassignHosts: { + source: 'host2', + target: 'host3' + } + })); + var configs = { + 'yarn-site': { + 'yarn.resourcemanager.hostname.rm1': 'host1', + 'yarn.resourcemanager.webapp.address.rm1': 'host1:8088', + 'yarn.resourcemanager.webapp.https.address.rm1': 'host1:8443', + 'yarn.resourcemanager.hostname.rm2': 'host2', + 'yarn.resourcemanager.webapp.address.rm2': 'host2:8088', + 'yarn.resourcemanager.webapp.https.address.rm2': 'host2:8443' + } + }; + var additionalDependencies = controller._getRmAdditionalDependencies(configs); + App.MoveRmConfigInitializer.setup(controller._getRmInitializerSettings(configs)); + configs = controller.setDynamicConfigs(configs, App.MoveRmConfigInitializer, additionalDependencies); + + expect(configs['yarn-site']).to.eql({ + 'yarn.resourcemanager.hostname.rm1': 'host1', + 'yarn.resourcemanager.webapp.address.rm1': 'host1:8088', + 'yarn.resourcemanager.webapp.https.address.rm1': 'host1:8443', + 'yarn.resourcemanager.hostname.rm2': 'host3', + 'yarn.resourcemanager.webapp.address.rm2': 'host3:8088', + 'yarn.resourcemanager.webapp.https.address.rm2': 'host3:8443' + }); + }); + }); + + describe('NAMENODE', function () { + var isHaEnabled = false; + + beforeEach(function () { + sinon.stub(App, 'get', function () { + return isHaEnabled; + }); + sinon.stub(App.Service, 'find', function () { + return [ + {serviceName: 'HDFS'}, + {serviceName: 'ACCUMULO'}, + {serviceName: 'HBASE'}, + {serviceName: 'HAWQ'} + ]; + }); + controller.set('content', Em.Object.create({ + reassignHosts: { + source: 'host1' + } + })); + }); + + afterEach(function () { + App.get.restore(); + App.Service.find.restore(); + App.MoveNameNodeConfigInitializer.cleanup(); + }); + + it('HA isn\'t enabled and HBASE, HAWQ and ACCUMULO service', function () { + isHaEnabled = false; + var configs = { + 'hbase-site': { + 'hbase.rootdir': 'hdfs://localhost:8020/apps/hbase/data' + }, + 'accumulo-site': { + 'instance.volumes': 'hdfs://localhost:8020/apps/accumulo/data', + 'instance.volumes.replacements': '' + }, + 'hawq-site': { + 'hawq_dfs_url': 'localhost:8020/hawq/data' + } + }; + + controller.set('content.reassignHosts.target', 'host2'); + + App.MoveNameNodeConfigInitializer.setup(controller._getNnInitializerSettings(configs)); + configs = controller.setDynamicConfigs(configs, App.MoveNameNodeConfigInitializer); + + expect(configs['hbase-site']['hbase.rootdir']).to.equal('hdfs://host2:8020/apps/hbase/data'); + expect(configs['accumulo-site']['instance.volumes']).to.equal('hdfs://host2:8020/apps/accumulo/data'); + expect(configs['accumulo-site']['instance.volumes.replacements']).to.equal('hdfs://host1:8020/apps/accumulo/data hdfs://host2:8020/apps/accumulo/data'); + expect(configs['hawq-site'].hawq_dfs_url).to.equal('host2:8020/hawq/data'); + }); + + it('HA enabled and namenode 1', function () { + isHaEnabled = true; + var configs = { + 'hdfs-site': { + 'dfs.nameservices': 's', + 'dfs.namenode.http-address.s.nn1': 'host1:50070', + 'dfs.namenode.https-address.s.nn1': 'host1:50470', + 'dfs.namenode.rpc-address.s.nn1': 'host1:8020' + }, + 'hdfs-client': { + 'dfs.namenode.rpc-address.s.nn1': '', + 'dfs.namenode.http-address.s.nn1': 'host1:50070' + } + }; + + controller.set('content.reassignHosts.target', 'host2'); + App.MoveNameNodeConfigInitializer.setup(controller._getNnInitializerSettings(configs)); + configs = controller.setDynamicConfigs(configs, App.MoveNameNodeConfigInitializer); + expect(configs['hdfs-site']).to.eql({ + "dfs.nameservices": "s", + "dfs.namenode.http-address.s.nn1": "host2:50070", + "dfs.namenode.https-address.s.nn1": "host2:50470", + "dfs.namenode.rpc-address.s.nn1": "host2:8020" + }); + expect(configs['hdfs-client']).to.eql({ + "dfs.namenode.http-address.s.nn1": "host2:50070", + "dfs.namenode.rpc-address.s.nn1": "host2:8020" + }); + }); + + it('HA enabled and namenode 2', function () { + isHaEnabled = true; + var configs = { + 'hdfs-site': { + 'dfs.nameservices': 's', + "dfs.namenode.http-address.s.nn1": "host1:50070", + 'dfs.namenode.http-address.s.nn2': 'host2:50070', + 'dfs.namenode.https-address.s.nn2': 'host2:50470', + 'dfs.namenode.rpc-address.s.nn2': 'host2:8020' + }, + 'hdfs-client': { + 'dfs.namenode.rpc-address.s.nn2': '', + 'dfs.namenode.http-address.s.nn2': 'host2:50070' + } + }; + controller.set('content.reassignHosts.source', 'host2'); + controller.set('content.reassignHosts.target', 'host3'); + + App.MoveNameNodeConfigInitializer.setup(controller._getNnInitializerSettings(configs)); + configs = controller.setDynamicConfigs(configs, App.MoveNameNodeConfigInitializer); + + expect(configs['hdfs-site']).to.eql({ + "dfs.nameservices": "s", + "dfs.namenode.http-address.s.nn1": "host1:50070", + "dfs.namenode.http-address.s.nn2": "host3:50070", + "dfs.namenode.https-address.s.nn2": "host3:50470", + "dfs.namenode.rpc-address.s.nn2": "host3:8020" + }); + expect(configs['hdfs-client']).to.eql({ + "dfs.namenode.http-address.s.nn2": "host3:50070", + "dfs.namenode.rpc-address.s.nn2": "host3:8020" + }); + }); + + }); + + describe('OOZIE_SERVER', function () { + + it('should upodate hadoop.proxyuser.${oozie_user}.hosts', function () { + + var configs = { + 'oozie-env': { + 'oozie_user': 'cool_dude' + }, + 'core-site': { + 'hadoop.proxyuser.cool_dude.hosts': '' + } + }; + + controller.set('content', Em.Object.create({ + masterComponentHosts: [ + { + component: 'OOZIE_SERVER', + hostName: 'host2' + }, + { + component: 'OOZIE_SERVER', + hostName: 'host3' + }, + { + component: 'OOZIE_SERVER', + hostName: 'host1' + } + ], + reassignHosts: { + source: 'host1', + target: 'host4' + } + })); + + App.MoveOSConfigInitializer.setup(controller._getOsInitializerSettings(configs)); + configs = controller.setDynamicConfigs(configs, App.MoveOSConfigInitializer); + App.MoveOSConfigInitializer.cleanup(); + + expect(configs['core-site']['hadoop.proxyuser.cool_dude.hosts']).to.equal('host2,host3,host4'); + + }); + + }); + + }); });
