Repository: ambari Updated Branches: refs/heads/trunk 7c2dd3944 -> 8cd6cfc6f
AMBARI-13076. Incorrect UI behaviour if host registration request fails (alexantonenko) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/8cd6cfc6 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/8cd6cfc6 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/8cd6cfc6 Branch: refs/heads/trunk Commit: 8cd6cfc6f01f224195a76e3ad362be41e69d17bb Parents: 7c2dd39 Author: Alex Antonenko <[email protected]> Authored: Fri Sep 11 18:41:45 2015 +0300 Committer: Alex Antonenko <[email protected]> Committed: Fri Sep 11 18:41:45 2015 +0300 ---------------------------------------------------------------------- .../app/controllers/wizard/step3_controller.js | 50 +++------ .../app/controllers/wizard/step9_controller.js | 40 +++---- ambari-web/app/mixins/common/reload_popup.js | 36 ++++++- ambari-web/app/utils/polling.js | 41 +++---- .../test/controllers/wizard/step3_test.js | 6 +- .../test/controllers/wizard/step6_test.js | 9 +- .../test/controllers/wizard/step7_test.js | 6 +- .../test/controllers/wizard/step8_test.js | 5 + .../test/controllers/wizard/step9_test.js | 4 +- .../test/mixins/common/reload_popup_test.js | 107 +++++++++++++++++++ 10 files changed, 217 insertions(+), 87 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/8cd6cfc6/ambari-web/app/controllers/wizard/step3_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/wizard/step3_controller.js b/ambari-web/app/controllers/wizard/step3_controller.js index 1e707c9..8905993 100644 --- a/ambari-web/app/controllers/wizard/step3_controller.js +++ b/ambari-web/app/controllers/wizard/step3_controller.js @@ -541,7 +541,6 @@ App.WizardStep3Controller = Em.Controller.extend(App.ReloadPopupMixin, { * @return {$.ajax|null} */ doBootstrap: function () { - var self = this; if (this.get('stopBootstrap')) { return null; } @@ -552,23 +551,14 @@ App.WizardStep3Controller = Em.Controller.extend(App.ReloadPopupMixin, { sender: this, data: { bootRequestId: this.get('content.installOptions.bootRequestId'), - numPolls: this.get('numPolls') + numPolls: this.get('numPolls'), + errorLogMessage: 'Bootstrap failed', + callback: this.doBootstrap, + shouldUseDefaultHandler: true }, - success: 'doBootstrapSuccessCallback' - }). - retry({ - times: App.maxRetries, - timeout: App.timeout - }). - then( - function () { - self.closeReloadPopup(); - }, - function () { - self.showReloadPopup(); - console.log('Bootstrap failed'); - } - ); + success: 'doBootstrapSuccessCallback', + error: 'reloadErrorCallback' + }); }, /** @@ -579,6 +569,7 @@ App.WizardStep3Controller = Em.Controller.extend(App.ReloadPopupMixin, { doBootstrapSuccessCallback: function (data) { var self = this; var pollingInterval = 3000; + this.reloadSuccessCallback(); if (Em.isNone(data.hostsStatus)) { console.log('Invalid response, setting timeout'); window.setTimeout(function () { @@ -646,25 +637,17 @@ App.WizardStep3Controller = Em.Controller.extend(App.ReloadPopupMixin, { if (this.get('stopBootstrap')) { return null; } - var self = this; return App.ajax.send({ name: 'wizard.step3.is_hosts_registered', sender: this, - success: 'isHostsRegisteredSuccessCallback' - }). - retry({ - times: App.maxRetries, - timeout: App.timeout - }). - then( - function () { - self.closeReloadPopup(); - }, - function () { - self.showReloadPopup(); - console.log('Error: Getting registered host information from the server'); - } - ); + success: 'isHostsRegisteredSuccessCallback', + error: 'reloadErrorCallback', + data: { + errorLogMessage: 'Error: Getting registered host information from the server', + callback: this.isHostsRegistered, + shouldUseDefaultHandler: true + } + }); }, /** @@ -676,6 +659,7 @@ App.WizardStep3Controller = Em.Controller.extend(App.ReloadPopupMixin, { console.log('registration attempt...'); var hosts = this.get('bootHosts'); var jsonData = data; + this.reloadSuccessCallback(); if (!jsonData) { console.warn("Error: jsonData is null"); return; http://git-wip-us.apache.org/repos/asf/ambari/blob/8cd6cfc6/ambari-web/app/controllers/wizard/step9_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/wizard/step9_controller.js b/ambari-web/app/controllers/wizard/step9_controller.js index abfb56a..bd1d173 100644 --- a/ambari-web/app/controllers/wizard/step9_controller.js +++ b/ambari-web/app/controllers/wizard/step9_controller.js @@ -1033,7 +1033,6 @@ App.WizardStep9Controller = Em.Controller.extend(App.ReloadPopupMixin, { * @return {$.ajax|null} */ getLogsByRequest: function (polling, requestId) { - var self = this; return App.ajax.send({ name: 'wizard.step9.load_log', sender: this, @@ -1041,19 +1040,15 @@ App.WizardStep9Controller = Em.Controller.extend(App.ReloadPopupMixin, { polling: polling, cluster: this.get('content.cluster.name'), requestId: requestId, - numPolls: this.get('numPolls') - }, - success: 'getLogsByRequestSuccessCallback', - error: 'getLogsByRequestErrorCallback' - }).retry({times: App.maxRetries, timeout: 3000}).then( - function () { - self.closeReloadPopup(); + numPolls: this.get('numPolls'), + callback: this.getLogsByRequest, + args: [polling, requestId], + timeout: 3000, + errorLogMessage: 'Install services all retries failed' }, - function () { - self.showReloadPopup(); - console.log('Install services all retries failed'); - } - ); + success: 'reloadSuccessCallback', + error: 'reloadErrorCallback' + }); }, /** @@ -1061,10 +1056,11 @@ App.WizardStep9Controller = Em.Controller.extend(App.ReloadPopupMixin, { * @param {object} data * @param {object} opt * @param {object} params - * @method getLogsByRequestSuccessCallback + * @method reloadSuccessCallback */ - getLogsByRequestSuccessCallback: function (data, opt, params) { + reloadSuccessCallback: function (data, opt, params) { var parsedData = jQuery.parseJSON(data); + this._super(); console.log("TRACE: In success function for the GET logs data"); console.log("TRACE: Step9 -> The value is: ", parsedData); this.set('isPolling', params.polling); @@ -1073,10 +1069,18 @@ App.WizardStep9Controller = Em.Controller.extend(App.ReloadPopupMixin, { /** * Error-callback for get log by request - * @method getLogsByRequestErrorCallback + * @param {object} jqXHR + * @param {string} ajaxOptions + * @param {string} error + * @param {object} opt + * @param {object} params + * @method reloadErrorCallback */ - getLogsByRequestErrorCallback: function () { - this.loadLogData(true); + reloadErrorCallback: function (jqXHR, ajaxOptions, error, opt, params) { + this._super(jqXHR, ajaxOptions, error, opt, params); + if (jqXHR.status) { + this.loadLogData(true); + } }, /** http://git-wip-us.apache.org/repos/asf/ambari/blob/8cd6cfc6/ambari-web/app/mixins/common/reload_popup.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/mixins/common/reload_popup.js b/ambari-web/app/mixins/common/reload_popup.js index 539d1d5..1a2a9be 100644 --- a/ambari-web/app/mixins/common/reload_popup.js +++ b/ambari-web/app/mixins/common/reload_popup.js @@ -20,8 +20,39 @@ var App = require('app'); App.ReloadPopupMixin = Em.Mixin.create({ + retryCount: 0, + reloadPopup: null, + reloadSuccessCallback: function () { + this.closeReloadPopup(); + }, + + reloadErrorCallback: function (jqXHR, ajaxOptions, error, opt, params) { + if (jqXHR.status) { + if (params.errorLogMessage) { + console.log(params.errorLogMessage); + } + this.closeReloadPopup(); + if (params.shouldUseDefaultHandler) { + App.ajax.defaultErrorHandler(jqXHR, opt.url, opt.method, jqXHR.status); + } + } else { + var times = Em.isNone(params.times) ? App.get('maxRetries') : params.times, + timeout = Em.isNone(params.timeout) ? App.get('timeout') : params.timeout; + this.showReloadPopup(); + if (this.get('retryCount') < times) { + if (params.callback) { + var self = this; + window.setTimeout(function () { + params.callback.apply(self, params.args || []); + }, timeout); + } + this.incrementProperty('retryCount'); + } + } + }, + showReloadPopup: function () { var self = this; if (!this.get('reloadPopup')) { @@ -35,7 +66,10 @@ App.ReloadPopupMixin = Em.Mixin.create({ this.t('app.reloadPopup.link') + "</a></div>", encodeBody: false, onClose: function () { - self.set('reloadPopup', null); + self.setProperties({ + reloadPopup: null, + retryCount: 0 + }); this._super(); } })); http://git-wip-us.apache.org/repos/asf/ambari/blob/8cd6cfc6/ambari-web/app/utils/polling.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/utils/polling.js b/ambari-web/app/utils/polling.js index 339efcf..7442a31 100644 --- a/ambari-web/app/utils/polling.js +++ b/ambari-web/app/utils/polling.js @@ -151,34 +151,26 @@ App.Poll = Em.Object.extend(App.ReloadPopupMixin, { */ startPolling: function () { if (!this.get('requestId')) return false; - var self = this; this.pollTaskLog(); App.ajax.send({ name: 'background_operations.get_by_request', sender: this, data: { - requestId: this.get('requestId') + requestId: this.get('requestId'), + callback: this.startPolling, + errorLogMessage: 'Install services all retries failed' }, - success: 'startPollingSuccessCallback', - error: 'startPollingErrorCallback' - }) - .retry({times: App.maxRetries, timeout: App.timeout}) - .then( - function () { - self.closeReloadPopup(); - }, - function () { - self.showReloadPopup(); - console.log('Install services all retries failed'); - } - ); + success: 'reloadSuccessCallback', + error: 'reloadErrorCallback' + }); return true; }, - startPollingSuccessCallback: function (data) { + reloadSuccessCallback: function (data) { var self = this; var result = this.parseInfo(data); + this._super(); if (!result) { window.setTimeout(function () { self.startPolling(); @@ -186,12 +178,15 @@ App.Poll = Em.Object.extend(App.ReloadPopupMixin, { } }, - startPollingErrorCallback: function (request, ajaxOptions, error) { - console.log("TRACE: In error function for the GET data"); - console.log("TRACE: value of the url is: " + url); - console.log("TRACE: error code status is: " + request.status); - if (!this.get('isSuccess')) { - this.set('isError', true); + reloadErrorCallback: function (request, ajaxOptions, error, opt, params) { + this._super(request, ajaxOptions, error, opt, params); + if (request.status) { + console.log("TRACE: In error function for the GET data"); + console.log("TRACE: value of the url is: " + url); + console.log("TRACE: error code status is: " + request.status); + if (!this.get('isSuccess')) { + this.set('isError', true); + } } }, @@ -244,8 +239,6 @@ App.Poll = Em.Object.extend(App.ReloadPopupMixin, { parseInfo: function (polledData) { console.log('TRACE: Entering task info function'); - var self = this; - var totalProgress = 0; var tasksData = polledData.tasks; console.log("The value of tasksData is: ", tasksData); if (!tasksData) { http://git-wip-us.apache.org/repos/asf/ambari/blob/8cd6cfc6/ambari-web/test/controllers/wizard/step3_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/controllers/wizard/step3_test.js b/ambari-web/test/controllers/wizard/step3_test.js index aede550..6cab32a 100644 --- a/ambari-web/test/controllers/wizard/step3_test.js +++ b/ambari-web/test/controllers/wizard/step3_test.js @@ -811,11 +811,7 @@ describe('App.WizardStep3Controller', function () { describe('#isHostsRegistered', function () { beforeEach(function () { - sinon.stub(App.ajax, 'send', function () { - return {retry: function () { - return {then: Em.K} - }} - }); + sinon.stub(App.ajax, 'send', Em.K); }); afterEach(function () { App.ajax.send.restore(); http://git-wip-us.apache.org/repos/asf/ambari/blob/8cd6cfc6/ambari-web/test/controllers/wizard/step6_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/controllers/wizard/step6_test.js b/ambari-web/test/controllers/wizard/step6_test.js index cc53d6f..b5630c6 100644 --- a/ambari-web/test/controllers/wizard/step6_test.js +++ b/ambari-web/test/controllers/wizard/step6_test.js @@ -47,6 +47,7 @@ var controller, describe('App.WizardStep6Controller', function () { beforeEach(function () { + sinon.stub(console, 'error', Em.K); controller = App.WizardStep6Controller.create(); controller.set('content', Em.Object.create({ hosts: {}, @@ -71,6 +72,10 @@ describe('App.WizardStep6Controller', function () { }); + afterEach(function () { + console.error.restore(); + }); + describe('#isAddHostWizard', function () { it('true if content.controllerName is addHostController', function () { controller.set('content.controllerName', 'addHostController'); @@ -289,7 +294,7 @@ describe('App.WizardStep6Controller', function () { }; controller.set('content.hosts', hosts); controller.set('content.masterComponentHosts', masterComponentHosts); - controller.set('content.recommendations', recommendations) + controller.set('content.recommendations', recommendations); controller.set('headers', headers); controller.render(); expect(controller.get('isLoaded')).to.equal(true); @@ -485,7 +490,7 @@ describe('App.WizardStep6Controller', function () { ]) }) ]) - }) + }); controller.updateValidationsSuccessCallback(validationData); expect(controller.get('generalErrorMessages').length).to.equal(0); expect(controller.get('generalWarningMessages').length).to.equal(0); http://git-wip-us.apache.org/repos/asf/ambari/blob/8cd6cfc6/ambari-web/test/controllers/wizard/step7_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/controllers/wizard/step7_test.js b/ambari-web/test/controllers/wizard/step7_test.js index 8bf9ca7..d60dc15 100644 --- a/ambari-web/test/controllers/wizard/step7_test.js +++ b/ambari-web/test/controllers/wizard/step7_test.js @@ -106,10 +106,12 @@ describe('App.InstallerStep7Controller', function () { serviceConfigProperties: [] } }); + sinon.stub(console, 'error', Em.K); }); afterEach(function() { App.config.setPreDefinedServiceConfigs.restore(); + console.error.restore(); }); describe('#installedServiceNames', function () { @@ -288,7 +290,7 @@ describe('App.InstallerStep7Controller', function () { site1: true, site3: true }; - var siteToTagMap = installerStep7Controller._createSiteToTagMap(desired_configs,sites) + var siteToTagMap = installerStep7Controller._createSiteToTagMap(desired_configs,sites); expect(siteToTagMap).to.eql({ site1: "tag1", site3: "tag3" @@ -520,7 +522,7 @@ describe('App.InstallerStep7Controller', function () { desired_configs: desired_configs } }; - var siteToTagMap = installerStep7Controller.getConfigTagsSuccess(data) + var siteToTagMap = installerStep7Controller.getConfigTagsSuccess(data); expect(installerStep7Controller.get('serviceConfigTags')).to.eql([ { "siteName": "site1", http://git-wip-us.apache.org/repos/asf/ambari/blob/8cd6cfc6/ambari-web/test/controllers/wizard/step8_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/controllers/wizard/step8_test.js b/ambari-web/test/controllers/wizard/step8_test.js index 5317f07..f1784e3 100644 --- a/ambari-web/test/controllers/wizard/step8_test.js +++ b/ambari-web/test/controllers/wizard/step8_test.js @@ -60,6 +60,11 @@ describe('App.WizardStep8Controller', function () { configs: configs }); configurationController = App.MainServiceInfoConfigsController.create({}); + sinon.stub(console, 'error', Em.K); + }); + + afterEach(function () { + console.error.restore(); }); var siteObjTests = Em.A([ http://git-wip-us.apache.org/repos/asf/ambari/blob/8cd6cfc6/ambari-web/test/controllers/wizard/step9_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/controllers/wizard/step9_test.js b/ambari-web/test/controllers/wizard/step9_test.js index 80982cb..414867f 100644 --- a/ambari-web/test/controllers/wizard/step9_test.js +++ b/ambari-web/test/controllers/wizard/step9_test.js @@ -1318,10 +1318,10 @@ describe('App.InstallerStep9Controller', function () { describe('#startPolling', function () { beforeEach(function () { - sinon.stub(c, 'getLogsByRequestErrorCallback', Em.K); + sinon.stub(c, 'reloadErrorCallback', Em.K); }); afterEach(function () { - c.getLogsByRequestErrorCallback.restore(); + c.reloadErrorCallback.restore(); }); it('should set isSubmitDisabled to true', function () { c.set('isSubmitDisabled', false); http://git-wip-us.apache.org/repos/asf/ambari/blob/8cd6cfc6/ambari-web/test/mixins/common/reload_popup_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/mixins/common/reload_popup_test.js b/ambari-web/test/mixins/common/reload_popup_test.js index 28c865a..1018983 100644 --- a/ambari-web/test/mixins/common/reload_popup_test.js +++ b/ambari-web/test/mixins/common/reload_popup_test.js @@ -51,9 +51,116 @@ describe('App.ReloadPopupMixin', function () { describe('#closeReloadPopup', function () { it('should hide modal popup', function () { + obj.set('retryCount', 1); obj.showReloadPopup(); obj.closeReloadPopup(); expect(obj.get('reloadPopup')).to.be.null; + expect(obj.get('retryCount')).to.equal(0); + }); + + }); + + describe('#reloadSuccessCallback', function () { + + it('should hide modal popup', function () { + obj.set('retryCount', 1); + obj.showReloadPopup(); + obj.reloadSuccessCallback(); + expect(obj.get('reloadPopup')).to.be.null; + expect(obj.get('retryCount')).to.equal(0); + }); + + }); + + describe('#reloadErrorCallback', function () { + + var cases = [ + { + args: [{status: 404}, null, null, {}, {shouldUseDefaultHandler: true}], + closeReloadPopupCallCount: 1, + consoleLogCallCount: 0, + defaultErrorHandlerCallCount: 1, + showReloadPopupCallCount: 0, + setTimeoutCount: 0, + title: 'status received, no console message, default error handler' + }, + { + args: [{status: 404}, null, null, {}, {errorLogMessage: 'error'}], + closeReloadPopupCallCount: 1, + consoleLogCallCount: 1, + defaultErrorHandlerCallCount: 0, + showReloadPopupCallCount: 0, + setTimeoutCount: 0, + title: 'status received, console message displayed, no default error handler' + }, + { + args: [{status: 0}, null, null, {}, {times: 5}], + retryCount: 5, + retryCountResult: 5, + closeReloadPopupCallCount: 0, + consoleLogCallCount: 0, + defaultErrorHandlerCallCount: 0, + showReloadPopupCallCount: 1, + setTimeoutCount: 0, + title: 'no status received, custom retries count, max retries reached' + }, + { + args: [{status: 0}, null, null, {}, {}], + retryCount: 2, + retryCountResult: 3, + closeReloadPopupCallCount: 0, + consoleLogCallCount: 0, + defaultErrorHandlerCallCount: 0, + showReloadPopupCallCount: 1, + setTimeoutCount: 0, + title: 'no status received, default retries count, max retries not reached, no callback' + }, + { + args: [{status: 0}, null, null, {}, {callback: Em.K}], + retryCount: 2, + retryCountResult: 3, + closeReloadPopupCallCount: 0, + consoleLogCallCount: 0, + defaultErrorHandlerCallCount: 0, + showReloadPopupCallCount: 1, + setTimeoutCount: 1, + title: 'no status received, default retries count, max retries not reached, callback specified' + } + ]; + + beforeEach(function () { + sinon.stub(obj, 'closeReloadPopup', Em.K); + sinon.stub(console, 'log', Em.K); + sinon.stub(App.ajax, 'defaultErrorHandler', Em.K); + sinon.stub(obj, 'showReloadPopup', Em.K); + sinon.stub(App, 'get').withArgs('maxRetries').returns(3); + sinon.stub(window, 'setTimeout', Em.K); + }); + + afterEach(function () { + obj.closeReloadPopup.restore(); + console.log.restore(); + App.ajax.defaultErrorHandler.restore(); + obj.showReloadPopup.restore(); + App.get.restore(); + window.setTimeout.restore(); + }); + + cases.forEach(function (item) { + it(item.title, function () { + if (!Em.isNone(item.retryCount)) { + obj.set('retryCount', item.retryCount); + } + obj.reloadErrorCallback.apply(obj, item.args); + expect(obj.closeReloadPopup.callCount).to.equal(item.closeReloadPopupCallCount); + expect(console.log.callCount).to.equal(item.consoleLogCallCount); + expect(App.ajax.defaultErrorHandler.callCount).to.equal(item.defaultErrorHandlerCallCount); + expect(obj.showReloadPopup.callCount).to.equal(item.showReloadPopupCallCount); + expect(window.setTimeout.callCount).to.equal(item.setTimeoutCount); + if (!Em.isNone(item.retryCountResult)) { + obj.set('retryCount', item.retryCountResult); + } + }); }); });
