Repository: ambari Updated Branches: refs/heads/trunk a60d8608b -> 4b962fabc
AMBARI-5405 Cover main app 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/4b962fab Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/4b962fab Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/4b962fab Branch: refs/heads/trunk Commit: 4b962fabc8b141fa6805aae8fd8865f3dcd3493e Parents: a60d860 Author: atkach <atk...@hortonworks.com> Authored: Wed Apr 9 15:32:30 2014 +0300 Committer: atkach <atk...@hortonworks.com> Committed: Wed Apr 9 15:32:30 2014 +0300 ---------------------------------------------------------------------- ambari-web/app/app.js | 62 +++-- ambari-web/app/assets/test/tests.js | 14 +- ambari-web/app/utils/ajax.js | 2 +- .../app/views/main/service/info/summary.js | 8 +- ambari-web/test/app_test.js | 264 +++++++++++++++++++ ambari-web/test/init_model_test.js | 34 +++ .../views/main/service/info/summary_test.js | 105 ++++++++ 7 files changed, 442 insertions(+), 47 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/4b962fab/ambari-web/app/app.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/app.js b/ambari-web/app/app.js index fb4476a..aa1f909 100644 --- a/ambari-web/app/app.js +++ b/ambari-web/app/app.js @@ -80,7 +80,7 @@ module.exports = Em.Application.create({ isHaEnabled: function() { if (!this.get('isHadoop2Stack')) return false; return !this.HostComponent.find().someProperty('componentName', 'SECONDARY_NAMENODE'); - }.property('router.clusterController.isLoaded'), + }.property('router.clusterController.isLoaded', 'isHadoop2Stack'), /** * List of disabled components for the current stack with related info. @@ -167,57 +167,65 @@ module.exports = Em.Application.create({ var reviewConfigsService = require('data/review_configs') .findProperty('config_name', 'services').config_value .findProperty('service_name', component.get('serviceName')); - reviewConfigsService.set('service_components', reviewConfigsService.get('service_components').filter(function (serviceComponent) { - if (serviceComponent.get('component_name') != component.get('componentName')) { - return true; - } else { - componentCopy.set('reviewConfigs', serviceComponent); - return false; - } - })); + //review_configs might not contain particular service + if (reviewConfigsService) { + reviewConfigsService.set('service_components', reviewConfigsService.get('service_components').filter(function (serviceComponent) { + if (serviceComponent.get('component_name') != component.get('componentName')) { + return true; + } else { + componentCopy.set('reviewConfigs', serviceComponent); + return false; + } + })); + } return componentCopy; }, /** - * Resolve dependency in components. Check forbidden/allowed components and + * Resolve dependency in components. + * if component with config category from "data/service_configs" doesn't match components from stack + * then disable it and push to stackDependedComponents + * otherwise enable component and remove it from stackDependedComponents + * Check forbidden/allowed components and * remove/restore related data. */ - handleStackDependedComponents: function() { + handleStackDependedComponents: function () { // need for unit testing and test mode if (this.get('handleStackDependencyTest') || this.testMode) return; - var stackDependedComponents = []; + var stackDependedComponents = this.get('stackDependedComponents'); var service_configs = require('data/service_configs'); var stackServiceComponents = this.StackServiceComponent.find(); if (!stackServiceComponents.mapProperty('componentName').length) { - return; + return; } // disable components - service_configs.forEach(function(service){ - service.configCategories.forEach(function(serviceConfigCategory){ + service_configs.forEach(function (service) { + service.configCategories.forEach(function (serviceConfigCategory) { var categoryComponents = serviceConfigCategory.get('hostComponentNames'); if (categoryComponents && categoryComponents.length) { - categoryComponents.forEach(function(categoryComponent) { - var stackComponent = stackServiceComponents.findProperty('componentName',categoryComponent); - if(!stackComponent && !this.get('stackDependedComponents').mapProperty('componentName').contains['categoryComponent'] ) { + categoryComponents.forEach(function (categoryComponent) { + var stackComponent = stackServiceComponents.findProperty('componentName', categoryComponent); + if (!stackComponent && !stackDependedComponents.mapProperty('componentName').contains['categoryComponent']) { var _stackComponent = Ember.Object.create({ componentName: categoryComponent, - serviceName:service.serviceName + serviceName: service.serviceName }); stackDependedComponents.push(this.disableComponent(_stackComponent)); } - },this); + }, this); } - },this); - },this); + }, this); + }, this); + // enable components - if (this.get('stackDependedComponents').length > 0) { - this.get('stackDependedComponents').forEach(function(component) { - if (stackServiceComponents.findProperty('componentName',component.get('componentName'))) { + if (stackDependedComponents.length > 0) { + stackDependedComponents.forEach(function (component) { + if (stackServiceComponents.someProperty('componentName', component.get('componentName'))) { this.enableComponent(component); - stackDependedComponents = this.get('stackDependedComponents').removeObject(component); + stackDependedComponents.removeObject(component); } }, this); } - this.set('stackDependedComponents', this.get('stackDependedComponents').concat(stackDependedComponents)); + this.set('stackDependedComponents', stackDependedComponents); }, /** http://git-wip-us.apache.org/repos/asf/ambari/blob/4b962fab/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 478561e..4390c02 100644 --- a/ambari-web/app/assets/test/tests.js +++ b/ambari-web/app/assets/test/tests.js @@ -18,19 +18,7 @@ var App = require('app'); -require('models/stack_service_component'); -require('mappers/server_data_mapper'); -require('mappers/stack_service_component_mapper'); - - var a = require('test/service_components'); - var r = Em.A([]); - a.items.forEach(function(i) { - i.serviceComponents.forEach(function(sc) { - r.pushObject(sc.StackServiceComponents); - }); - }); - App.stackServiceComponentMapper.map({items: r}); - +require('test/init_model_test'); require('test/app_test'); require('test/data/HDP2/site_properties_test'); require('test/controllers/global/background_operations_test'); http://git-wip-us.apache.org/repos/asf/ambari/blob/4b962fab/ambari-web/app/utils/ajax.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/utils/ajax.js b/ambari-web/app/utils/ajax.js index cad1c3e..496d0c1 100644 --- a/ambari-web/app/utils/ajax.js +++ b/ambari-web/app/utils/ajax.js @@ -1232,7 +1232,7 @@ var urls = { }, 'wizard.service_components': { 'real': '{stackUrl}/stackServices?fields=StackServices/comments,StackServices/service_version,serviceComponents/*', - 'mock': '/data/wizard/stacks/HDP-2.1/service_components.json', + 'mock': '/data/stacks/HDP-2.1/service_components.json', 'format': function(data) { return { timeout: 10000, http://git-wip-us.apache.org/repos/asf/ambari/blob/4b962fab/ambari-web/app/views/main/service/info/summary.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/main/service/info/summary.js b/ambari-web/app/views/main/service/info/summary.js index ba4acb0..821261f 100644 --- a/ambari-web/app/views/main/service/info/summary.js +++ b/ambari-web/app/views/main/service/info/summary.js @@ -16,6 +16,7 @@ */ var App = require('app'); +require('views/main/dashboard/service'); App.AlertItemView = Em.View.extend({ tagName:"li", @@ -417,12 +418,7 @@ App.MainServiceInfoSummaryView = Em.View.extend({ * Alerts panel not display for PIG, SQOOP and TEZ Service */ isNoAlertsService: function () { - var serviceName = this.get('service.serviceName'); - if (!serviceName) { - return false; - } - var noAlertsServices = ['PIG', 'SQOOP', 'TEZ']; - return noAlertsServices.indexOf(serviceName) > -1; + return !!this.get('service.serviceName') && ['PIG', 'SQOOP', 'TEZ'].contains(this.get('service.serviceName')); }.property(''), gangliaUrl:function () { http://git-wip-us.apache.org/repos/asf/ambari/blob/4b962fab/ambari-web/test/app_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/app_test.js b/ambari-web/test/app_test.js index 106f4ad..2a97a3f 100644 --- a/ambari-web/test/app_test.js +++ b/ambari-web/test/app_test.js @@ -17,6 +17,9 @@ */ var App = require('app'); +require('views/common/quick_view_link_view'); +require('models/host_component'); +require('models/stack_service_component'); describe('#App', function() { @@ -120,4 +123,265 @@ describe('#App', function() { }); }); }); + + describe('#stackVersionURL', function () { + + App.QuickViewLinks.reopen({ + loadTags: function () {} + }); + + var testCases = [ + { + title: 'if currentStackVersion and defaultStackVersion are empty then stackVersionURL should contain prefix', + currentStackVersion: '', + defaultStackVersion: '', + result: '/stacks/HDP/version/' + }, + { + title: 'if currentStackVersion is "HDP-1.3.1" then stackVersionURL should be "/stacks/HDP/version/1.3.1"', + currentStackVersion: 'HDP-1.3.1', + defaultStackVersion: '', + result: '/stacks/HDP/version/1.3.1' + }, + { + title: 'if defaultStackVersion is "HDP-1.3.1" then stackVersionURL should be "/stacks/HDP/version/1.3.1"', + currentStackVersion: '', + defaultStackVersion: 'HDP-1.3.1', + result: '/stacks/HDP/version/1.3.1' + }, + { + title: 'if defaultStackVersion and currentStackVersion are different then stackVersionURL should have currentStackVersion value', + currentStackVersion: 'HDP-1.3.2', + defaultStackVersion: 'HDP-1.3.1', + result: '/stacks/HDP/version/1.3.2' + }, + { + title: 'if defaultStackVersion is "HDPLocal-1.3.1" then stackVersionURL should be "/stacks/HDPLocal/version/1.3.1"', + currentStackVersion: '', + defaultStackVersion: 'HDPLocal-1.3.1', + result: '/stacks/HDPLocal/version/1.3.1' + }, + { + title: 'if currentStackVersion is "HDPLocal-1.3.1" then stackVersionURL should be "/stacks/HDPLocal/version/1.3.1"', + currentStackVersion: 'HDPLocal-1.3.1', + defaultStackVersion: '', + result: '/stacks/HDPLocal/version/1.3.1' + } + ]; + + testCases.forEach(function (test) { + it(test.title, function () { + App.set('currentStackVersion', test.currentStackVersion); + App.set('defaultStackVersion', test.defaultStackVersion); + expect(App.get('stackVersionURL')).to.equal(test.result); + App.set('currentStackVersion', "HDP-1.2.2"); + App.set('defaultStackVersion', "HDP-1.2.2"); + }); + }); + }); + + describe('#stack2VersionURL', function () { + + var testCases = [ + { + title: 'if currentStackVersion and defaultStackVersion are empty then stack2VersionURL should contain prefix', + currentStackVersion: '', + defaultStackVersion: '', + result: '/stacks2/HDP/versions/' + }, + { + title: 'if currentStackVersion is "HDP-1.3.1" then stack2VersionURL should be "/stacks2/HDP/versions/1.3.1"', + currentStackVersion: 'HDP-1.3.1', + defaultStackVersion: '', + result: '/stacks2/HDP/versions/1.3.1' + }, + { + title: 'if defaultStackVersion is "HDP-1.3.1" then stack2VersionURL should be "/stacks/HDP/versions/1.3.1"', + currentStackVersion: '', + defaultStackVersion: 'HDP-1.3.1', + result: '/stacks2/HDP/versions/1.3.1' + }, + { + title: 'if defaultStackVersion and currentStackVersion are different then stack2VersionURL should have currentStackVersion value', + currentStackVersion: 'HDP-1.3.2', + defaultStackVersion: 'HDP-1.3.1', + result: '/stacks2/HDP/versions/1.3.2' + }, + { + title: 'if defaultStackVersion is "HDPLocal-1.3.1" then stack2VersionURL should be "/stacks2/HDPLocal/versions/1.3.1"', + currentStackVersion: '', + defaultStackVersion: 'HDPLocal-1.3.1', + result: '/stacks2/HDPLocal/versions/1.3.1' + }, + { + title: 'if currentStackVersion is "HDPLocal-1.3.1" then stack2VersionURL should be "/stacks2/HDPLocal/versions/1.3.1"', + currentStackVersion: 'HDPLocal-1.3.1', + defaultStackVersion: '', + result: '/stacks2/HDPLocal/versions/1.3.1' + } + ]; + + testCases.forEach(function (test) { + it(test.title, function () { + App.set('currentStackVersion', test.currentStackVersion); + App.set('defaultStackVersion', test.defaultStackVersion); + expect(App.get('stack2VersionURL')).to.equal(test.result); + App.set('currentStackVersion', "HDP-1.2.2"); + App.set('defaultStackVersion', "HDP-1.2.2"); + }); + }); + }); + + describe('#currentStackVersionNumber', function () { + + var testCases = [ + { + title: 'if currentStackVersion is empty then currentStackVersionNumber should be empty', + currentStackVersion: '', + result: '' + }, + { + title: 'if currentStackVersion is "HDP-1.3.1" then currentStackVersionNumber should be "1.3.1', + currentStackVersion: 'HDP-1.3.1', + result: '1.3.1' + }, + { + title: 'if currentStackVersion is "HDPLocal-1.3.1" then currentStackVersionNumber should be "1.3.1', + currentStackVersion: 'HDPLocal-1.3.1', + result: '1.3.1' + } + ]; + + testCases.forEach(function (test) { + it(test.title, function () { + App.set('currentStackVersion', test.currentStackVersion); + expect(App.get('currentStackVersionNumber')).to.equal(test.result); + App.set('currentStackVersion', "HDP-1.2.2"); + }); + }); + }); + + describe('#isHadoop2Stack', function () { + + var testCases = [ + { + title: 'if currentStackVersion is empty then isHadoop2Stack should be false', + currentStackVersion: '', + result: false + }, + { + title: 'if currentStackVersion is "HDP-1.9.9" then isHadoop2Stack should be false', + currentStackVersion: 'HDP-1.9.9', + result: false + }, + { + title: 'if currentStackVersion is "HDP-2.0.0" then isHadoop2Stack should be true', + currentStackVersion: 'HDP-2.0.0', + result: true + }, + { + title: 'if currentStackVersion is "HDP-2.0.1" then isHadoop2Stack should be true', + currentStackVersion: 'HDP-2.0.1', + result: true + } + ]; + + testCases.forEach(function (test) { + it(test.title, function () { + App.set('currentStackVersion', test.currentStackVersion); + expect(App.get('isHadoop2Stack')).to.equal(test.result); + App.set('currentStackVersion', "HDP-1.2.2"); + }); + }); + }); + + describe('#isHaEnabled', function () { + + it('if hadoop stack version less than 2 then isHaEnabled should be false', function () { + App.set('currentStackVersion', 'HDP-1.3.1'); + expect(App.get('isHaEnabled')).to.equal(false); + App.set('currentStackVersion', "HDP-1.2.2"); + }); + it('if hadoop stack version higher than 2 then isHaEnabled should be true', function () { + App.set('currentStackVersion', 'HDP-2.0.1'); + expect(App.get('isHaEnabled')).to.equal(true); + App.set('currentStackVersion', "HDP-1.2.2"); + }); + it('if cluster has SECONDARY_NAMENODE then isHaEnabled should be false', function () { + App.store.load(App.HostComponent, { + id: 'SECONDARY_NAMENODE', + component_name: 'SECONDARY_NAMENODE' + }); + App.set('currentStackVersion', 'HDP-2.0.1'); + expect(App.get('isHaEnabled')).to.equal(false); + App.set('currentStackVersion', "HDP-1.2.2"); + }); + }); + + describe('#handleStackDependedComponents()', function () { + + it('if handleStackDependencyTest is true then stackDependedComponents should be unmodified', function () { + App.set('testMode', false); + App.set('handleStackDependencyTest', true); + App.handleStackDependedComponents(); + expect(App.get('stackDependedComponents')).to.be.empty; + }); + + it('if testMode is true then stackDependedComponents should be unmodified', function () { + App.set('handleStackDependencyTest', false); + App.set('testMode', true); + App.handleStackDependedComponents(); + expect(App.get('stackDependedComponents')).to.be.empty; + }); + + it('if stack contains all components then stackDependedComponents should be empty', function () { + App.set('testMode', false); + App.set('handleStackDependencyTest', false); + App.handleStackDependedComponents(); + expect(App.get('stackDependedComponents')).to.be.empty; + }); + + it('if stack is missing component then push it to stackDependedComponents', function () { + App.set('testMode', false); + App.set('handleStackDependencyTest', false); + var dtRecord = App.StackServiceComponent.find('DATANODE'); + dtRecord.deleteRecord(); + dtRecord.get('stateManager').transitionTo('loading'); + App.handleStackDependedComponents(); + expect(App.get('stackDependedComponents').mapProperty('componentName')).to.eql(["DATANODE"]); + App.store.load(App.StackServiceComponent, { + id: 'DATANODE', + component_name: 'DATANODE', + service_name: 'HDFS', + component_category: 'SLAVE', + is_master: false, + is_client: false, + stack_name: 'HDP', + stack_version: '2.1' + }); + }); + + it('remove stack components from stackDependedComponents', function () { + App.set('testMode', false); + App.set('handleStackDependencyTest', false); + App.set('stackDependedComponents', [ + Em.Object.create({ + componentName: "DATANODE", + serviceName: "HDFS", + properties: {}, + reviewConfigs: {}, + configCategory: {} + }), + Em.Object.create({ + componentName: "categoryComponent", + serviceName: "", + properties: {}, + reviewConfigs: {}, + configCategory: {} + }) + ]); + App.handleStackDependedComponents(); + expect(App.get('stackDependedComponents').mapProperty('componentName')).to.eql(["categoryComponent"]); + }); + }); }); http://git-wip-us.apache.org/repos/asf/ambari/blob/4b962fab/ambari-web/test/init_model_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/init_model_test.js b/ambari-web/test/init_model_test.js new file mode 100644 index 0000000..e94753f --- /dev/null +++ b/ambari-web/test/init_model_test.js @@ -0,0 +1,34 @@ +/** + * 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('models/stack_service_component'); +require('mappers/server_data_mapper'); +require('mappers/stack_service_component_mapper'); + +/** + * initialization of App.StackServiceComponent model + * @type {*} + */ +var data = {items: Em.A([])}; +require('test/service_components').items.forEach(function(i) { + i.serviceComponents.forEach(function(sc) { + data.items.pushObject(sc.StackServiceComponents); + }); +}); +App.stackServiceComponentMapper.map(data); http://git-wip-us.apache.org/repos/asf/ambari/blob/4b962fab/ambari-web/test/views/main/service/info/summary_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/views/main/service/info/summary_test.js b/ambari-web/test/views/main/service/info/summary_test.js new file mode 100644 index 0000000..8392ad0 --- /dev/null +++ b/ambari-web/test/views/main/service/info/summary_test.js @@ -0,0 +1,105 @@ +/** + * 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('views/main/service/info/summary'); + +describe('App.MainServiceInfoSummaryView', function() { + + var mainServiceInfoSummaryView = App.MainServiceInfoSummaryView.create({ + monitorsLiveTextView: Em.View.create(), + controller: Em.Object.create({ + content: Em.Object.create({ + id: 'HDFS', + serviceName: 'HDFS', + hostComponents: [] + }) + }) + }); + + describe('#servers', function () { + it('services shuldn\'t have servers except FLUME and ZOOKEEPER', function () { + expect(mainServiceInfoSummaryView.get('servers')).to.be.empty; + }); + + it('if one server exists then first server should have isComma and isAnd property false', function () { + mainServiceInfoSummaryView.set('controller.content', Em.Object.create({ + id: 'ZOOKEEPER', + serviceName: 'ZOOKEEPER', + hostComponents: [ + Em.Object.create({ + displayName: '', + isMaster: true + }) + ] + })); + expect(mainServiceInfoSummaryView.get('servers').objectAt(0).isComma).to.equal(false); + expect(mainServiceInfoSummaryView.get('servers').objectAt(0).isAnd).to.equal(false); + }); + + it('if more than one servers exist then first server should have isComma - true and isAnd - false', function () { + mainServiceInfoSummaryView.set('controller.content', Em.Object.create({ + id: 'ZOOKEEPER', + serviceName: 'ZOOKEEPER', + hostComponents: [ + Em.Object.create({ + displayName: '', + isMaster: true + }), + Em.Object.create({ + displayName: '', + isMaster: true + }) + ] + })); + expect(mainServiceInfoSummaryView.get('servers').objectAt(0).isComma).to.equal(true); + expect(mainServiceInfoSummaryView.get('servers').objectAt(0).isAnd).to.equal(false); + expect(mainServiceInfoSummaryView.get('servers').objectAt(1).isComma).to.equal(false); + expect(mainServiceInfoSummaryView.get('servers').objectAt(1).isAnd).to.equal(false); + }); + + it('if more than two servers exist then second server should have isComma - false and isAnd - true', function () { + mainServiceInfoSummaryView.set('controller.content', Em.Object.create({ + id: 'ZOOKEEPER', + serviceName: 'ZOOKEEPER', + hostComponents: [ + Em.Object.create({ + displayName: '', + isMaster: true + }), + Em.Object.create({ + displayName: '', + isMaster: true + }), + Em.Object.create({ + displayName: '', + isMaster: true + }) + ] + })); + expect(mainServiceInfoSummaryView.get('servers').objectAt(0).isComma).to.equal(true); + expect(mainServiceInfoSummaryView.get('servers').objectAt(0).isAnd).to.equal(false); + expect(mainServiceInfoSummaryView.get('servers').objectAt(1).isComma).to.equal(false); + expect(mainServiceInfoSummaryView.get('servers').objectAt(1).isAnd).to.equal(true); + expect(mainServiceInfoSummaryView.get('servers').objectAt(2).isComma).to.equal(false); + expect(mainServiceInfoSummaryView.get('servers').objectAt(2).isAnd).to.equal(false); + }); + + }); +});