Repository: ambari Updated Branches: refs/heads/trunk a511d2828 -> 817a7e34e
AMBARI-5609 UI unit tests for admin and alerts controllers. (atkach) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/817a7e34 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/817a7e34 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/817a7e34 Branch: refs/heads/trunk Commit: 817a7e34e3ef67d273c5617329913a5276878bf3 Parents: a511d28 Author: atkach <[email protected]> Authored: Tue Apr 29 13:40:53 2014 +0300 Committer: atkach <[email protected]> Committed: Tue Apr 29 13:40:53 2014 +0300 ---------------------------------------------------------------------- ambari-web/app/assets/test/tests.js | 2 + ambari-web/app/controllers/main/admin.js | 8 +- .../app/controllers/main/alerts_controller.js | 33 ++- ambari-web/test/controllers/main/admin_test.js | 71 +++++ .../controllers/main/alerts_controller_test.js | 260 +++++++++++++++++++ 5 files changed, 361 insertions(+), 13 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/817a7e34/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 363a05f..7e8c040 100644 --- a/ambari-web/app/assets/test/tests.js +++ b/ambari-web/app/assets/test/tests.js @@ -58,6 +58,8 @@ require('test/controllers/main/item_test'); require('test/controllers/main/jobs_controller_test'); require('test/controllers/main/jobs/hive_job_details_controller_test'); require('test/controllers/main/service_test'); +require('test/controllers/main/admin_test'); +require('test/controllers/main/alerts_controller_test'); require('test/controllers/wizard/stack_upgrade/step3_controller_test'); require('test/controllers/installer_test'); require('test/controllers/wizard_test'); http://git-wip-us.apache.org/repos/asf/ambari/blob/817a7e34/ambari-web/app/controllers/main/admin.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/main/admin.js b/ambari-web/app/controllers/main/admin.js index cbb9d12..84dbc49 100644 --- a/ambari-web/app/controllers/main/admin.js +++ b/ambari-web/app/controllers/main/admin.js @@ -27,15 +27,15 @@ App.MainAdminController = Em.Controller.extend({ * * @type {Boolean} */ - isAccessAvailable: function() { + isAccessAvailable: function () { var dependencies = { services: ['YARN', 'TEZ'] }; var serviceNames = App.Service.find().mapProperty('serviceName') - .filter(function(serviceName) { + .filter(function (serviceName) { return dependencies.services.contains(serviceName); }); - var isAppTimelineServerAvailable = App.HostComponent.find().findProperty('componentName','APP_TIMELINE_SERVER') ? true : false; - return (dependencies.services.length == serviceNames.length && isAppTimelineServerAvailable); + var isAppTimelineServerAvailable = App.HostComponent.find().someProperty('componentName', 'APP_TIMELINE_SERVER'); + return (dependencies.services.length === serviceNames.length && isAppTimelineServerAvailable); }.property() }); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/817a7e34/ambari-web/app/controllers/main/alerts_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/main/alerts_controller.js b/ambari-web/app/controllers/main/alerts_controller.js index f0fb6c8..dc6adaf 100644 --- a/ambari-web/app/controllers/main/alerts_controller.js +++ b/ambari-web/app/controllers/main/alerts_controller.js @@ -72,7 +72,10 @@ App.MainAlertsController = Em.Controller.extend({ this.set('isLoaded', true); } }, - + /** + * request alerts from server, which belong to particular host + * @return {Boolean} + */ getAlertsByHost: function () { if (this.get('resourceName')) { App.ajax.send({ @@ -83,12 +86,17 @@ App.MainAlertsController = Em.Controller.extend({ }, success: 'getAlertsSuccessCallback', error: 'getAlertsErrorCallback' - }) + }); + return true; } else { console.warn('GET Alerts error: hostName parameter is missing'); + return false; } }, - + /** + * request alerts from server, which belong to particular service + * @return {Boolean} + */ getAlertsByService: function () { if (this.get('resourceName')) { App.ajax.send({ @@ -99,9 +107,11 @@ App.MainAlertsController = Em.Controller.extend({ }, success: 'getAlertsSuccessCallback', error: 'getAlertsErrorCallback' - }) + }); + return true; } else { console.warn('GET Alerts error: serviceName parameter is missing'); + return false; } }, @@ -109,12 +119,15 @@ App.MainAlertsController = Em.Controller.extend({ * map to associate old status format with and maintain sorting */ statusNumberMap: { - "OK" : "0", + "OK": "0", "WARNING": "1", "CRITICAL": "2", "PASSIVE": "3" }, - + /** + * format json data and push into @alerts array + * @param json + */ getAlertsSuccessCallback: function (json) { var alerts = []; if (json && json.alerts && json.alerts.detail) { @@ -130,11 +143,13 @@ App.MainAlertsController = Em.Controller.extend({ })); }, this); } - this.set('alerts', alerts.sortProperty('status','date').reverse()); + this.set('alerts', alerts.sortProperty('status', 'date').reverse()); this.set('isLoaded', true); }, - - getAlertsErrorCallback: function(){ + /** + * finish loading if call failed + */ + getAlertsErrorCallback: function () { this.set('isLoaded', true); } }); http://git-wip-us.apache.org/repos/asf/ambari/blob/817a7e34/ambari-web/test/controllers/main/admin_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/controllers/main/admin_test.js b/ambari-web/test/controllers/main/admin_test.js new file mode 100644 index 0000000..b2828d0 --- /dev/null +++ b/ambari-web/test/controllers/main/admin_test.js @@ -0,0 +1,71 @@ +/** + * 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/service'); +require('models/host_component'); +require('controllers/main/admin'); + +describe('MainAdminController', function () { + + var controller = App.MainAdminController.create(); + + describe('#isAccessAvailable()', function () { + + beforeEach(function () { + Em.propertyDidChange(controller, 'isAccessAvailable'); + }); + + it('Services do not match dependencies', function () { + App.Service.find().clear(); + App.store.load(App.Service, { + id: 'HDFS', + service_name: 'HDFS' + }); + expect(controller.get("isAccessAvailable")).to.be.false; + }); + it('APP_TIMELINE_SERVER is absent', function () { + App.Service.find().clear(); + App.HostComponent.find().clear(); + expect(controller.get("isAccessAvailable")).to.be.false; + }); + it('Only one YARN service installed', function () { + App.store.load(App.Service, { + id: 'YARN', + service_name: 'YARN' + }); + expect(controller.get("isAccessAvailable")).to.be.false; + }); + it('TEZ and YARN services installed', function () { + App.store.load(App.Service, { + id: 'TEZ', + service_name: 'TEZ' + }); + expect(controller.get("isAccessAvailable")).to.be.false; + }); + it('TEZ and YARN services, APP_TIMELINE_SERVER component installed', function () { + App.store.load(App.HostComponent, { + id: 'APP_TIMELINE_SERVER_host1', + component_name: 'APP_TIMELINE_SERVER' + }); + expect(controller.get("isAccessAvailable")).to.be.true; + }); + }); +}); http://git-wip-us.apache.org/repos/asf/ambari/blob/817a7e34/ambari-web/test/controllers/main/alerts_controller_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/controllers/main/alerts_controller_test.js b/ambari-web/test/controllers/main/alerts_controller_test.js new file mode 100644 index 0000000..3a3dc7f --- /dev/null +++ b/ambari-web/test/controllers/main/alerts_controller_test.js @@ -0,0 +1,260 @@ +/** + * 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/alerts_controller'); +require('models/alert'); + +describe('MainAlertsController', function () { + + var controller = App.MainAlertsController.create(); + + describe('#loadAlerts()', function () { + + before(function () { + sinon.stub(controller, 'getFromServer', Em.K); + }); + after(function () { + controller.getFromServer.restore(); + }); + + it('getFromServer should be called', function () { + controller.set('resourceName', null); + controller.set('isLoaded', true); + controller.set('resourceType', null); + controller.loadAlerts('name1', 'type1'); + expect(controller.get("isLoaded")).to.be.false; + expect(controller.get("resourceName")).to.equal('name1'); + expect(controller.get("resourceType")).to.equal('type1'); + expect(controller.getFromServer.calledOnce).to.be.true; + }); + }); + + describe('#update()', function () { + + var clock; + + beforeEach(function () { + clock = sinon.useFakeTimers(); + sinon.stub(controller, 'getFromServer', Em.K); + sinon.spy(controller, 'update'); + }); + afterEach(function () { + clock.restore(); + controller.getFromServer.restore(); + controller.update.restore(); + }); + + it('isUpdating = true', function () { + controller.set('isUpdating', true); + expect(controller.get("updateTimer")).not.to.be.null; + clock.tick(App.componentsUpdateInterval); + expect(controller.getFromServer.calledOnce).to.be.true; + expect(controller.update.calledTwice).to.be.true; + }); + it('isUpdating = false', function () { + controller.set('isUpdating', false); + expect(controller.update.calledOnce).to.be.true; + }); + }); + + describe('#getFromServer()', function () { + var obj = Em.Object.create({isNagiosInstalled: false}); + + beforeEach(function () { + sinon.stub(controller, 'getAlertsByService', Em.K); + sinon.stub(controller, 'getAlertsByHost', Em.K); + sinon.stub(App.router, 'get', function() {return obj.get('isNagiosInstalled')}); + }); + afterEach(function () { + controller.getAlertsByService.restore(); + controller.getAlertsByHost.restore(); + App.router.get.restore(); + }); + + it('Nagios is not installed', function () { + obj.set('isNagiosInstalled', false); + controller.set('isLoaded', false); + controller.getFromServer(); + expect(controller.get('isLoaded')).to.be.true; + controller.set('isLoaded', false); + }); + it('Nagios installed, SERVICE resource type', function () { + obj.set('isNagiosInstalled', true); + controller.set('resourceType', 'SERVICE'); + controller.getFromServer(); + expect(controller.get('isLoaded')).to.be.false; + expect(controller.getAlertsByService.calledOnce).to.be.true; + }); + it('Nagios installed, HOST resource type', function () { + obj.set('isNagiosInstalled', true); + controller.set('resourceType', 'HOST'); + controller.getFromServer(); + expect(controller.get('isLoaded')).to.be.false; + expect(controller.getAlertsByHost.calledOnce).to.be.true; + }); + it('Nagios installed, unknown resource type', function () { + obj.set('isNagiosInstalled', true); + controller.set('resourceType', 'RS1'); + controller.getFromServer(); + expect(controller.get('isLoaded')).to.be.false; + expect(controller.getAlertsByService.called).to.be.false; + expect(controller.getAlertsByHost.called).to.be.false; + }); + }); + + describe('#getAlertsByHost()', function () { + + beforeEach(function () { + sinon.stub(App.ajax, 'send', Em.K); + }); + afterEach(function () { + App.ajax.send.restore(); + }); + + it('resourceName is null', function () { + controller.set('resourceName', null); + expect(controller.getAlertsByHost()).to.be.false; + expect(App.ajax.send.called).to.be.false; + }); + it('resourceName is correct', function () { + controller.set('resourceName', 'host1'); + expect(controller.getAlertsByHost()).to.be.true; + expect(App.ajax.send.calledOnce).to.be.true; + }); + }); + + describe('#getAlertsByService()', function () { + + beforeEach(function () { + sinon.stub(App.ajax, 'send', Em.K); + }); + afterEach(function () { + App.ajax.send.restore(); + }); + + it('resourceName is null', function () { + controller.set('resourceName', null); + expect(controller.getAlertsByService()).to.be.false; + expect(App.ajax.send.called).to.be.false; + }); + it('resourceName is correct', function () { + controller.set('resourceName', 'service1'); + expect(controller.getAlertsByService()).to.be.true; + expect(App.ajax.send.calledOnce).to.be.true; + }); + }); + + describe('#getAlertsSuccessCallback()', function () { + + var testCases = [ + { + title: 'data is null', + data: null, + result: [] + }, + { + title: 'data.alerts is null', + data: {alerts: null}, + result: [] + }, + { + title: 'data.alerts.detail is null', + data: {alerts: {detail: null}}, + result: [] + }, + { + title: 'data.alerts.detail is empty', + data: {alerts: {detail: []}}, + result: [] + } + ]; + testCases.forEach(function (test) { + it(test.title, function () { + controller.set('isLoaded', false); + controller.getAlertsSuccessCallback(test.data); + expect(controller.get('alerts')).to.eql(test.result); + expect(controller.get('isLoaded')).to.be.true; + }); + }); + + var data = {alerts: {detail: [ + { + description: 't1', + service_name: "s1", + status_time: 1, + status: 'OK', + output: 'o1', + host_name: 'h1', + last_status_time: 1 + } + ]}}; + var testCasesOfStatus = [ + { + title: 'data.alerts.detail is correct, OK status', + status: 'OK', + result: '0' + }, + { + title: 'data.alerts.detail is correct, WARNING status', + status: 'WARNING', + result: '1' + }, + { + title: 'data.alerts.detail is correct, CRITICAL status', + status: 'CRITICAL', + result: '2' + }, + { + title: 'data.alerts.detail is correct, PASSIVE status', + status: 'PASSIVE', + result: '3' + }, + { + title: 'data.alerts.detail is correct, unknown status', + status: '', + result: '4' + } + ]; + testCasesOfStatus.forEach(function (test) { + it(test.title, function () { + controller.set('isLoaded', false); + data.alerts.detail[0].status = test.status; + controller.getAlertsSuccessCallback(data); + expect(controller.get('alerts.length')).to.equal(1); + expect(controller.get('alerts').objectAt(0).get('status')).to.equal(test.result); + expect(controller.get('isLoaded')).to.be.true; + }); + }); + }); + + describe('#getAlertsErrorCallback()', function () { + it('isLoaded was false', function () { + controller.set('isLoaded', false); + controller.getAlertsErrorCallback(); + expect(controller.get('isLoaded')).to.be.true; + }); + it('isLoaded was true', function () { + controller.set('isLoaded', true); + controller.getAlertsErrorCallback(); + expect(controller.get('isLoaded')).to.be.true; + }); + }); +}); \ No newline at end of file
