Repository: ambari Updated Branches: refs/heads/trunk f71d6b923 -> cc92b6102
AMBARI-5422 UI unit tests for cluster and BO controller. (atkach) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/cc92b610 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/cc92b610 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/cc92b610 Branch: refs/heads/trunk Commit: cc92b610264bfca23bbdd9730a4972ccb1848b70 Parents: f71d6b9 Author: atkach <[email protected]> Authored: Thu Apr 10 16:57:11 2014 +0300 Committer: atkach <[email protected]> Committed: Thu Apr 10 16:59:27 2014 +0300 ---------------------------------------------------------------------- .../global/background_operations_controller.js | 77 ++- .../controllers/global/cluster_controller.js | 35 +- ambari-web/app/utils/host_progress_popup.js | 11 +- .../global/background_operations_test.js | 691 ++++++++++++++++--- .../global/cluster_controller_test.js | 394 ++++++++++- .../test/controllers/main/admin/cluster_test.js | 40 +- 6 files changed, 1079 insertions(+), 169 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/cc92b610/ambari-web/app/controllers/global/background_operations_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/global/background_operations_controller.js b/ambari-web/app/controllers/global/background_operations_controller.js index 9dee2c0..933a413 100644 --- a/ambari-web/app/controllers/global/background_operations_controller.js +++ b/ambari-web/app/controllers/global/background_operations_controller.js @@ -165,27 +165,13 @@ App.BackgroundOperationsController = Em.Controller.extend({ */ callBackForMostRecent: function (data) { var runningServices = 0; - var self = this; var currentRequestIds = []; data.items.forEach(function (request) { - var rq = self.get("services").findProperty('id', request.Requests.id); - var isRunning = (request.Requests.task_count - - (request.Requests.aborted_task_count + request.Requests.completed_task_count + request.Requests.failed_task_count - + request.Requests.timed_out_task_count - request.Requests.queued_task_count)) > 0; + var rq = this.get("services").findProperty('id', request.Requests.id); + var isRunning = this.isRequestRunning(request); var requestParams = this.parseRequestContext(request.Requests.request_context); - var inputs = null; - if (request.Requests.inputs) { - inputs = JSON.parse(request.Requests.inputs); - } - var oneHost = false; - if (inputs && inputs.included_hosts) { - var hosts = inputs.included_hosts.split(','); - oneHost = (hosts.length < 2); - } - if(request.Requests.request_schedule && oneHost && /Recommission/.test(requestParams.requestContext)){ - request.Requests.request_schedule.schedule_id = null; - } + this.assignScheduleId(request, requestParams); currentRequestIds.push(request.Requests.id); if (rq) { rq.set('progress', Math.ceil(request.Requests.progress_percent)); @@ -210,18 +196,61 @@ App.BackgroundOperationsController = Em.Controller.extend({ previousTaskStatusMap: {}, contextCommand: requestParams.contextCommand }); - self.get("services").unshift(rq); + this.get("services").unshift(rq); } runningServices += ~~isRunning; }, this); - //remove old request if it's absent in API response - self.get('services').forEach(function(service, index, services){ - if(!currentRequestIds.contains(service.id)) { + this.removeOldRequests(currentRequestIds); + this.set("allOperationsCount", runningServices); + this.set('serviceTimestamp', App.dateTime()); + }, + /** + * remove old requests + * as API returns 10 latest request, the requests that absent in response should be removed + * @param currentRequestIds + */ + removeOldRequests: function (currentRequestIds) { + this.get('services').forEach(function (service, index, services) { + if (!currentRequestIds.contains(service.id)) { services.splice(index, 1); } }); - self.set("allOperationsCount", runningServices); - self.set('serviceTimestamp', App.dateTime()); + }, + /** + * identify whether request is running by task counters + * @param request + * @return {Boolean} + */ + isRequestRunning: function (request) { + return (request.Requests.task_count - + (request.Requests.aborted_task_count + request.Requests.completed_task_count + request.Requests.failed_task_count + + request.Requests.timed_out_task_count - request.Requests.queued_task_count)) > 0; + }, + /** + * identify whether there is only one host in request + * @param inputs + * @return {Boolean} + */ + isOneHost: function (inputs) { + if (!inputs) { + return false; + } + inputs = JSON.parse(inputs); + if (inputs && inputs.included_hosts) { + return inputs.included_hosts.split(',').length < 2; + } + return false + }, + /** + * assign schedule_id of request to null if it's Recommision operation + * @param request + * @param requestParams + */ + assignScheduleId: function (request, requestParams) { + var oneHost = this.isOneHost(request.Requests.inputs); + if (request.Requests.request_schedule && oneHost && /Recommission/.test(requestParams.requestContext)) { + request.Requests.request_schedule.schedule_id = null; + } }, /** @@ -328,4 +357,4 @@ App.BackgroundOperationsController.CommandContexts = { * @param {Number} totalBatchCount Parameter {2}. Total number of batches. Example 10. */ ROLLING_RESTART : "_PARSE_.ROLLING-RESTART.{0}.{1}.{2}" -} +}; \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/cc92b610/ambari-web/app/controllers/global/cluster_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/global/cluster_controller.js b/ambari-web/app/controllers/global/cluster_controller.js index 242ba56..7bea318 100644 --- a/ambari-web/app/controllers/global/cluster_controller.js +++ b/ambari-web/app/controllers/global/cluster_controller.js @@ -52,15 +52,15 @@ App.ClusterController = Em.Controller.extend({ this.set('clusterDataLoadedPercent', 'width:' + (Math.floor(numLoaded / loadListLength * 100)).toString() + '%'); }, - dataLoadList:Em.Object.create({ - 'hosts':false, - 'serviceMetrics':false, - 'stackComponents':false, + dataLoadList: Em.Object.create({ + 'hosts': false, + 'serviceMetrics': false, + 'stackComponents': false, 'services': false, - 'cluster':false, - 'clusterStatus':false, - 'racks':false, - 'users':false, + 'cluster': false, + 'clusterStatus': false, + 'racks': false, + 'users': false, 'componentConfigs': false }), @@ -69,7 +69,7 @@ App.ClusterController = Em.Controller.extend({ */ loadClusterName: function (reload) { if (this.get('clusterName') && !reload) { - return; + return false; } App.ajax.send({ @@ -175,8 +175,7 @@ App.ClusterController = Em.Controller.extend({ return 'http://nagiosserver/nagios'; } else { // We want live data here - var svcs = App.Service.find(); - var nagiosSvc = svcs.findProperty("serviceName", "NAGIOS"); + var nagiosSvc = App.Service.find("NAGIOS"); if (nagiosSvc) { var svcComponents = nagiosSvc.get('hostComponents'); if (svcComponents) { @@ -392,7 +391,7 @@ App.ClusterController = Em.Controller.extend({ }, callback) }, - loadAmbariViews: function() { + loadAmbariViews: function () { App.ajax.send({ name: 'views.info', sender: this, @@ -400,9 +399,9 @@ App.ClusterController = Em.Controller.extend({ }); }, - loadAmbariViewsSuccess: function(data) { - this.set('ambariViews',[]); - data.items.forEach(function(item){ + loadAmbariViewsSuccess: function (data) { + this.set('ambariViews', []); + data.items.forEach(function (item) { App.ajax.send({ name: 'views.instances', data: { @@ -414,8 +413,8 @@ App.ClusterController = Em.Controller.extend({ }, this) }, - loadViewInstancesSuccess: function(data) { - data.instances.forEach(function(instance){ + loadViewInstancesSuccess: function (data) { + data.instances.forEach(function (instance) { var view = Em.Object.create({ label: data.ViewInfo.label, viewName: instance.ViewInstanceInfo.view_name, @@ -430,7 +429,7 @@ App.ClusterController = Em.Controller.extend({ * * @param callback */ - loadStackServiceComponents: function(callback) { + loadStackServiceComponents: function (callback) { var callbackObj = { loadStackServiceComponentsSuccess: callback }; http://git-wip-us.apache.org/repos/asf/ambari/blob/cc92b610/ambari-web/app/utils/host_progress_popup.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/utils/host_progress_popup.js b/ambari-web/app/utils/host_progress_popup.js index 8d1cdbe..290cbcf 100644 --- a/ambari-web/app/utils/host_progress_popup.js +++ b/ambari-web/app/utils/host_progress_popup.js @@ -158,15 +158,18 @@ App.HostPopup = Em.Object.create({ * @return {Number} percent of completion */ getProgress: function (tasks) { + if (!tasks || tasks.length === 0) return 0; + var completedActions = 0; var queuedActions = 0; var inProgressActions = 0; - tasks.forEach(function(task) { - if(['COMPLETED', 'FAILED', 'ABORTED', 'TIMEDOUT'].contains(task.Tasks.status)){ + + tasks.forEach(function (task) { + if (['COMPLETED', 'FAILED', 'ABORTED', 'TIMEDOUT'].contains(task.Tasks.status)) { completedActions++; - } else if(task.Tasks.status === 'QUEUED'){ + } else if (task.Tasks.status === 'QUEUED') { queuedActions++; - } else if(task.Tasks.status === 'IN_PROGRESS'){ + } else if (task.Tasks.status === 'IN_PROGRESS') { inProgressActions++; } }); http://git-wip-us.apache.org/repos/asf/ambari/blob/cc92b610/ambari-web/test/controllers/global/background_operations_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/controllers/global/background_operations_test.js b/ambari-web/test/controllers/global/background_operations_test.js index 710147a..23166ec 100644 --- a/ambari-web/test/controllers/global/background_operations_test.js +++ b/ambari-web/test/controllers/global/background_operations_test.js @@ -29,101 +29,100 @@ require('controllers/global/background_operations_controller'); require('views/common/modal_popup'); require('utils/host_progress_popup'); -var controller; - describe('App.BackgroundOperationsController', function () { - /** - * Predefined data - * - */ - App.set('clusterName', 'testName'); - App.bgOperationsUpdateInterval = 100; - - var tests = Em.A([ - { - levelInfo: Em.Object.create({ - name: 'REQUESTS_LIST', - requestId: null, - taskId: null, - sync: false - }), - e: { - name: 'background_operations.get_most_recent', - successCallback: 'callBackForMostRecent', - data: {} - }, - response: {items:[]}, - m: '"Get Most Recent"' - }, - { - levelInfo: Em.Object.create({ - name: 'TASK_DETAILS', - requestId: 1, - taskId: 1, - sync: false - }), - e: { - name: 'background_operations.get_by_task', - successCallback: 'callBackFilteredByTask', - data: { - taskId: 1, - requestId: 1, + var controller = App.BackgroundOperationsController.create(); + + describe('#getQueryParams', function () { + /** + * Predefined data + * + */ + App.set('clusterName', 'testName'); + App.bgOperationsUpdateInterval = 100; + + var tests = Em.A([ + { + levelInfo: Em.Object.create({ + name: 'REQUESTS_LIST', + requestId: null, + taskId: null, sync: false - } - }, - response: {items:{Tasks:{request_id:0}}}, - m: '"Filtered By task"' - }, - { - levelInfo: Em.Object.create({ - name: 'TASKS_LIST', - requestId: 1, - taskId: 1, - sync: false - }), - e: { - name: 'background_operations.get_by_request', - successCallback: 'callBackFilteredByRequest', - data: { + }), + e: { + name: 'background_operations.get_most_recent', + successCallback: 'callBackForMostRecent', + data: {} + }, + response: {items: []}, + m: '"Get Most Recent"' + }, + { + levelInfo: Em.Object.create({ + name: 'TASK_DETAILS', requestId: 1, + taskId: 1, sync: false - } - }, - response: {items:{Requests:{id:0}}}, - m: '"Filtered By Request (TASKS_LIST)"' - }, - { - levelInfo: Em.Object.create({ - name: 'HOSTS_LIST', - requestId: 1, - taskId: 1, - sync: false - }), - e: { - name: 'background_operations.get_by_request', - successCallback: 'callBackFilteredByRequest', - data: { + }), + e: { + name: 'background_operations.get_by_task', + successCallback: 'callBackFilteredByTask', + data: { + taskId: 1, + requestId: 1, + sync: false + } + }, + response: {items: {Tasks: {request_id: 0}}}, + m: '"Filtered By task"' + }, + { + levelInfo: Em.Object.create({ + name: 'TASKS_LIST', requestId: 1, + taskId: 1, sync: false - } + }), + e: { + name: 'background_operations.get_by_request', + successCallback: 'callBackFilteredByRequest', + data: { + requestId: 1, + sync: false + } + }, + response: {items: {Requests: {id: 0}}}, + m: '"Filtered By Request (TASKS_LIST)"' }, - response: {items:{Requests:{id:0}}}, - m: '"Filtered By Request (HOSTS_LIST)"' - } - ]); + { + levelInfo: Em.Object.create({ + name: 'HOSTS_LIST', + requestId: 1, + taskId: 1, + sync: false + }), + e: { + name: 'background_operations.get_by_request', + successCallback: 'callBackFilteredByRequest', + data: { + requestId: 1, + sync: false + } + }, + response: {items: {Requests: {id: 0}}}, + m: '"Filtered By Request (HOSTS_LIST)"' + } + ]); - describe('#getQueryParams', function() { - beforeEach(function() { - controller = App.BackgroundOperationsController.create(); + beforeEach(function () { App.testMode = false; }); - afterEach(function() { + afterEach(function () { App.testMode = true; }); - tests.forEach(function(test) { - it(test.m, function() { + tests.forEach(function (test) { + it(test.m, function () { controller.set('levelInfo', test.levelInfo); var r = controller.getQueryParams(); expect(r.name).to.equal(test.e.name); @@ -133,4 +132,534 @@ describe('App.BackgroundOperationsController', function () { }); }); + describe('#startPolling()', function () { + + beforeEach(function () { + sinon.spy(App.updater, 'run'); + sinon.spy(controller, 'requestMostRecent'); + }); + afterEach(function () { + App.updater.run.restore(); + controller.requestMostRecent.restore(); + }); + + it('isWorking = false', function () { + controller.set('isWorking', false); + expect(App.updater.run.calledOnce).to.equal(false); + expect(controller.requestMostRecent.calledOnce).to.equal(false); + }); + it('isWorking = true', function () { + controller.set('isWorking', true); + expect(App.updater.run.calledOnce).to.equal(true); + expect(controller.requestMostRecent.calledOnce).to.equal(true); + }); + }); + + describe('#callBackForMostRecent()', function () { + it('No requests exists', function () { + var data = { + items: [] + }; + controller.callBackForMostRecent(data); + expect(controller.get("allOperationsCount")).to.equal(0); + expect(controller.get("services")).to.be.empty; + }); + it('One non-running request', function () { + var data = { + items: [ + { + Requests: { + id: 1, + request_context: '', + task_count: 0, + aborted_task_count: 0, + completed_task_count: 0, + failed_task_count: 0, + timed_out_task_count: 0, + queued_task_count: 0 + } + } + ] + }; + controller.callBackForMostRecent(data); + expect(controller.get("allOperationsCount")).to.equal(0); + expect(controller.get("services").mapProperty('id')).to.eql([1]); + }); + + + it('One running request', function () { + var data = { + items: [ + { + Requests: { + id: 1, + request_context: '', + task_count: 1, + aborted_task_count: 0, + completed_task_count: 0, + failed_task_count: 0, + timed_out_task_count: 0, + queued_task_count: 0 + } + } + ] + }; + controller.callBackForMostRecent(data); + expect(controller.get("allOperationsCount")).to.equal(1); + expect(controller.get("services").mapProperty('id')).to.eql([1]); + }); + it('Two requests in order', function () { + var data = { + items: [ + { + Requests: { + id: 1, + request_context: '' + } + }, + { + Requests: { + id: 2, + request_context: '' + } + } + ] + }; + controller.callBackForMostRecent(data); + expect(controller.get("allOperationsCount")).to.equal(0); + expect(controller.get("services").mapProperty('id')).to.eql([2, 1]); + }); + }); + + describe('#removeOldRequests()', function () { + var testCases = [ + { + title: 'No requests exist', + content: { + currentRequestIds: [], + services: [] + }, + result: [] + }, + { + title: 'One current request', + content: { + currentRequestIds: [1], + services: [ + {id: 1} + ] + }, + result: [ + {id: 1} + ] + }, + { + title: 'One old request', + content: { + currentRequestIds: [2], + services: [ + {id: 1} + ] + }, + result: [] + }, + { + title: 'One old request and one is current', + content: { + currentRequestIds: [2], + services: [ + {id: 1}, + {id: 2} + ] + }, + result: [ + {id: 2} + ] + } + ]; + + testCases.forEach(function (test) { + it(test.title, function () { + controller.set('services', test.content.services); + controller.removeOldRequests(test.content.currentRequestIds); + expect(controller.get('services')).to.eql(test.result); + }); + }); + }); + + describe('#isRequestRunning()', function () { + var testCases = [ + { + title: 'Counters are missing', + request: { + Requests: {} + }, + result: false + }, + { + title: 'Request has zero tasks', + request: { + Requests: { + task_count: 0, + aborted_task_count: 0, + completed_task_count: 0, + failed_task_count: 0, + timed_out_task_count: 0, + queued_task_count: 0 + } + }, + result: false + }, + { + title: 'One task in running status', + request: { + Requests: { + task_count: 1, + aborted_task_count: 0, + completed_task_count: 0, + failed_task_count: 0, + timed_out_task_count: 0, + queued_task_count: 0 + } + }, + result: true + }, + { + title: 'One task in queued status', + request: { + Requests: { + task_count: 1, + aborted_task_count: 0, + completed_task_count: 0, + failed_task_count: 0, + timed_out_task_count: 0, + queued_task_count: 1 + } + }, + result: true + }, + { + title: 'One task in aborted status', + request: { + Requests: { + task_count: 1, + aborted_task_count: 1, + completed_task_count: 0, + failed_task_count: 0, + timed_out_task_count: 0, + queued_task_count: 0 + } + }, + result: false + }, + { + title: 'One task in completed status', + request: { + Requests: { + task_count: 1, + aborted_task_count: 0, + completed_task_count: 1, + failed_task_count: 0, + timed_out_task_count: 0, + queued_task_count: 0 + } + }, + result: false + }, + { + title: 'One task in failed status', + request: { + Requests: { + task_count: 1, + aborted_task_count: 0, + completed_task_count: 0, + failed_task_count: 1, + timed_out_task_count: 0, + queued_task_count: 0 + } + }, + result: false + }, + { + title: 'One task in timed out status', + request: { + Requests: { + task_count: 1, + aborted_task_count: 0, + completed_task_count: 0, + failed_task_count: 0, + timed_out_task_count: 1, + queued_task_count: 0 + } + }, + result: false + }, + { + title: 'One task in timed out status and the second one in running', + request: { + Requests: { + task_count: 2, + aborted_task_count: 0, + completed_task_count: 0, + failed_task_count: 0, + timed_out_task_count: 1, + queued_task_count: 0 + } + }, + result: true + }, + { + title: 'One task in each status', + request: { + Requests: { + task_count: 5, + aborted_task_count: 1, + completed_task_count: 1, + failed_task_count: 1, + timed_out_task_count: 1, + queued_task_count: 1 + } + }, + result: true + }, + { + title: 'One task in each status except queued', + request: { + Requests: { + task_count: 5, + aborted_task_count: 1, + completed_task_count: 1, + failed_task_count: 1, + timed_out_task_count: 1, + queued_task_count: 0 + } + }, + result: true + }, + { + title: 'No tasks in running status', + request: { + Requests: { + task_count: 4, + aborted_task_count: 1, + completed_task_count: 1, + failed_task_count: 1, + timed_out_task_count: 1, + queued_task_count: 0 + } + }, + result: false + } + ]; + + testCases.forEach(function (test) { + it(test.title, function () { + expect(controller.isRequestRunning(test.request)).to.eql(test.result); + }); + }); + }); + + describe('#isOneHost()', function () { + var testCases = [ + { + title: 'inputs is null', + inputs: null, + result: false + }, + { + title: 'inputs is "null"', + inputs: 'null', + result: false + }, + { + title: 'inputs is empty object', + inputs: '{}', + result: false + }, + { + title: 'included_hosts is empty', + inputs: '{"included_hosts": ""}', + result: false + }, + { + title: 'included_hosts contain one host', + inputs: '{"included_hosts": "host1"}', + result: true + }, + { + title: 'included_hosts contain two hosts', + inputs: '{"included_hosts": "host1,host2"}', + result: false + } + ]; + + testCases.forEach(function (test) { + it(test.title, function () { + expect(controller.isOneHost(test.inputs)).to.eql(test.result); + }); + }); + }); + + describe('#assignScheduleId()', function () { + var testCases = [ + { + title: 'isOneHost is false', + content: { + request: { + Requests: { + request_schedule: { + schedule_id: 1 + }, + inputs: null + } + }, + requestParams: '' + }, + result: 1 + }, + { + title: 'isOneHost is true and requestContext is empty', + content: { + request: { + Requests: { + request_schedule: { + schedule_id: 1 + }, + inputs: '{"included_hosts": "host1"}' + } + }, + requestParams: { + requestContext: '' + } + }, + result: 1 + }, + { + title: 'isOneHost is true and requestContext contains "Recommission"', + content: { + request: { + Requests: { + request_schedule: { + schedule_id: 1 + }, + inputs: '{"included_hosts": "host1"}' + } + }, + requestParams: { + requestContext: 'Recommission' + } + }, + result: null + } + ]; + + testCases.forEach(function (test) { + it(test.title, function () { + controller.assignScheduleId(test.content.request, test.content.requestParams); + expect(test.content.request.Requests.request_schedule.schedule_id).to.equal(test.result); + }); + }); + }); + + describe('#callBackFilteredByRequest()', function () { + + it('request haven\'t tasks and isRunning false', function () { + var data = { + Requests: {id: 1}, + tasks: [] + }; + var request = Em.Object.create({ + id: 1, + previousTaskStatusMap: {}, + isRunning: false, + progress: 0, + status:'' + }); + controller.set('services', [request]); + controller.callBackFilteredByRequest(data); + expect(request.get('previousTaskStatusMap')).to.eql({}); + expect(request.get('hostsMap')).to.eql({}); + expect(request.get('isRunning')).to.equal(false); + }); + + it('request haven\'t tasks and isRunning true', function () { + var data = { + Requests: {id: 1}, + tasks: [] + }; + var request = Em.Object.create({ + id: 1, + previousTaskStatusMap: {}, + isRunning: true, + progress: 0, + status:'' + }); + controller.set('services', [request]); + controller.callBackFilteredByRequest(data); + expect(request.get('previousTaskStatusMap')).to.eql({}); + expect(request.get('hostsMap')).to.eql({}); + expect(request.get('isRunning')).to.equal(true); + }); + + it('request has one completed task', function () { + var data = { + Requests: {id: 1}, + tasks: [ + { + Tasks: { + id: 1, + host_name: 'host1', + status: 'COMPLETED' + } + } + ] + }; + var request = Em.Object.create({ + id: 1, + previousTaskStatusMap: {}, + isRunning: true, + progress: 100, + status:'' + }); + controller.set('services', [request]); + controller.callBackFilteredByRequest(data); + expect(request.get('previousTaskStatusMap')).to.eql({"1": "COMPLETED"}); + expect(request.get('hostsMap')['host1'].logTasks.length).to.equal(1); + expect(request.get('isRunning')).to.equal(false); + }); + + it('request has one completed task and one running task', function () { + var data = { + Requests: {id: 1}, + tasks: [ + { + Tasks: { + id: 1, + host_name: 'host1', + status: 'COMPLETED' + } + }, + { + Tasks: { + id: 2, + host_name: 'host1', + status: 'IN_PROGRESS' + } + } + ] + }; + var request = Em.Object.create({ + id: 1, + previousTaskStatusMap: {}, + isRunning: true, + progress: 100, + status:'' + }); + controller.set('services', [request]); + controller.callBackFilteredByRequest(data); + expect(request.get('previousTaskStatusMap')).to.eql({"1": "COMPLETED", "2": "IN_PROGRESS"}); + expect(request.get('hostsMap')['host1'].logTasks.length).to.equal(2); + expect(request.get('isRunning')).to.equal(true); + }); + }); }); http://git-wip-us.apache.org/repos/asf/ambari/blob/cc92b610/ambari-web/test/controllers/global/cluster_controller_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/controllers/global/cluster_controller_test.js b/ambari-web/test/controllers/global/cluster_controller_test.js index 43f0409..9b099f9 100644 --- a/ambari-web/test/controllers/global/cluster_controller_test.js +++ b/ambari-web/test/controllers/global/cluster_controller_test.js @@ -22,81 +22,431 @@ require('controllers/global/cluster_controller'); require('models/host_component'); require('utils/http_client'); require('models/service'); +require('models/host'); +require('utils/ajax'); describe('App.clusterController', function () { var controller = App.ClusterController.create(); - App.Service.FIXTURES = [{service_name: 'NAGIOS'}]; + App.Service.FIXTURES = [ + {service_name: 'NAGIOS'} + ]; describe('#updateLoadStatus()', function () { controller.set('dataLoadList', Em.Object.create({ - 'item1':false, - 'item2':false + 'item1': false, + 'item2': false })); - it('when none item is loaded then width should be "width:0"', function(){ + it('when none item is loaded then width should be "width:0"', function () { expect(controller.get('clusterDataLoadedPercent')).to.equal('width:0'); }); - it('when first item is loaded then isLoaded should be false', function(){ + it('when first item is loaded then isLoaded should be false', function () { controller.updateLoadStatus.call(controller, 'item1'); expect(controller.get('isLoaded')).to.equal(false); }); - it('when first item is loaded then width should be "width:50%"', function(){ + it('when first item is loaded then width should be "width:50%"', function () { controller.updateLoadStatus.call(controller, 'item1'); expect(controller.get('clusterDataLoadedPercent')).to.equal('width:50%'); }); - it('when all items are loaded then isLoaded should be true', function(){ + it('when all items are loaded then isLoaded should be true', function () { controller.updateLoadStatus.call(controller, 'item2'); expect(controller.get('isLoaded')).to.equal(true); }); - it('when all items are loaded then width should be "width:100%"', function(){ + it('when all items are loaded then width should be "width:100%"', function () { controller.updateLoadStatus.call(controller, 'item2'); expect(controller.get('clusterDataLoadedPercent')).to.equal('width:100%'); }); }); - describe('#loadClusterNameSuccessCallback', function() { + describe('#loadClusterName()', function () { + + beforeEach(function () { + sinon.spy(App.ajax, 'send'); + }); + afterEach(function () { + App.ajax.send.restore(); + }); + + it('if clusterName is "mycluster" and reload is false then loadClusterName should return false', function () { + controller.set('cluster', {Clusters: {cluster_name: 'mycluster'}}); + expect(controller.loadClusterName(false)).to.equal(false); + }); + + it('reload is true and clusterName is not empty', function () { + controller.loadClusterName(true); + expect(App.ajax.send.calledOnce).to.equal(true); + expect(App.get('currentStackVersion')).to.equal('HDP-2.0.5'); + }); + + it('reload is false and clusterName is empty', function () { + controller.set('cluster', {Clusters: {cluster_name: ''}}); + controller.loadClusterName(false); + expect(App.ajax.send.calledOnce).to.equal(true); + expect(App.get('currentStackVersion')).to.equal('HDP-2.0.5'); + }); + + + }); + + describe('#loadClusterNameSuccessCallback', function () { var test_data = { - "items" : [ + "items": [ { - "Clusters" : { - "cluster_name" : "tdk", - "version" : "HDP-1.3.0" + "Clusters": { + "cluster_name": "tdk", + "version": "HDP-1.3.0" } } ] }; - controller.loadClusterNameSuccessCallback(test_data); - it('Check cluster', function() { + it('Check cluster', function () { + controller.loadClusterNameSuccessCallback(test_data); expect(controller.get('cluster.Clusters.cluster_name')).to.equal('tdk'); expect(controller.get('cluster.Clusters.version')).to.equal('HDP-1.3.0'); expect(App.get('clusterName')).to.equal('tdk'); }); }); - describe('#loadClusterNameErrorCallback', function() { + describe('#loadClusterNameErrorCallback', function () { controller.loadClusterNameErrorCallback(); - it('', function() { + it('', function () { expect(controller.get('isLoaded')).to.equal(true); }); }); - describe('#getUrl', function() { + describe('#getServerClockSuccessCallback()', function () { + var testCases = [ + { + title: 'if server clock is 1 then currentServerTime should be 1000', + data: { + RootServiceComponents: { + server_clock: 1 + } + }, + result: 1000 + }, + { + title: 'if server clock is 0 then currentServerTime should be 0', + data: { + RootServiceComponents: { + server_clock: 0 + } + }, + result: 0 + }, + { + title: 'if server clock is 111111111111 then currentServerTime should be 111111111111000', + data: { + RootServiceComponents: { + server_clock: 111111111111 + } + }, + result: 111111111111000 + }, + { + title: 'if server clock is 1111111111113 then currentServerTime should be 1111111111113', + data: { + RootServiceComponents: { + server_clock: 1111111111113 + } + }, + result: 1111111111113 + } + ]; + var currentServerTime = App.get('currentServerTime'); + var clockDistance = App.get('clockDistance'); + + testCases.forEach(function (test) { + it(test.title, function () { + controller.getServerClockSuccessCallback(test.data); + expect(App.get('currentServerTime')).to.equal(test.result); + App.set('clockDistance', clockDistance); + App.set('currentServerTime', currentServerTime); + }); + }); + }); + + describe('#getUrl', function () { controller.set('clusterName', 'tdk'); var tests = ['test1', 'test2', 'test3']; - it('testMode = true', function() { + it('testMode = true', function () { App.testMode = true; - tests.forEach(function(test) { + tests.forEach(function (test) { expect(controller.getUrl(test, test)).to.equal(test); }); }); - it('testMode = false', function() { + it('testMode = false', function () { App.testMode = false; - tests.forEach(function(test) { + tests.forEach(function (test) { expect(controller.getUrl(test, test)).to.equal(App.apiPrefix + '/clusters/' + controller.get('clusterName') + test); }); }); }); + describe('#gangliaUrl', function () { + it('testMode = true', function () { + App.testMode = true; + expect(controller.get('gangliaUrl')).to.equal('http://gangliaserver/ganglia/?t=yes'); + }); + it('Ganglia service is absent', function () { + App.testMode = false; + controller.set('gangliaWebProtocol', ''); + expect(controller.get('gangliaUrl')).to.equal(null); + }); + it('Ganglia doesn\'t have any components', function () { + App.store.load(App.Service, { + id: 'GANGLIA', + service_name: 'GANGLIA' + }); + controller.set('gangliaWebProtocol', ''); + expect(controller.get('gangliaUrl')).to.equal(null); + expect(controller.get('isGangliaInstalled')).to.equal(true); + }); + it('Ganglia Server doesn\'t have host', function () { + App.store.load(App.HostComponent, { + id: 'GANGLIA_SERVER_GANGLIA_host', + component_name: 'GANGLIA_SERVER', + service_id: 'GANGLIA', + host_id: 'GANGLIA_host' + }); + App.store.load(App.Service, { + id: 'GANGLIA', + service_name: 'GANGLIA', + host_components: ['GANGLIA_SERVER_GANGLIA_host'] + }); + controller.set('gangliaWebProtocol', ''); + expect(controller.get('gangliaUrl')).to.equal(null); + }); + it('Ganglia Server host is "GANGLIA_host"', function () { + App.store.load(App.Host, { + id: 'GANGLIA_host', + host_name: 'GANGLIA_host', + host_components: ['GANGLIA_SERVER_GANGLIA_host'], + public_host_name: 'GANGLIA_host' + }); + controller.set('gangliaWebProtocol', ''); + expect(controller.get('gangliaUrl')).to.equal("http://GANGLIA_host/ganglia"); + }); + it('singleNodeInstall = true', function () { + App.set('singleNodeInstall', true); + controller.set('gangliaWebProtocol', ''); + expect(controller.get('gangliaUrl')).to.equal("http://:42080/ganglia"); + }); + it('singleNodeAlias is "alias"', function () { + App.set('singleNodeAlias', 'alias'); + controller.set('gangliaWebProtocol', ''); + expect(controller.get('gangliaUrl')).to.equal("http://alias:42080/ganglia"); + App.set('singleNodeInstall', false); + App.set('singleNodeAlias', ''); + }); + }); + + describe('#nagiosUrl', function () { + it('testMode = true', function () { + App.testMode = true; + controller.set('nagiosWebProtocol', ''); + expect(controller.get('nagiosUrl')).to.equal('http://nagiosserver/nagios'); + }); + it('Nagios service is absent', function () { + App.testMode = false; + controller.set('nagiosWebProtocol', ''); + expect(controller.get('nagiosUrl')).to.equal(null); + }); + it('Nagios doesn\'t have any components', function () { + App.store.load(App.Service, { + id: 'NAGIOS', + service_name: 'NAGIOS' + }); + controller.set('nagiosWebProtocol', ''); + expect(controller.get('nagiosUrl')).to.equal(null); + expect(controller.get('isNagiosInstalled')).to.equal(true); + }); + it('NAGIOS Server doesn\'t have host', function () { + App.store.load(App.HostComponent, { + id: 'NAGIOS_SERVER_NAGIOS_host', + component_name: 'NAGIOS_SERVER', + service_id: 'NAGIOS', + host_id: 'NAGIOS_host' + }); + App.store.load(App.Service, { + id: 'NAGIOS', + service_name: 'NAGIOS', + host_components: ['NAGIOS_SERVER_NAGIOS_host'] + }); + controller.set('nagiosWebProtocol', ''); + expect(controller.get('nagiosUrl')).to.equal(null); + }); + it('NAGIOS Server host is "NAGIOS_host"', function () { + App.store.load(App.Host, { + id: 'NAGIOS_host', + host_name: 'NAGIOS_host', + host_components: ['NAGIOS_SERVER_NAGIOS_host'], + public_host_name: 'NAGIOS_host' + }); + controller.set('nagiosWebProtocol', ''); + expect(controller.get('nagiosUrl')).to.equal("http://NAGIOS_host/nagios"); + }); + it('singleNodeInstall = true', function () { + App.set('singleNodeInstall', true); + controller.set('nagiosWebProtocol', ''); + expect(controller.get('nagiosUrl')).to.equal("http://:42080/nagios"); + }); + it('singleNodeAlias is "alias"', function () { + App.set('singleNodeAlias', 'alias'); + controller.set('nagiosWebProtocol', ''); + expect(controller.get('nagiosUrl')).to.equal("http://alias:42080/nagios"); + }); + }); + + describe('#nagiosWebProtocol', function () { + var testCases = [ + { + title: 'if ambariProperties is null then nagiosWebProtocol should be "http"', + data: null, + result: 'http' + }, + { + title: 'if ambariProperties is empty object then nagiosWebProtocol should be "http"', + data: {}, + result: 'http' + }, + { + title: 'if nagios.https is false then nagiosWebProtocol should be "http"', + data: {'nagios.https': false}, + result: 'http' + }, + { + title: 'if nagios.https is true then nagiosWebProtocol should be "http"', + data: {'nagios.https': true}, + result: 'https' + } + ]; + + testCases.forEach(function (test) { + it(test.title, function () { + controller.set('ambariProperties', test.data); + expect(controller.get('nagiosWebProtocol')).to.equal(test.result); + }); + }); + }); + + describe('#gangliaWebProtocol', function () { + var testCases = [ + { + title: 'if ambariProperties is null then nagiosWebProtocol should be "http"', + data: null, + result: 'http' + }, + { + title: 'if ambariProperties is empty object then nagiosWebProtocol should be "http"', + data: {}, + result: 'http' + }, + { + title: 'if nagios.https is false then nagiosWebProtocol should be "http"', + data: {'ganglia.https': false}, + result: 'http' + }, + { + title: 'if nagios.https is true then nagiosWebProtocol should be "http"', + data: {'ganglia.https': true}, + result: 'https' + } + ]; + + testCases.forEach(function (test) { + it(test.title, function () { + controller.set('ambariProperties', test.data); + expect(controller.get('gangliaWebProtocol')).to.equal(test.result); + }); + }); + }); + + describe('#startPolling()', function () { + + beforeEach(function () { + sinon.spy(App.updater, 'run'); + }); + afterEach(function () { + App.updater.run.restore(); + }); + it('isWorking = false', function () { + controller.set('isWorking', false); + expect(App.updater.run.calledOnce).to.equal(false); + expect(controller.startPolling()).to.equal(false); + }); + + it('isWorking = true', function () { + controller.set('isWorking', true); + expect(App.updater.run.calledOnce).to.equal(true); + expect(controller.startPolling()).to.equal(true); + }); + }); + + describe('#deferServiceMetricsLoad()', function () { + beforeEach(function () { + sinon.spy(App.serviceMetricsMapper, 'map'); + }); + afterEach(function () { + App.serviceMetricsMapper.map.restore(); + }); + it('json is null', function () { + controller.set('serviceMetricsJson', {}); + controller.set('dataLoadList.serviceMetrics', false); + controller.deferServiceMetricsLoad(null); + expect(controller.get('serviceMetricsJson')).to.equal(null); + expect(controller.get('dataLoadList.serviceMetrics')).to.equal(true); + expect(App.serviceMetricsMapper.map.calledOnce).to.equal(true); + }); + it('json is correct', function () { + controller.deferServiceMetricsLoad({data: ''}); + expect(controller.get('serviceMetricsJson')).to.eql({data: ''}); + }); + it('json is correct and dataLoadList.hosts is true', function () { + controller.set('serviceMetricsJson', {}); + controller.set('dataLoadList.serviceMetrics', false); + controller.set('dataLoadList.hosts', true); + controller.deferServiceMetricsLoad(null); + expect(controller.get('dataLoadList.serviceMetrics')).to.equal(true); + expect(App.serviceMetricsMapper.map.calledOnce).to.equal(true); + }); + }); + + describe('#clusterName', function () { + var testCases = [ + { + title: 'if cluster is null then clusterName should be null', + data: null, + result: null + }, + { + title: 'if cluster.Clusters.cluster_name is null then clusterName should be null', + data: { + Clusters: { + cluster_name: null + } + }, + result: null + }, + { + title: 'if cluster.Clusters.cluster_name is null then clusterName should be null', + data: { + Clusters: { + cluster_name: 'mycluster' + } + }, + result: 'mycluster' + } + ]; + + testCases.forEach(function (test) { + it(test.title, function () { + controller.set('cluster', test.data); + expect(controller.get('clusterName')).to.equal(test.result); + }); + }); + }); + }); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/cc92b610/ambari-web/test/controllers/main/admin/cluster_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/controllers/main/admin/cluster_test.js b/ambari-web/test/controllers/main/admin/cluster_test.js index ce35948..b23f728 100644 --- a/ambari-web/test/controllers/main/admin/cluster_test.js +++ b/ambari-web/test/controllers/main/admin/cluster_test.js @@ -23,49 +23,49 @@ require('controllers/main/admin/cluster'); describe('App.MainAdminClusterController', function () { - App.set('currentStackVersion', 'HDP-1.2.2'); - App.set('defaultStackVersion', 'HDP-1.2.2'); var data = { - "items" : [ + "items": [ { - "Versions" : { - "stack_version" : "1.3.1", - "min_upgrade_version" : "1.2.0" + "Versions": { + "stack_version": "1.3.1", + "min_upgrade_version": "1.2.0" } - }, + }, { - "Versions" : { - "stack_version" : "1.3.0", - "min_upgrade_version" : "1.2.0" + "Versions": { + "stack_version": "1.3.0", + "min_upgrade_version": "1.2.0" } }, { - "Versions" : { - "stack_version" : "1.2.2", - "min_upgrade_version" : "1.2.0" + "Versions": { + "stack_version": "1.2.2", + "min_upgrade_version": "1.2.0" } }, { - "Versions" : { - "stack_version" : "1.2.0", - "min_upgrade_version" : "1.2.0" + "Versions": { + "stack_version": "1.2.0", + "min_upgrade_version": "1.2.0" } } ] }; describe('#updateUpgradeVersionSuccessCallback()', function () { - it('upgrade version of stack should be "HDP-1.3.0"', function(){ + it('upgrade version of stack should be "HDP-1.3.1"', function () { + App.set('currentStackVersion', 'HDP-1.2.2'); var controller = App.MainAdminClusterController.create({ - parseServicesInfo:function(){} + parseServicesInfo: function () {} }); controller.updateUpgradeVersionSuccessCallback.call(controller, data); expect(controller.get('upgradeVersion')).to.equal('HDP-1.3.1'); }); - it('if min upgrade version less then current then upgrade version equal current', function(){ + it('if min upgrade version less then current then upgrade version equal current', function () { + App.set('currentStackVersion', 'HDP-1.2.2'); data.items[0].Versions.min_upgrade_version = "1.2.3"; var controller = App.MainAdminClusterController.create({ - parseServicesInfo:function(){} + parseServicesInfo: function () {} }); controller.updateUpgradeVersionSuccessCallback.call(controller, data); expect(controller.get('upgradeVersion')).to.equal('HDP-1.2.2');
