Repository: ambari Updated Branches: refs/heads/trunk eef00a9ec -> dfc77fb21
AMBARI-11164. Widgets: Graph legend can be misleading when labels are long (onechiporenko) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/dfc77fb2 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/dfc77fb2 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/dfc77fb2 Branch: refs/heads/trunk Commit: dfc77fb2155ee9d80b1479c0f90aec208aa2f483 Parents: eef00a9 Author: Oleg Nechiporenko <[email protected]> Authored: Fri May 15 14:34:54 2015 +0300 Committer: Oleg Nechiporenko <[email protected]> Committed: Fri May 15 14:36:23 2015 +0300 ---------------------------------------------------------------------- ambari-web/app/styles/application.less | 1 - .../app/views/common/chart/linear_time.js | 30 +- ambari-web/test/controllers/installer_test.js | 884 ++++++++++++++++++- 3 files changed, 898 insertions(+), 17 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/dfc77fb2/ambari-web/app/styles/application.less ---------------------------------------------------------------------- diff --git a/ambari-web/app/styles/application.less b/ambari-web/app/styles/application.less index 6261b43..7235c98 100644 --- a/ambari-web/app/styles/application.less +++ b/ambari-web/app/styles/application.less @@ -2141,7 +2141,6 @@ a:focus { width: 60px; } .chart-legend { - left: 60px; top: 245px; } .x_tick { http://git-wip-us.apache.org/repos/asf/ambari/blob/dfc77fb2/ambari-web/app/views/common/chart/linear_time.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/common/chart/linear_time.js b/ambari-web/app/views/common/chart/linear_time.js index 5f00cbc..2f0c33a 100644 --- a/ambari-web/app/views/common/chart/linear_time.js +++ b/ambari-web/app/views/common/chart/linear_time.js @@ -451,44 +451,44 @@ App.ChartLinearTimeView = Ember.View.extend({ var palette = new Rickshaw.Color.Palette({ scheme: 'munin'}); // Format series for display var series_min_length = 100000000; - data.forEach(function (series, index) { + data.forEach(function (series) { var seriesColor = self.colorForSeries(series); - if (seriesColor == null) { + if (Em.isNone(seriesColor)) { seriesColor = palette.color(); } series.color = seriesColor; series.stroke = 'rgba(0,0,0,0.3)'; - if (this.get('isPopup')) { + if (self.get('isPopup')) { // calculate statistic data for popup legend var avg = 0; var min = Number.MAX_VALUE; var max = Number.MIN_VALUE; for (var i = 0; i < series.data.length; i++) { avg += series.data[i]['y']; - if (series.data[i]['y'] < min) { - min = series.data[i]['y']; - } - else { - if (series.data[i]['y'] > max) { - max = series.data[i]['y']; + if (!Em.isNone(series.data[i]['y'])) { + if (series.data[i]['y'] < min) { + min = series.data[i]['y']; } } + if (series.data[i]['y'] > max) { + max = series.data[i]['y']; + } } - series.name = string_utils.pad(series.name, 30, ' ', 2) + + series.name = string_utils.pad(series.name.length > 36 ? series.name.substr(0, 36) + '...' : series.name, 40, ' ', 2) + '| ' + string_utils.pad('min', 5, ' ', 3) + - string_utils.pad(this.get('yAxisFormatter')(min), 12, ' ', 3) + + string_utils.pad(self.get('yAxisFormatter')(min), 12, ' ', 3) + string_utils.pad('avg', 5, ' ', 3) + - string_utils.pad(this.get('yAxisFormatter')(avg/series.data.length), 12, ' ', 3) + + string_utils.pad(self.get('yAxisFormatter')(avg/series.data.compact().length), 12, ' ', 3) + string_utils.pad('max', 12, ' ', 3) + - string_utils.pad(this.get('yAxisFormatter')(max), 5, ' ', 3); + string_utils.pad(self.get('yAxisFormatter')(max), 5, ' ', 3); } if (series.data.length < series_min_length) { series_min_length = series.data.length; } - }.bind(this)); + }); // All series should have equal length - data.forEach(function(series, index) { + data.forEach(function(series) { if (series.data.length > series_min_length) { series.data.length = series_min_length; } http://git-wip-us.apache.org/repos/asf/ambari/blob/dfc77fb2/ambari-web/test/controllers/installer_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/controllers/installer_test.js b/ambari-web/test/controllers/installer_test.js index 14a323d..93c2dd2 100644 --- a/ambari-web/test/controllers/installer_test.js +++ b/ambari-web/test/controllers/installer_test.js @@ -36,11 +36,893 @@ describe('App.InstallerController', function () { it ('Correct data', function() { installerController.loadStacksVersionsSuccessCallback(require('test/stack')); expect(installerController.get('content.stacks.length')).to.equal(2); - expect(installerController.get('content.stacks').everyProperty('isSelected')).to.equal(false); + expect(installerController.get('content.stacks').everyProperty('isSelected')).to.be.false; expect(installerController.get('content.stacks').mapProperty('id')).to.eql(['HDP-2.1','HDP-1.3']); }); }); + describe('#getCluster', function() { + it ('Should return merged clusterStatusTemplate', function() { + installerController.set('clusterStatusTemplate', { + name: 'template' + }); + expect(installerController.getCluster()).to.eql({ + name: 'template' + }); + }); + }); + + describe('#getHosts', function() { + it ('Should return empty array', function() { + expect(installerController.getHosts()).to.eql([]); + }); + }); + + describe('#loadServices', function() { + it ('Should resolve nothing', function() { + var res = installerController.loadServices(); + res.then(function(data){ + expect(data).to.be.undefined; + }); + }); + }); + + describe('#checkRepoURL', function() { + beforeEach(function () { + sinon.stub(App.ajax, 'send', function(data){ + return null; + }); + }); + afterEach(function () { + App.ajax.send.restore(); + }); + it ('Should reload installed stacks', function() { + var stacks = Em.A([ + Em.Object.create({ + isSelected: false + }), + Em.Object.create({ + isSelected: true, + reload: false, + id: 'nn-cc', + repositories: Em.A([ + Em.Object.create({ + isSelected: true + }) + ]), + operatingSystems: Em.A([ + Em.Object.create({ + isSelected: true, + repositories: Em.A([ + Em.Object.create({ + errorTitle: '1', + errorContent: '1', + validation: '' + }) + ]) + }) + ]) + }) + ]); + var wizard = Em.Object.create({ + skipValidationChecked: true + }); + installerController.set('content.stacks', stacks); + installerController.checkRepoURL(wizard); + + var expected = [ + { + "isSelected": false + }, + { + "isSelected": true, + "reload": true, + "id": "nn-cc", + "repositories": [ + { + "isSelected": true + } + ], + "operatingSystems": [ + { + "isSelected": true, + "repositories": [ + { + "errorTitle": "", + "errorContent": "", + "validation": "icon-repeat" + } + ] + } + ] + } + ]; + + var res = JSON.parse(JSON.stringify(installerController.get('content.stacks'))); + + expect(res).to.be.eql(expected); + }); + }); + + describe('#checkRepoURLSuccessCallback', function() { + it ('Should check stacks for sucess', function() { + var stacks = Em.A([ + Em.Object.create({ + isSelected: false + }), + Em.Object.create({ + isSelected: true, + reload: false, + id: 'nn-cc', + repositories: Em.A([ + Em.Object.create({ + repoId: 11, + isSelected: true + }) + ]), + operatingSystems: Em.A([ + Em.Object.create({ + isSelected: true, + id: 1, + repositories: Em.A([ + Em.Object.create({ + repoId: 11, + errorTitle: '1', + errorContent: '1', + validation: '' + }) + ]) + }) + ]) + }) + ]); + var resolve = false; + var data = { + osId: 1, + repoId: 11, + dfd: { + resolve: function() { + resolve = true; + } + } + }; + installerController.set('content.stacks', stacks); + installerController.checkRepoURLSuccessCallback(null,null,data); + + var expected = [ + { + "isSelected": false + }, + { + "isSelected": true, + "reload": false, + "id": "nn-cc", + "repositories": [ + { + "repoId": 11, + "isSelected": true + } + ], + "operatingSystems": [ + { + "isSelected": true, + "id": 1, + "repositories": [ + { + "repoId": 11, + "errorTitle": "1", + "errorContent": "1", + "validation": "icon-ok" + } + ] + } + ] + } + ]; + + var res = JSON.parse(JSON.stringify(installerController.get('content.stacks'))); + expect(resolve).to.be.true; + expect(res).to.be.eql(expected); + }); + }); + + describe('#checkRepoURLErrorCallback', function() { + it ('Should check stacks for error', function() { + var stacks = Em.A([ + Em.Object.create({ + isSelected: false + }), + Em.Object.create({ + isSelected: true, + reload: false, + id: 'nn-cc', + repositories: Em.A([ + Em.Object.create({ + repoId: 11, + isSelected: true + }) + ]), + operatingSystems: Em.A([ + Em.Object.create({ + isSelected: true, + id: 1, + repositories: Em.A([ + Em.Object.create({ + repoId: 11, + errorTitle: '1', + errorContent: '1', + validation: '' + }) + ]) + }) + ]) + }) + ]); + var resolve = false; + var data = { + osId: 1, + repoId: 11, + dfd: { + reject: function() { + resolve = true; + } + } + }; + var req = { + status: 500, + statusText: 'error' + }; + installerController.set('content.stacks', stacks); + installerController.checkRepoURLErrorCallback(req,{},{},{},data); + + var expected = [ + { + "isSelected": false + }, + { + "isSelected": true, + "reload": false, + "id": "nn-cc", + "repositories": [ + { + "repoId": 11, + "isSelected": true + } + ], + "operatingSystems": [ + { + "isSelected": true, + "id": 1, + "repositories": [ + { + "repoId": 11, + "errorTitle": "500:error", + "errorContent": "", + "validation": "icon-exclamation-sign" + } + ] + } + ] + } + ]; + + var res = JSON.parse(JSON.stringify(installerController.get('content.stacks'))); + expect(resolve).to.be.true; + expect(res).to.be.eql(expected); + }); + }); + + describe('#loadStacks', function() { + it ('Should resolve promise with true', function() { + installerController.set('content.stacks', Em.Object.create({ + length: 2 + })); + var res = installerController.loadStacks(); + res.then(function(data){ + expect(data).to.be.true; + }); + }); + it ('Should resolve promise with false', function() { + installerController.set('content.stacks', null); + var res = installerController.loadStacks(); + res.then(function(data){ + expect(data).to.be.false; + }); + }); + }); + + describe('#setLowerStepsDisable', function() { + it ('Should disable lower steps', function() { + var steps = Em.A([ + Em.Object.create({ + step: 0, + value: false + }), + Em.Object.create({ + step: 1, + value: false + }), + Em.Object.create({ + step: 2, + value: false + }), + Em.Object.create({ + step: 3, + value: false + }), + Em.Object.create({ + step: 4, + value: false + }) + ]); + installerController.set('isStepDisabled', steps); + installerController.setLowerStepsDisable(3); + var expected = [ + { + "step": 0, + "value": true + }, + { + "step": 1, + "value": true + }, + { + "step": 2, + "value": true + }, + { + "step": 3, + "value": false + }, + { + "step": 4, + "value": false + } + ]; + + var res = JSON.parse(JSON.stringify(installerController.get('isStepDisabled'))); + + expect(res).to.eql(expected); + }); + }); + + describe('#setStepsEnable', function() { + it ('Should enable next steps', function() { + var steps = Em.A([ + Em.Object.create({ + step: 0, + value: false + }), + Em.Object.create({ + step: 1, + value: false + }), + Em.Object.create({ + step: 2, + value: false + }), + Em.Object.create({ + step: 3, + value: false + }), + Em.Object.create({ + step: 4, + value: false + }) + ]); + installerController.set('isStepDisabled', steps); + installerController.totalSteps = steps.length - 1; + installerController.set('currentStep',2); + var expected = [ + { + "step": 0, + "value": false + }, + { + "step": 1, + "value": true + }, + { + "step": 2, + "value": true + }, + { + "step": 3, + "value": true + }, + { + "step": 4, + "value": true + } + ]; + + var res = JSON.parse(JSON.stringify(installerController.get('isStepDisabled'))); + + expect(res).to.eql(expected); + }); + }); + + describe('#loadMap', function() { + it ('Should load cluster', function() { + var loadCluster = false; + var checker = { + load: function() { + loadCluster = true; + } + }; + installerController.loadMap['0'][0].callback.call(checker); + expect(loadCluster).to.be.true; + }); + it ('Should load stacks', function() { + var loadStacks = false; + var checker = { + loadStacks: function() { + loadStacks = true; + } + }; + installerController.loadMap['1'][0].callback.call(checker); + expect(loadStacks).to.be.true; + }); + it ('Should load stacks async', function() { + var loadStacksVersions = false; + var checker = { + loadStacksVersions: function() { + loadStacksVersions = true; + } + }; + installerController.loadMap['1'][1].callback.call(checker, true).then(function(data){ + expect(data).to.be.true; + }); + expect(loadStacksVersions).to.be.false; + }); + it ('Should load installOptions', function() { + var loadStacks = false; + var checker = { + load: function() { + loadStacks = true; + } + }; + installerController.loadMap['2'][0].callback.call(checker); + expect(loadStacks).to.be.true; + }); + it ('Should load loadConfirmedHosts', function() { + var loadConfirmedHosts = false; + var checker = { + loadConfirmedHosts: function() { + loadConfirmedHosts = true; + } + }; + installerController.loadMap['3'][0].callback.call(checker); + expect(loadConfirmedHosts).to.be.true; + }); + it ('Should load loadServices', function() { + var loadServices = false; + var checker = { + loadServices: function() { + loadServices = true; + } + }; + installerController.loadMap['4'][0].callback.call(checker); + expect(loadServices).to.be.true; + }); + it ('Should load loadServices', function() { + var setSkipSlavesStep = false; + var loadMasterComponentHosts = false; + var loadConfirmedHosts = false; + var loadRecommendations = false; + + var checker = { + setSkipSlavesStep: function() { + setSkipSlavesStep = true; + }, + loadMasterComponentHosts: function() { + loadMasterComponentHosts = true; + }, + loadConfirmedHosts: function() { + loadConfirmedHosts = true; + }, + loadRecommendations: function() { + loadRecommendations = true; + } + }; + installerController.loadMap['5'][0].callback.call(checker); + expect(loadConfirmedHosts).to.be.true; + expect(setSkipSlavesStep).to.be.true; + expect(loadMasterComponentHosts).to.be.true; + expect(loadRecommendations).to.be.true; + + }); + it ('Should load serviceConfigGroups', function() { + var loadServiceConfigGroups = false; + var loadServiceConfigProperties = false; + var loadCurrentHostGroups = false; + var loadRecommendationsConfigs = false; + var loadConfigThemes = false; + + var checker = { + loadServiceConfigGroups: function() { + loadServiceConfigGroups = true; + }, + loadServiceConfigProperties: function() { + loadServiceConfigProperties = true; + }, + loadCurrentHostGroups: function() { + loadCurrentHostGroups = true; + }, + loadRecommendationsConfigs: function() { + loadRecommendationsConfigs = true; + }, + loadConfigThemes: function() { + loadConfigThemes = true; + } + }; + installerController.loadMap['7'][0].callback.call(checker); + expect(loadServiceConfigGroups).to.be.true; + expect(loadServiceConfigProperties).to.be.true; + expect(loadCurrentHostGroups).to.be.true; + expect(loadRecommendationsConfigs).to.be.true; + expect(loadConfigThemes).to.be.true; + }); + it ('Should load clients', function() { + var loadSlaveComponentHosts = false; + var loadClients = false; + var loadRecommendations = false; + + var checker = { + loadSlaveComponentHosts: function() { + loadSlaveComponentHosts = true; + }, + loadClients: function() { + loadClients = true; + }, + loadRecommendations: function() { + loadRecommendations = true; + } + }; + installerController.loadMap['6'][0].callback.call(checker); + expect(loadSlaveComponentHosts).to.be.true; + expect(loadClients).to.be.true; + expect(loadRecommendations).to.be.true; + }); + }); + + describe('#removeHosts', function() { + var hostsDb = { + 'h1': {}, + 'h2': {}, + 'h3': {}, + 'h4': {} + }; + beforeEach(function () { + sinon.stub(installerController, 'getDBProperty').returns(hostsDb); + }); + afterEach(function () { + installerController.getDBProperty.restore(); + }); + it ('Should remove hosts from the list', function() { + var hosts = Em.A([ + { + name: 'h1' + }, + { + name: 'h2' + }, + { + name: 'h3' + } + ]); + installerController.removeHosts(hosts); + expect(hostsDb).to.eql({ + 'h4': {} + }); + }); + }); + + describe('#allHosts', function() { + it ('Should return hosts', function() { + var hosts = { + 'h1': { + disk_info: Em.A([{ + available: 1, + size: 10 + }]), + hostComponents: Em.A([]) + } + }; + var masterComponentHosts = Em.A([ + { + hostName: 'h1', + component: 'component', + display_name: 'n1' + } + ]); + var slaveComponentHosts = Em.A([ + { + hosts: Em.A([ + { + hostName: 'h1' + } + ]) + } + ]); + installerController.set('content.hosts', hosts); + installerController.set('content.masterComponentHosts', masterComponentHosts); + installerController.set('content.slaveComponentHosts', slaveComponentHosts); + var res = JSON.parse(JSON.stringify(installerController.get('allHosts'))); + expect(res).to.eql([ + { + "diskInfo": [ + { + "available": 1, + "size": 10 + } + ], + "diskTotal": 0.0000095367431640625, + "diskFree": 9.5367431640625e-7, + "hostComponents": [ + { + "componentName": "component", + "displayName": "n1" + }, + {} + ] + } + ]); + }); + }); + + describe('#loadServiceConfigProperties', function() { + beforeEach(function () { + sinon.stub(installerController, 'getDBProperty').returns({ + value: 2 + }); + }); + afterEach(function () { + installerController.getDBProperty.restore(); + }); + it ('Should load service config property', function() { + installerController.loadServiceConfigProperties(); + expect(installerController.get('content.serviceConfigProperties')).to.eql({ + "value": 2 + }); + }); + }); + + describe('#saveServices', function() { + it ('Should return correct names', function() { + var stepController = Em.A([ + Em.Object.create({ + isInstalled: true, + isSelected: true, + serviceName: 'i1' + }), + Em.Object.create({ + isInstalled: false, + isSelected: true, + serviceName: 'i2' + }), + Em.Object.create({ + isInstalled: true, + isSelected: false, + serviceName: 'i3' + }) + ]); + installerController.saveServices(stepController); + expect(installerController.get('content.selectedServiceNames')).to.eql(['i1','i2']); + expect(installerController.get('content.installedServiceNames')).to.eql(['i1','i3']); + }); + }); + + describe('#saveClients', function() { + it ('Should return correct clients names', function() { + var stepController = Em.Object.create({ + content: Em.A([ + Em.Object.create({ + isInstalled: true, + isSelected: true, + serviceName: 'i1', + serviceComponents: Em.A([ + Em.Object.create({ + isClient: true, + componentName: 'name', + displayName: 'dname' + }) + ]) + }), + Em.Object.create({ + isInstalled: false, + isSelected: true, + serviceName: 'i2', + serviceComponents: Em.A([ + Em.Object.create({ + isClient: false + }) + ]) + }), + Em.Object.create({ + isInstalled: true, + isSelected: false, + serviceName: 'i3', + serviceComponents: Em.A([ + Em.Object.create({ + isClient: false + }) + ]) + }) + ]) + }); + installerController.saveClients(stepController); + var res = JSON.parse(JSON.stringify(installerController.get('content.clients'))); + expect(res).to.eql([ + { + "component_name": "name", + "display_name": "dname", + "isInstalled": false + } + ]); + }); + }); + + describe('#saveMasterComponentHosts', function() { + beforeEach(function () { + sinon.stub(installerController, 'getDBProperty').returns({ + 'h1': { + id: 11 + }, + 'h3': { + id: 13 + }, + 'h2': { + id: 12 + } + }); + }); + afterEach(function () { + installerController.getDBProperty.restore(); + }); + it ('Should return hosts', function() { + var stepController = Em.Object.create({ + selectedServicesMasters: Em.A([ + Em.Object.create({ + display_name: 'n1', + component_name: 'c1', + serviceId: 1, + selectedHost: 'h1' + }) + ]) + }); + installerController.saveMasterComponentHosts(stepController); + expect(installerController.get('content.masterComponentHosts')).to.eql([ + { + "display_name": "n1", + "component": "c1", + "serviceId": 1, + "isInstalled": false, + "host_id": 11 + } + ]); + }); + }); + + describe('#loadConfirmedHosts', function() { + beforeEach(function () { + sinon.stub(installerController, 'getDBProperty').returns({ + 'h1': { + id: 11 + }, + 'h3': { + id: 13 + }, + 'h2': { + id: 12 + } + }); + }); + afterEach(function () { + installerController.getDBProperty.restore(); + }); + it ('Should load hosts from db', function() { + installerController.loadConfirmedHosts(); + expect(installerController.get('content.hosts')).to.eql({ + 'h1': { + id: 11 + }, + 'h3': { + id: 13 + }, + 'h2': { + id: 12 + } + }); + }); + }); + + describe('#loadMasterComponentHosts', function() { + beforeEach(function () { + sinon.stub(installerController, 'getDBProperty', function(key) { + if (key == 'hosts') { + return { + 'h1': { + id: 11 + }, + 'h3': { + id: 13 + }, + 'h2': { + id: 12 + } + } + } else { + return Em.A([ + { + hostName: '', + host_id: 11 + } + ]); + } + }); + }); + afterEach(function () { + installerController.getDBProperty.restore(); + }); + it ('Should load hosts', function() { + installerController.loadMasterComponentHosts(); + expect(installerController.get('content.masterComponentHosts')).to.eql([ + { + "hostName": "h1", + "host_id": 11 + } + ]); + }); + }); + + describe('#loadSlaveComponentHosts', function() { + beforeEach(function () { + sinon.stub(installerController, 'getDBProperty', function(key) { + if (key == 'hosts') { + return { + 'h1': { + id: 11 + }, + 'h3': { + id: 13 + }, + 'h2': { + id: 12 + } + } + } else { + return Em.A([ + { + hosts: Em.A([ + { + hostName: '', + host_id: 11 + } + ]) + } + ]); + } + }); + }); + afterEach(function () { + installerController.getDBProperty.restore(); + }); + it ('Should load slave hosts', function() { + installerController.loadSlaveComponentHosts(); + expect(installerController.get('content.slaveComponentHosts')).to.eql([ + { + "hosts": [ + { + "hostName": "h1", + "host_id": 11 + } + ] + } + ]); + }); + }); + describe('#getServerVersionSuccessCallback', function () { var cases = [
