Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 6AEDF200BD0 for ; Wed, 30 Nov 2016 19:33:43 +0100 (CET) Received: by cust-asf.ponee.io (Postfix) id 695E3160B13; Wed, 30 Nov 2016 18:33:43 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 4F66E160B06 for ; Wed, 30 Nov 2016 19:33:41 +0100 (CET) Received: (qmail 24200 invoked by uid 500); 30 Nov 2016 18:33:40 -0000 Mailing-List: contact commits-help@ambari.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: ambari-dev@ambari.apache.org Delivered-To: mailing list commits@ambari.apache.org Received: (qmail 24191 invoked by uid 99); 30 Nov 2016 18:33:40 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 30 Nov 2016 18:33:40 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 54A4FDFCF7; Wed, 30 Nov 2016 18:33:40 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: atkach@apache.org To: commits@ambari.apache.org Message-Id: X-Mailer: ASF-Git Admin Mailer Subject: ambari git commit: AMBARI-12697 Rolling upgrade: Ambari UI should be able to display rolling upgrade history (dili via atkach) Date: Wed, 30 Nov 2016 18:33:40 +0000 (UTC) archived-at: Wed, 30 Nov 2016 18:33:43 -0000 Repository: ambari Updated Branches: refs/heads/branch-2.5 502cffba1 -> ef4183771 AMBARI-12697 Rolling upgrade: Ambari UI should be able to display rolling upgrade history (dili via atkach) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/ef418377 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/ef418377 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/ef418377 Branch: refs/heads/branch-2.5 Commit: ef41837712fee03772aca344b2edc337396974a0 Parents: 502cffb Author: Andrii Tkach Authored: Wed Nov 30 20:32:16 2016 +0200 Committer: Andrii Tkach Committed: Wed Nov 30 20:32:16 2016 +0200 ---------------------------------------------------------------------- ambari-web/app/assets/test/tests.js | 5 + ambari-web/app/controllers.js | 1 + .../admin/stack_upgrade_history_controller.js | 217 +++++++++++ ambari-web/app/mappers.js | 3 +- .../app/mappers/stack_upgrade_history_mapper.js | 54 +++ ambari-web/app/messages.js | 28 ++ ambari-web/app/models.js | 2 + .../app/models/finished_upgrade_entity.js | 92 +++++ .../stack_version/stack_upgrade_history.js | 37 ++ ambari-web/app/routes/main.js | 7 + ambari-web/app/styles/stack_versions.less | 69 ++++ .../admin/stack_upgrade/upgrade_history.hbs | 105 ++++++ .../stack_upgrade/upgrade_history_details.hbs | 46 +++ ambari-web/app/views.js | 2 + .../views/main/admin/stack_upgrade/menu_view.js | 6 + .../upgrade_history_details_view.js | 85 +++++ .../admin/stack_upgrade/upgrade_history_view.js | 303 +++++++++++++++ .../stack_upgrade_history_controller_test.js | 125 +++++++ .../stack_upgrade_history_mapper_test.js | 372 +++++++++++++++++++ .../test/models/finished_upgrade_entity_test.js | 197 ++++++++++ .../upgrade_history_details_view_test.js | 248 +++++++++++++ .../stack_upgrade/upgrade_history_view_test.js | 173 +++++++++ 22 files changed, 2176 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/ef418377/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 8571fc4..7440819 100644 --- a/ambari-web/app/assets/test/tests.js +++ b/ambari-web/app/assets/test/tests.js @@ -70,6 +70,7 @@ var files = [ 'test/controllers/main/admin/kerberos/step8_controller_test', 'test/controllers/main/admin/stack_and_upgrade_controller_test', + 'test/controllers/main/admin/stack_upgrade_history_controller_test', 'test/controllers/main/admin/serviceAccounts_controller_test', 'test/controllers/main/admin/highAvailability_controller_test', 'test/controllers/main/admin/highAvailability/progress_controller_test', @@ -145,6 +146,7 @@ var files = [ 'test/mappers/users_mapper_test', 'test/mappers/stack_mapper_test', 'test/mappers/stack_service_mapper_test', + 'test/mappers/stack_upgrade_history_mapper_test', 'test/mappers/repository_version_mapper_test', 'test/mappers/configs/config_groups_mapper_test', 'test/mappers/configs/service_config_version_mapper_test', @@ -251,6 +253,8 @@ var files = [ 'test/views/main/admin/stack_upgrade/upgrade_group_view_test', 'test/views/main/admin/stack_upgrade/upgrade_task_view_test', 'test/views/main/admin/stack_upgrade/upgrade_wizard_view_test', + 'test/views/main/admin/stack_upgrade/upgrade_history_view_test', + 'test/views/main/admin/stack_upgrade/upgrade_history_details_view_test', 'test/views/main/admin/stack_upgrade/version_view_test', 'test/views/main/admin/stack_upgrade/services_view_test', 'test/views/main/admin/stack_upgrade/menu_view_test', @@ -384,6 +388,7 @@ var files = [ 'test/models/widget_property_test', 'test/models/host_stack_version_test', 'test/models/upgrade_entity_test', + 'test/models/finished_upgrade_entity_test', 'test/models/configs/sub_section_test', 'test/models/configs/section_test', 'test/models/configs/service_config_version_test', http://git-wip-us.apache.org/repos/asf/ambari/blob/ef418377/ambari-web/app/controllers.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers.js b/ambari-web/app/controllers.js index 5664029..81e5eb7 100644 --- a/ambari-web/app/controllers.js +++ b/ambari-web/app/controllers.js @@ -85,6 +85,7 @@ require('controllers/main/admin/highAvailability/journalNode/step6_controller'); require('controllers/main/admin/highAvailability/journalNode/step7_controller'); require('controllers/main/admin/highAvailability/journalNode/step8_controller'); require('controllers/main/admin/stack_and_upgrade_controller'); +require('controllers/main/admin/stack_upgrade_history_controller'); require('controllers/main/admin/serviceAccounts_controller'); require('utils/polling'); require('controllers/main/admin/kerberos'); http://git-wip-us.apache.org/repos/asf/ambari/blob/ef418377/ambari-web/app/controllers/main/admin/stack_upgrade_history_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/main/admin/stack_upgrade_history_controller.js b/ambari-web/app/controllers/main/admin/stack_upgrade_history_controller.js new file mode 100644 index 0000000..9bec825 --- /dev/null +++ b/ambari-web/app/controllers/main/admin/stack_upgrade_history_controller.js @@ -0,0 +1,217 @@ +/** + * 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'); +var stringUtils = require('utils/string_utils'); + +App.MainAdminStackUpgradeHistoryController = Em.ArrayController.extend({ + name: 'mainAdminStackUpgradeHistoryController', + + startIndex: 1, + + resetStartIndex: false, + + /** + * status of tasks/items/groups which should be grayed out and disabled + * @type {Array} + */ + nonActiveStates: ['PENDING'], + + /** + * mutable properties of Upgrade Task + * @type {Array} + */ + taskDetailsProperties: ['status', 'stdout', 'stderr', 'error_log', 'host_name', 'output_log'], + + /** + * Current upgrade record clicked on the UI + * @type {App.StackUpgradeHistory|null} + * */ + currentUpgradeRecord: null, + + isDowngrade: false, + + upgradeData: null, + + /** + * List of all App.StackUpgradeHistory. Latest one at the beginning + * @type {App.StackUpgradeHistory[]} + */ + content: App.StackUpgradeHistory.find(), + + upgradeHistoryUrl: function() { + return App.get('apiPrefix') + '/clusters/' + App.get('clusterName') + '/upgrades?fields=Upgrade'; + }.property('App.clusterName'), + + upgradeUpgradeRecordUrl: function() { + var record = this.get('currentUpgradeRecord'); + return App.get('apiPrefix') + '/clusters/' + App.get('clusterName') + '/upgrades/' + record.get('requestId'); + }.property('App.clusterName', 'currentUpgradeRecord'), + + loadStackUpgradeHistoryToModel: function () { + console.log('Load stack upgrade history'); + var dfd = $.Deferred(); + App.HttpClient.get(this.get('upgradeHistoryUrl'), App.stackUpgradeHistoryMapper, { + complete: function () { + dfd.resolve(); + } + }); + return dfd.promise(); + }, + + loadStackUpgradeRecord: function () { + var record = this.get('currentUpgradeRecord'); + this.set('isDowngrade', ('DOWNGRADE' == record.get('direction'))) + var dfd = $.Deferred(); + var self = this; + if (record != null) { + App.ajax.send({ + name: 'admin.upgrade.data', + sender: this, + data: { + id: record.get('requestId') + }, + success: 'loadUpgradeRecordSuccessCallback' + }).then(dfd.resolve).complete(function () { + }); + } else { + dfd.resolve(); + } + return dfd.promise(); + }, + + loadUpgradeRecordSuccessCallback: function(newData){ + if (Em.isNone(newData)) { + var record = this.get('currentUpgradeRecord'); + console.debug('No data returned for upgrad record ' + record.get('requestId')) + return; + } + var upgradeGroups = []; + if (newData.upgrade_groups) { + nonActiveStates = this.get('nonActiveStates'), + //wrap all entities into App.finishedUpgradeEntity + newData.upgrade_groups.forEach(function (newGroup) { + var hasExpandableItems = newGroup.upgrade_items.some(function (item) { + return !nonActiveStates.contains(item.UpgradeItem.status); + }), + oldGroup = App.finishedUpgradeEntity.create({type: 'GROUP', hasExpandableItems: hasExpandableItems}, newGroup.UpgradeGroup), + upgradeItems = []; + newGroup.upgrade_items.forEach(function (item) { + var oldItem = App.finishedUpgradeEntity.create({type: 'ITEM'}, item.UpgradeItem); + this.formatMessages(oldItem); + oldItem.set('tasks', []); + upgradeItems.pushObject(oldItem); + }, this); + upgradeItems.reverse(); + oldGroup.set('upgradeItems', upgradeItems); + upgradeGroups.pushObject(oldGroup); + }, this); + upgradeGroups.reverse(); + this.set('upgradeData', Em.Object.create({ + upgradeGroups: upgradeGroups, + upgrade_groups: newData.upgrade_groups, + Upgrade: newData.Upgrade + })); + } + }, + + /** + * format upgrade item text + * @param {App.finishedUpgradeEntity} oldItem + */ + formatMessages: function (oldItem) { + var text = oldItem.get('text'); + var messages = []; + + try { + var messageArray = JSON.parse(text); + for (var i = 0; i < messageArray.length; i++) { + messages.push(messageArray[i].message); + } + oldItem.set('text', messages.join(' ')); + } catch (err) { + console.warn('Upgrade Item has malformed text'); + } + oldItem.set('messages', messages); + }, + + /** + * request Upgrade Item and its tasks from server + * @param {Em.Object} item + * @param {Function} customCallback + * @return {$.ajax} + */ + getUpgradeItem: function (item) { + return App.ajax.send({ + name: 'admin.upgrade.upgrade_item', + sender: this, + data: { + upgradeId: item.get('request_id'), + groupId: item.get('group_id'), + stageId: item.get('stage_id') + }, + success: 'getUpgradeItemSuccessCallback' + }); + }, + + /** + * success callback of getTasks + * @param {object} data + */ + getUpgradeItemSuccessCallback: function (data) { + this.get('upgradeData.upgradeGroups').forEach(function (group) { + if (group.get('group_id') === data.UpgradeItem.group_id) { + group.get('upgradeItems').forEach(function (item) { + if (item.get('stage_id') === data.UpgradeItem.stage_id) { + if (item.get('tasks.length')) { + data.tasks.forEach(function (task) { + var currentTask = item.get('tasks').findProperty('id', task.Tasks.id); + this.get('taskDetailsProperties').forEach(function (property) { + currentTask.set(property, task.Tasks[property]); + }, this); + }, this); + } else { + var tasks = []; + data.tasks.forEach(function (task) { + tasks.pushObject(App.finishedUpgradeEntity.create({type: 'TASK'}, task.Tasks)); + }); + item.set('tasks', tasks); + } + item.set('isTasksLoaded', true); + } + }, this); + } + }, this); + }, + + /** + * status of Upgrade request + * @type {string} + */ + requestStatus: function () { + if (this.get('upgradeData')){ + if (this.get('upgradeData.Upgrade')) { + return this.get('upgradeData.Upgrade.request_status'); + } else { + return ''; + } + } else { + return '' + } + }.property('upgradeData.Upgrade.request_status'), +}); http://git-wip-us.apache.org/repos/asf/ambari/blob/ef418377/ambari-web/app/mappers.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/mappers.js b/ambari-web/app/mappers.js index 96193bc..cde9bcc 100644 --- a/ambari-web/app/mappers.js +++ b/ambari-web/app/mappers.js @@ -43,4 +43,5 @@ require('mappers/alert_groups_mapper'); require('mappers/alert_notification_mapper'); require('mappers/root_service_mapper'); require('mappers/widget_mapper'); -require('mappers/widget_layout_mapper'); \ No newline at end of file +require('mappers/widget_layout_mapper'); +require('mappers/stack_upgrade_history_mapper'); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/ef418377/ambari-web/app/mappers/stack_upgrade_history_mapper.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/mappers/stack_upgrade_history_mapper.js b/ambari-web/app/mappers/stack_upgrade_history_mapper.js new file mode 100644 index 0000000..63088a7 --- /dev/null +++ b/ambari-web/app/mappers/stack_upgrade_history_mapper.js @@ -0,0 +1,54 @@ +/** + * 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'); +var stringUtils = require('utils/string_utils'); + +App.stackUpgradeHistoryMapper = App.QuickDataMapper.create({ + model: App.StackUpgradeHistory, + + config: { + "id": "Upgrade.request_id", + "request_id": "Upgrade.request_id", + "cluster_name": "Upgrade.cluster_name", + "direction": "Upgrade.direction", + "from_version": "Upgrade.from_version", + "to_version": "Upgrade.to_version", + "end_time":"Upgrade.end_time", + "start_time":"Upgrade.start_time", + "create_time": "Upgrade.create_time", + "request_status": "Upgrade.request_status", + "upgrade_type": "Upgrade.upgrade_type", + "downgrade_allowed": "Upgrade.downgrade_allowed", + "skip_failures": "Upgrade.skip_failures", + "skip_service_check_failures": "Upgrade.skip_service_check_failures" + }, + + map: function (json) { + App.set('isStackUpgradeHistoryLoaded',false); + var model = this.get('model'); + var result = []; + json.items.forEach(function(item) { + var parseResult = this.parseIt(item, this.get('config')); + result.push(parseResult); + }, this); + + App.store.loadMany(this.get('model'), result); + App.store.commit(); + App.set('isStackUpgradeHistoryLoaded',true); + }, +}); http://git-wip-us.apache.org/repos/asf/ambari/blob/ef418377/ambari-web/app/messages.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js index 7c3ccd3..5c7e0e8 100644 --- a/ambari-web/app/messages.js +++ b/ambari-web/app/messages.js @@ -130,6 +130,7 @@ Em.I18n.translations = { 'common.open':'Open', 'common.copy':'Copy', 'common.complete':'Complete', + 'common.completed':'Completed', 'common.metrics':'Metrics', 'common.timeRange':'Time Range', 'common.name':'Name', @@ -172,6 +173,7 @@ Em.I18n.translations = { 'common.recommission':'Recommission', 'common.failure': 'Failure', 'common.type': 'Type', + 'common.direction': 'Direction', 'common.close': 'Close', 'common.warning': 'Warning', 'common.critical': 'Critical', @@ -192,6 +194,7 @@ Em.I18n.translations = { 'common.repositories':'Repositories', 'common.stack.versions':'Stack Versions', 'common.versions':'Versions', + 'common.upgrade.history':'Upgrade History', 'common.serviceAccounts': 'Service Accounts', 'common.add': 'Add', 'common.edit': 'Edit', @@ -203,6 +206,7 @@ Em.I18n.translations = { 'common.details':'Details', 'common.stats':'Stats', 'common.abort': 'Abort', + 'common.aborted': 'Aborted', 'common.misc': 'Misc', 'common.userSettings': 'User Settings', 'common.aboutAmbari': 'About', @@ -334,6 +338,14 @@ Em.I18n.translations = { 'common.logs': 'Logs', 'common.warn.message': '
{0}
', 'common.link': 'Link', + 'common.from.version': 'From Version', + 'common.to.version': 'To Version', + 'common.start.time': 'Start Time', + 'common.end.time': 'End Time', + 'common.rolling': 'Rolling', + 'common.express': 'Express', + 'common.rolling.downgrade': 'Rolling Downgrade', + 'common.express.downgrade': 'Express Downgrade', 'models.alert_instance.tiggered.verbose': "Occurred on {0}
Checked on {1}", 'models.alert_definition.triggered.verbose': "Occurred on {0}", @@ -1728,6 +1740,22 @@ Em.I18n.translations = { 'admin.stackVersions.hosts.popup.primary': "Go to Hosts", 'admin.stackVersions.details.install.hosts.popup.title': "Install {0} version", + 'admin.stackVersions.upgradeHistory.upgrade': 'Upgrades', + 'admin.stackVersions.upgradeHistory.downgrade': 'Downgrades', + 'admin.stackVersions.upgradeHistory.show.details': 'Click to show more details on {0}', + 'admin.stackVersions.upgradeHistory.success': 'Sucessful {0}', + 'admin.stackVersions.upgradeHistory.aborted': 'Aborted {0}', + 'admin.stackVersions.upgradeHistory.summary': 'Summary', + 'admin.stackVersions.upgradeHistory.history': 'History', + 'admin.stackVersions.upgradeHistory.filter.all': 'All ({0})', + 'admin.stackVersions.upgradeHistory.filter.upgrade': 'Upgrade ({0})', + 'admin.stackVersions.upgradeHistory.filter.downgrade': 'Downgrade ({0})', + 'admin.stackVersions.upgradeHistory.filter.successful.upgrade': 'Successful Upgrade ({0})', + 'admin.stackVersions.upgradeHistory.filter.successful.downgrade': 'Successful Downgrade ({0})', + 'admin.stackVersions.upgradeHistory.filter.aborted.upgrade': 'Aborted Upgrade ({0})', + 'admin.stackVersions.upgradeHistory.filter.aborted.downgrade': 'Aborted Downgrade ({0})', + 'admin.stackVersions.upgradeHistory.no.history': 'No upgrade/downgrade history available', + 'admin.stackVersions.upgradeHistory.record.title': '{0} {1} to {2}', 'admin.stackUpgrade.preCheck.warning.message': "{0} Warning {1}", 'admin.stackUpgrade.preCheck.bypass.message': "{0} Error {1}", http://git-wip-us.apache.org/repos/asf/ambari/blob/ef418377/ambari-web/app/models.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/models.js b/ambari-web/app/models.js index b877255..e0168a2 100644 --- a/ambari-web/app/models.js +++ b/ambari-web/app/models.js @@ -30,6 +30,7 @@ require('models/stack_version/repository_version'); require('models/stack_version/os'); require('models/stack_version/service_simple'); require('models/stack_version/repository'); +require('models/stack_version/stack_upgrade_history'); require('models/operating_system'); require('models/repository'); require('models/stack_service'); @@ -64,6 +65,7 @@ require('models/master_component'); require('models/host_stack_version'); require('models/root_service'); require('models/upgrade_entity'); +require('models/finished_upgrade_entity'); require('models/configs/theme/theme_condition'); require('models/configs/service_config_version'); require('models/configs/stack_config_property'); http://git-wip-us.apache.org/repos/asf/ambari/blob/ef418377/ambari-web/app/models/finished_upgrade_entity.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/models/finished_upgrade_entity.js b/ambari-web/app/models/finished_upgrade_entity.js new file mode 100644 index 0000000..c08ef45 --- /dev/null +++ b/ambari-web/app/models/finished_upgrade_entity.js @@ -0,0 +1,92 @@ +/** + * 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. + */ + + +/** + * @type {Ember.Object} + * @class + */ +App.finishedUpgradeEntity = Em.Object.extend({ + + /** + * type of entity "GROUP", "ITEM", "TASK" + * @type {string} + */ + type: null, + + /** + * @type {boolean} + */ + isExpanded: false, + + /** + * @type {boolean} + */ + hasExpandableItems: false, + + /** + * @type {boolean} + */ + isVisible: Em.computed.notEqual('status', 'PENDING'), + + /** + * status of tasks/items/groups which should be grayed out and disabled + * @type {Array} + */ + nonActiveStates: ['PENDING'], + + /** + * @type {boolean} + */ + isRunning: Em.computed.existsIn('status', ['IN_PROGRESS']), + + /** + * @type {number} + */ + progress: function () { + return Math.floor(this.get('progress_percent')); + }.property('progress_percent'), + + /** + * indicate whether entity has active link + * @type {boolean} + */ + isActive: function () { + return !this.get('nonActiveStates').contains(this.get('status')); + }.property('status'), + + /** + * indicate whether upgrade group should be expanded + * @type {boolean} + */ + isExpandableGroup: function () { + return this.get('type') === 'GROUP' && (this.get('isActive') || this.get('hasExpandableItems')); + }.property('isActive', 'hasExpandableItems'), + + upgradeItemStatus: Em.computed.firstNotBlank('display_status', 'status'), + + /** + * @type {string} + */ + upgradeGroupStatus: function () { + if (this.get('type') === 'GROUP' && !this.get('isActive') && this.get('hasExpandableItems')) { + return 'SUBITEM_FAILED'; + } + return this.get('display_status') || this.get('status'); + }.property('isExpandableGroup', 'display_status', 'status') +}); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/ef418377/ambari-web/app/models/stack_version/stack_upgrade_history.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/models/stack_version/stack_upgrade_history.js b/ambari-web/app/models/stack_version/stack_upgrade_history.js new file mode 100644 index 0000000..d4a89dc --- /dev/null +++ b/ambari-web/app/models/stack_version/stack_upgrade_history.js @@ -0,0 +1,37 @@ +/** + * 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'); + +App.StackUpgradeHistory = DS.Model.extend({ + requestId: DS.attr('number'), + clusterName: DS.attr('string'), + direction: DS.attr('string'), + fromVersion: DS.attr('string'), + toVersion: DS.attr('string'), + requestStatus: DS.attr('string'), + upgradeType: DS.attr('string'), + downgradeAllowed: DS.attr('boolean'), + skipFailures: DS.attr('boolean'), + skipServiceCheckFailures: DS.attr('boolean'), + endTime: DS.attr('number'), + startTime: DS.attr('number'), + createTime: DS.attr('number'), +}); + +App.StackUpgradeHistory.FIXTURES = []; http://git-wip-us.apache.org/repos/asf/ambari/blob/ef418377/ambari-web/app/routes/main.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/routes/main.js b/ambari-web/app/routes/main.js index f0fe5d7..7e7b622 100644 --- a/ambari-web/app/routes/main.js +++ b/ambari-web/app/routes/main.js @@ -519,6 +519,13 @@ module.exports = Em.Route.extend(App.RouterRedirections, { } }), + upgradeHistory: Em.Route.extend({ + route: '/history', + connectOutlets: function (router, context) { + router.get('mainAdminStackAndUpgradeController').connectOutlet('mainAdminStackUpgradeHistory'); + }, + }), + stackNavigate: function (router, event) { var parent = event.view._parentView; parent.deactivateChildViews(); http://git-wip-us.apache.org/repos/asf/ambari/blob/ef418377/ambari-web/app/styles/stack_versions.less ---------------------------------------------------------------------- diff --git a/ambari-web/app/styles/stack_versions.less b/ambari-web/app/styles/stack_versions.less index 921b418..715bbe3 100644 --- a/ambari-web/app/styles/stack_versions.less +++ b/ambari-web/app/styles/stack_versions.less @@ -420,6 +420,75 @@ } } +#stack-upgrade-record-dialog { + .details-box { + padding: 5px; + margin-left: 15px; + margin-right: 95px; + .button-row { + text-align: right; + padding: 5px; + } + input[type="checkbox"] { + margin: 0; + } + .message { + line-height: 30px; + } + } + .task-details { + .manage-controls a { + cursor: pointer; + margin-right: 12px; + } + textarea { + width: 100%; + min-height: 100px; + box-sizing: border-box; + } + } + .task-list { + overflow-x: hidden; + .progress { + margin-bottom: 0; + } + padding-left: 20px; + i { + margin-right: 5px; + } + } + .task-list-main-warp i { + font-size: 16px; + } + ul.failed-info-list { + max-height: 500px; + margin-top: 5px; + } + .upgrade-options-link { + position: absolute; + cursor: pointer; + right: 10%; + top: 13px; + width: 100px; + a { + font-size: 13px; + } + .icon-cogs { + color: #0088cc; + margin-right: 3px; + } + } + .upgrade-options-link.disabled { + cursor: not-allowed; + a, .icon-cogs { + color: #808080; + } + a:hover { + text-decoration: none; + } + } +} + .repository-list { .os-block { border-top: 1px solid #dddddd; http://git-wip-us.apache.org/repos/asf/ambari/blob/ef418377/ambari-web/app/templates/main/admin/stack_upgrade/upgrade_history.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/main/admin/stack_upgrade/upgrade_history.hbs b/ambari-web/app/templates/main/admin/stack_upgrade/upgrade_history.hbs new file mode 100644 index 0000000..6d4a32d --- /dev/null +++ b/ambari-web/app/templates/main/admin/stack_upgrade/upgrade_history.hbs @@ -0,0 +1,105 @@ +{{! +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +}} + +
+
+ {{view App.SpinnerView}} +
+
+
+ + {{t common.filter}}: + + {{view.selectedCategory.label}} + + + + +
+
+
+ + + + + + + + + + + + + {{#if view.pageContent}} + {{#each item in view.pageContent}} + + + + + + + + + + + {{/each}} + {{/if}} + +
{{t common.direction}}{{t common.type}}{{t common.from.version}}{{t common.to.version}}{{t common.start.time}}{{t common.duration}}{{t common.end.time}}{{t common.status}}
+ + + {{unbound item.directionLabel}} + + + + {{item.upgradeTypeLabel}} + + {{item.fromVersion}} + + {{item.toVersion}} + + {{item.startTimeLabel}} + + {{item.duration}} + + {{item.endTimeLabel}} + + {{item.requestStatus}} +
+
+
+ +
+
{{view.paginationInfo}}
+
+ + +
+
+
+
\ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/ef418377/ambari-web/app/templates/main/admin/stack_upgrade/upgrade_history_details.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/main/admin/stack_upgrade/upgrade_history_details.hbs b/ambari-web/app/templates/main/admin/stack_upgrade/upgrade_history_details.hbs new file mode 100644 index 0000000..2d431f9 --- /dev/null +++ b/ambari-web/app/templates/main/admin/stack_upgrade/upgrade_history_details.hbs @@ -0,0 +1,46 @@ +{{! +* 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. +}} + +
+
+
{{statusIcon controller.requestStatus}} +  {{view.upgradeStatusLabel}}
+
+ {{view App.ProgressBarView + progressBinding="view.overallProgress" + statusBinding="controller.requestStatus" + }} +
+
+ {{view.overallProgress}}% +
+
+ +
+ {{#if view.isReady}} + {{#each group in controller.upgradeData.upgradeGroups}} + {{#if group.isVisible}} + {{view App.upgradeGroupView contentBinding="group"}} + {{/if}} + {{/each}} + {{/if}} +
+ {{#unless view.isReady}} + {{view App.SpinnerView}} + {{/unless}} +
http://git-wip-us.apache.org/repos/asf/ambari/blob/ef418377/ambari-web/app/views.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views.js b/ambari-web/app/views.js index 0d9dc3f..0dac227 100644 --- a/ambari-web/app/views.js +++ b/ambari-web/app/views.js @@ -213,6 +213,8 @@ require('views/main/admin/stack_upgrade/upgrade_version_box_view'); require('views/main/admin/stack_upgrade/upgrade_version_column_view'); require('views/main/admin/stack_upgrade/upgrade_group_view'); require('views/main/admin/stack_upgrade/upgrade_task_view'); +require('views/main/admin/stack_upgrade/upgrade_history_view'); +require('views/main/admin/stack_upgrade/upgrade_history_details_view'); require('views/main/admin/stack_upgrade/services_view'); require('views/main/admin/stack_upgrade/versions_view'); require('views/main/admin/stack_upgrade/menu_view'); http://git-wip-us.apache.org/repos/asf/ambari/blob/ef418377/ambari-web/app/views/main/admin/stack_upgrade/menu_view.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/main/admin/stack_upgrade/menu_view.js b/ambari-web/app/views/main/admin/stack_upgrade/menu_view.js index 1e84f1c..db5f946 100644 --- a/ambari-web/app/views/main/admin/stack_upgrade/menu_view.js +++ b/ambari-web/app/views/main/admin/stack_upgrade/menu_view.js @@ -35,6 +35,12 @@ App.MainAdminStackMenuView = Em.CollectionView.extend({ label: Em.I18n.t('common.versions'), routing: 'versions', hidden: !App.get('stackVersionsAvailable') + }), + Em.Object.create({ + name: 'upgradeHistory', + label: Em.I18n.t('common.upgrade.history'), + routing: 'upgradeHistory', + hidden: !App.get('stackVersionsAvailable') }) ] }.property('App.stackVersionsAvailable'), http://git-wip-us.apache.org/repos/asf/ambari/blob/ef418377/ambari-web/app/views/main/admin/stack_upgrade/upgrade_history_details_view.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/main/admin/stack_upgrade/upgrade_history_details_view.js b/ambari-web/app/views/main/admin/stack_upgrade/upgrade_history_details_view.js new file mode 100644 index 0000000..983c26a --- /dev/null +++ b/ambari-web/app/views/main/admin/stack_upgrade/upgrade_history_details_view.js @@ -0,0 +1,85 @@ +/** + * 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'); +var date = require('utils/date/date'); + +App.MainAdminStackUpgradeHistoryDetailsView = Em.View.extend({ + controllerBinding: 'App.router.mainAdminStackUpgradeHistoryController', + templateName: require('templates/main/admin/stack_upgrade/upgrade_history_details'), + isReady: false, + + willInsertElement: function(){ + var self = this; + this.get('controller').loadStackUpgradeRecord().done(function(){ + self.populateUpgradeHistoryRecord(); + }); + }, + + willDestroyElement: function () { + this.set('isReady', false); + }, + + populateUpgradeHistoryRecord: function(){ + var upgradeData = this.get('controller').get('upgradeData') + this.set('isReady', (upgradeData != null)) + }, + + /** + * progress value is rounded to floor + * @type {number} + */ + overallProgress: function () { + return Math.floor(this.get('controller.upgradeData.Upgrade.progress_percent')); + }.property('controller.upgradeData.Upgrade.progress_percent'), + + /** + * label of Upgrade status + * @type {string} + */ + upgradeStatusLabel: function() { + var labelKey = null; + switch (this.get('controller.upgradeData.Upgrade.request_status')) { + case 'QUEUED': + case 'PENDING': + case 'IN_PROGRESS': + labelKey = 'admin.stackUpgrade.state.inProgress'; + break; + case 'COMPLETED': + labelKey = 'admin.stackUpgrade.state.completed'; + break; + case 'ABORTED': + labelKey = 'admin.stackUpgrade.state.paused'; + break; + case 'TIMEDOUT': + case 'FAILED': + case 'HOLDING_FAILED': + case 'HOLDING_TIMEDOUT': + case 'HOLDING': + labelKey = 'admin.stackUpgrade.state.paused'; + break; + } + if (labelKey) { + labelKey += (this.get('controller.isDowngrade')) ? '.downgrade' : ""; + return Em.I18n.t(labelKey); + } else { + return ""; + } + }.property('controller.upgradeData.Upgrade.request_status', 'controller.isDowngrade'), +}); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/ef418377/ambari-web/app/views/main/admin/stack_upgrade/upgrade_history_view.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/main/admin/stack_upgrade/upgrade_history_view.js b/ambari-web/app/views/main/admin/stack_upgrade/upgrade_history_view.js new file mode 100644 index 0000000..ef5f46b --- /dev/null +++ b/ambari-web/app/views/main/admin/stack_upgrade/upgrade_history_view.js @@ -0,0 +1,303 @@ +/** + * 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'); +var date = require('utils/date/date'); + +App.MainAdminStackUpgradeHistoryView = App.TableView.extend(App.TableServerViewMixin, { + + controllerBinding: 'App.router.mainAdminStackUpgradeHistoryController', + + templateName: require('templates/main/admin/stack_upgrade/upgrade_history'), + + summary: [], + + isReady: false, + + categories: [ + Em.Object.create({ + labelKey: 'admin.stackVersions.upgradeHistory.filter.all', + value: 'ALL', + isSelected: true + }), + Em.Object.create({ + labelKey: 'admin.stackVersions.upgradeHistory.filter.upgrade', + value: 'UPGRADE', + isSelected: false + }), + Em.Object.create({ + labelKey: 'admin.stackVersions.upgradeHistory.filter.downgrade', + value: 'DOWNGRADE', + isSelected: false + }), + Em.Object.create({ + labelKey: 'admin.stackVersions.upgradeHistory.filter.successful.upgrade', + value: 'UPGRADE_COMPLETED', + isSelected: false + }), + Em.Object.create({ + labelKey: 'admin.stackVersions.upgradeHistory.filter.aborted.upgrade', + value: 'UPGRADE_ABORTED', + isSelected: false + }), + Em.Object.create({ + labelKey: 'admin.stackVersions.upgradeHistory.filter.successful.downgrade', + value: 'DOWNGRADE_COMPLETED', + isSelected: false + }), + Em.Object.create({ + labelKey: 'admin.stackVersions.upgradeHistory.filter.aborted.downgrade', + value: 'DOWNGRADE_ABORTED', + isSelected: false + }), + ], + + /** + * @type {object} + */ + selectedCategory: Em.computed.findBy('categories', 'isSelected', true), + + filteredCount: function(){ + var filteredContent = this.get('filteredContent').toArray(); + return filteredContent.length; + }.property('filteredContent'), + + /** + * displaying content filtered by upgrade type and upgrade status. + */ + filteredContent: function () { + var result = []; + var filterValue = 'ALL'; + var category = this.get('selectedCategory'); + if (category) + filterValue = category.get('value'); + var result = this.filterBy(filterValue); + return result.reverse(); + }.property('selectedCategory'), + + /** + * sort and slice recieved content by pagination parameters + */ + pageContent: function () { + var content = this.get('filteredContent').toArray(); + content = this.processForDisplay(content); + content = content.slice(this.get('startIndex') - 1, this.get('endIndex')) + return content; + }.property('filteredContent', 'startIndex', 'endIndex'), + + processForDisplay: function(content){ + var processedContent = []; + content.forEach(function(item){ + if('UPGRADE' == item.get('direction')) + item.set('directionLabel', Em.I18n.t('common.upgrade')); + else + item.set('directionLabel', Em.I18n.t('common.downgrade')); + + if('NON_ROLLING' == item.get('upgradeType')) + item.set('upgradeTypeLabel', Em.I18n.t('common.express')); + else + item.set('upgradeTypeLabel', Em.I18n.t('common.rolling')); + + item.set('startTimeLabel', date.startTime(item.get('startTime'))); + item.set('endTimeLabel', date.startTime(item.get('endTime'))); + item.set('duration', date.durationSummary(item.get('startTime'), item.get('endTime'))); + processedContent.push(item); + },this); + return processedContent; + }, + + paginationLeftClass: function () { + if (this.get("startIndex") > 1) { + return "paginate_previous"; + } + return "paginate_disabled_previous"; + }.property("startIndex", 'filteredCount'), + + /** + * Determines how display "next"-link - as link or text + * @type {string} + */ + paginationRightClass: function () { + if (this.get("endIndex") < this.get("filteredCount")) { + return "paginate_next"; + } + return "paginate_disabled_next"; + }.property("endIndex", 'filteredCount'), + + /** + * Show previous-page if user not in the first page + * @method previousPage + */ + previousPage: function () { + if (this.get('paginationLeftClass') === 'paginate_previous') { + this._super(); + } + }, + + /** + * Show next-page if user not in the last page + * @method nextPage + */ + nextPage: function () { + if (this.get('paginationRightClass') === 'paginate_next') { + this._super(); + } + }, + + willInsertElement: function(){ + var self = this; + this.get('controller').loadStackUpgradeHistoryToModel().done(function(){ + self.populateUpgradeHistorySummary(); + }); + }, + + didInsertElement: function () { + this.observesCategories(); + }, + + observesCategories: function(){ + this.get('categories').forEach(function (category) { + var label = Em.I18n.t(category.labelKey).format(this.filterBy(category.value).length); + category.set('label', label) + }, this); + }.observes('isReady'), + + filterBy: function(filterValue){ + if ('ALL' == filterValue) { + var all_records = App.StackUpgradeHistory.find(); + return all_records.toArray(); + } else { + var tokens = filterValue.split('_'); + var direction_token = null + var status_token = null + + if (tokens.length == 1) { + direction_token = tokens[0] + } else if (tokens.length > 1) { + direction_token = tokens[0] + status_token = tokens[1] + } + + var result = [] + App.StackUpgradeHistory.find().forEach(function(item){ + var direction = item.get('direction'); + if (direction == direction_token) { + if (status_token != null) { + //only for the given status + var status = item.get('requestStatus'); + if (status == status_token) { + result.push(item) + } + } else { + //regardless status + result.push(item) + } + } + }, this); + return result + } + }, + + selectCategory: function(event){ + this.get('categories').filterProperty('isSelected').setEach('isSelected', false); + event.context.set('isSelected', true); + }, + + populateUpgradeHistorySummary: function(){ + this.set('isReady', false); + var result = [ + Em.Object.create({ + direction: 'UPGRADE', + label:Em.I18n.t('common.upgrade'), + hasSuccess: false, + success:0, + hasAbort: false, + abort:0, + }), + Em.Object.create({ + direction: 'DOWNGRADE', + label:Em.I18n.t('common.downgrade'), + hasSuccess: false, + success:0, + hasAbort: false, + abort:0, + }) + ]; + + App.StackUpgradeHistory.find().forEach(function(item){ + var direction = item.get('direction'); + var status = item.get('requestStatus'); + if('UPGRADE' == direction){ + if('COMPLETED' == status){ + result[0].set('success', result[0].get('success') + 1); + } else if ('ABORTED' == status) { + result[0].set('abort', result[0].get('abort') + 1); + } + } else if('DOWNGRADE' == direction){ + if('COMPLETED' == status){ + result[1].set('success', result[1].get('success')+1); + } else if ('ABORTED' == status){ + result[1].set('abort', result[1].get('abort')+1); + } + } + }, this); + + result[0].set('hasSuccess', result[0].get('success') > 0); + result[1].set('hasSuccess', result[1].get('success') > 0); + result[0].set('hasAbort', result[0].get('abort') > 0); + result[1].set('hasAbort', result[1].get('abort') > 0); + + this.set('summary', result); + this.set('isReady', true); + }, + + showUpgradeHistoryRecord: function(event) { + var record = event.context + var title = ''; + var direction = App.format.normalizeName(record.get('direction')); + var type = record.get('upgradeType') + if ('ROLLING' == type) + type = App.format.normalizeName(type); + else if ('NON_ROLLING' == type) + type = 'Express' + + title = Em.I18n.t('admin.stackVersions.upgradeHistory.record.title').format(type, direction, record.get('fromVersion')); + + this.get('controller').set('currentUpgradeRecord', record) + + App.ModalPopup.show({ + classNames: ['full-width-modal'], + header: title, + bodyClass: App.MainAdminStackUpgradeHistoryDetailsView, + primary: Em.I18n.t('common.dismiss'), + secondary: null, + didInsertElement: function () { + this._super(); + this.fitHeight(); + this.fitInnerHeight(); + }, + fitInnerHeight: function () { + var block = this.$().find('#modal > .modal-body'); + var scrollable = this.$().find('#modal .scrollable-block'); + scrollable.css('max-height', Number(block.css('max-height').slice(0, -2)) - block.height()); + block.css('max-height', 'none'); + }, + }); + }, +}); http://git-wip-us.apache.org/repos/asf/ambari/blob/ef418377/ambari-web/test/controllers/main/admin/stack_upgrade_history_controller_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/controllers/main/admin/stack_upgrade_history_controller_test.js b/ambari-web/test/controllers/main/admin/stack_upgrade_history_controller_test.js new file mode 100644 index 0000000..bbfce19 --- /dev/null +++ b/ambari-web/test/controllers/main/admin/stack_upgrade_history_controller_test.js @@ -0,0 +1,125 @@ +/** + * 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/admin/stack_upgrade_history_controller'); +require('utils/string_utils'); +var testHelpers = require('test/helpers'); +describe('App.MainAdminStackUpgradeHistoryController', function() { + + var controller = App.MainAdminStackUpgradeHistoryController.create({ + + }); + + describe("#upgradeHistoryUrl", function() { + before(function () { + this.mock = sinon.stub(App, 'get'); + this.mock.withArgs('apiPrefix').returns('apiPrefix') + .withArgs('clusterName').returns('clusterName'); + }); + after(function () { + this.mock.restore(); + }); + it("should be valid", function() { + controller.propertyDidChange('upgradeHistoryUrl'); + expect(controller.get('upgradeHistoryUrl')).to.equal('apiPrefix/clusters/clusterName/upgrades?fields=Upgrade'); + }); + }); + + describe("#requestStatus", function() { + beforeEach(function() { + this.mock = sinon.stub(App, 'get'); + }); + afterEach(function() { + this.mock.restore(); + }); + it("state should be what the record states", function() { + this.mock.returns(false); + controller.set('upgradeData', { Upgrade: {request_status: 'COMPLETED'}}); + controller.propertyDidChange('requestStatus'); + expect(controller.get('requestStatus')).to.equal('COMPLETED'); + }); + + it("upgradeData is null", function() { + this.mock.returns(false); + controller.set('upgradeData', null); + controller.propertyDidChange('requestStatus'); + expect(controller.get('requestStatus')).to.be.empty; + }); + }); + + describe("#loadStackUpgradeRecord()", function() { + it("get upgrade record data", function() { + controller.set('currentUpgradeRecord', Em.Object.create({'requestId':1, 'direction':'DOWNGRADE'})); + controller.loadStackUpgradeRecord(); + var args = testHelpers.findAjaxRequest('name', 'admin.upgrade.data'); + expect(args[0]).to.exists; + expect(args[0].sender).to.be.eql(controller); + expect(args[0].data).to.be.eql({ + id: 1 + }); + }); + }); + + describe("#loadUpgradeRecordSuccessCallback()", function() { + it("correct data", function() { + var data = { + "Upgrade": { + "request_status": "COMPLETED" + }, + "upgrade_groups": [ + { + "UpgradeGroup": { + "id": 1 + }, + "upgrade_items": [] + } + ]}; + controller.loadUpgradeRecordSuccessCallback(data); + expect(controller.get('upgradeData') == null).to.be.false; + }); + + it("data is null", function() { + var data = null; + controller.set('upgradeData', null) + controller.loadUpgradeRecordSuccessCallback(data); + expect(controller.get('upgradeData') == null).to.be.true; + }); + }); + + describe("#getUpgradeItem()", function() { + it("default callback", function() { + var item = Em.Object.create({ + request_id: 1, + group_id: 2, + stage_id: 3 + }); + controller.getUpgradeItem(item); + var args = testHelpers.findAjaxRequest('name', 'admin.upgrade.upgrade_item'); + expect(args[0]).to.exists; + expect(args[0].sender).to.be.eql(controller); + expect(args[0].success).to.be.equal('getUpgradeItemSuccessCallback'); + expect(args[0].data).to.be.eql({ + upgradeId: 1, + groupId: 2, + stageId: 3 + }); + }); + }); +}); http://git-wip-us.apache.org/repos/asf/ambari/blob/ef418377/ambari-web/test/mappers/stack_upgrade_history_mapper_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/mappers/stack_upgrade_history_mapper_test.js b/ambari-web/test/mappers/stack_upgrade_history_mapper_test.js new file mode 100644 index 0000000..07027e1 --- /dev/null +++ b/ambari-web/test/mappers/stack_upgrade_history_mapper_test.js @@ -0,0 +1,372 @@ +/** + * 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. + */ + +/*eslint-disable */ + +var App = require('app'); + +require('mappers/stack_upgrade_history_mapper'); + +describe('App.stackUpgradeHistoryMapper', function () { + + describe('#map', function () { + + var data = { + "href" : "http://bdavm079.svl.ibm.com:8080/api/v1/clusters/bi/upgrades?fields=Upgrade", + "items" : [ + { + "href" : "http://bdavm079.svl.ibm.com:8080/api/v1/clusters/bi/upgrades/7", + "Upgrade" : { + "cluster_name" : "bi", + "create_time" : 1463779169144, + "direction" : "UPGRADE", + "downgrade_allowed" : true, + "end_time" : 1463779266087, + "exclusive" : false, + "from_version" : "2.3.6.0-3712", + "pack" : "nonrolling-upgrade-2.4", + "progress_percent" : 100.0, + "request_context" : "Upgrading to 2.4.0.0-169", + "request_id" : 7, + "request_status" : "ABORTED", + "skip_failures" : false, + "skip_service_check_failures" : false, + "start_time" : 1463779170159, + "suspended" : false, + "to_version" : "2.4.0.0-169", + "type" : "INTERNAL_REQUEST", + "upgrade_type" : "NON_ROLLING" + } + }, + { + "href" : "http://bdavm079.svl.ibm.com:8080/api/v1/clusters/bi/upgrades/8", + "Upgrade" : { + "cluster_name" : "bi", + "create_time" : 1463779266212, + "direction" : "DOWNGRADE", + "downgrade_allowed" : true, + "end_time" : 1463779299440, + "exclusive" : false, + "from_version" : "2.3.6.0-3712", + "pack" : "nonrolling-upgrade-2.4", + "progress_percent" : 100.0, + "request_context" : "Downgrading to 2.3.6.0-3712", + "request_id" : 8, + "request_status" : "COMPLETED", + "skip_failures" : false, + "skip_service_check_failures" : false, + "start_time" : 1463779267220, + "suspended" : false, + "to_version" : "2.3.6.0-3712", + "type" : "INTERNAL_REQUEST", + "upgrade_type" : "NON_ROLLING" + } + }, + { + "href" : "http://bdavm079.svl.ibm.com:8080/api/v1/clusters/bi/upgrades/9", + "Upgrade" : { + "cluster_name" : "bi", + "create_time" : 1463780699654, + "direction" : "UPGRADE", + "downgrade_allowed" : true, + "end_time" : 1463780757685, + "exclusive" : false, + "from_version" : "2.3.6.0-3712", + "pack" : "nonrolling-upgrade-2.4", + "progress_percent" : 100.0, + "request_context" : "Upgrading to 2.4.0.0-169", + "request_id" : 9, + "request_status" : "ABORTED", + "skip_failures" : false, + "skip_service_check_failures" : false, + "start_time" : 1463780700670, + "suspended" : false, + "to_version" : "2.4.0.0-169", + "type" : "INTERNAL_REQUEST", + "upgrade_type" : "NON_ROLLING" + } + }, + { + "href" : "http://bdavm079.svl.ibm.com:8080/api/v1/clusters/bi/upgrades/10", + "Upgrade" : { + "cluster_name" : "bi", + "create_time" : 1463780757799, + "direction" : "DOWNGRADE", + "downgrade_allowed" : true, + "end_time" : 1463780794009, + "exclusive" : false, + "from_version" : "2.3.6.0-3712", + "pack" : "nonrolling-upgrade-2.4", + "progress_percent" : 100.0, + "request_context" : "Downgrading to 2.3.6.0-3712", + "request_id" : 10, + "request_status" : "COMPLETED", + "skip_failures" : false, + "skip_service_check_failures" : false, + "start_time" : 1463780758807, + "suspended" : false, + "to_version" : "2.3.6.0-3712", + "type" : "INTERNAL_REQUEST", + "upgrade_type" : "NON_ROLLING" + } + }, + { + "href" : "http://bdavm079.svl.ibm.com:8080/api/v1/clusters/bi/upgrades/11", + "Upgrade" : { + "cluster_name" : "bi", + "create_time" : 1463781287967, + "direction" : "UPGRADE", + "downgrade_allowed" : true, + "end_time" : 1463781341452, + "exclusive" : false, + "from_version" : "2.3.6.0-3712", + "pack" : "nonrolling-upgrade-2.4", + "progress_percent" : 100.0, + "request_context" : "Upgrading to 2.4.0.0-169", + "request_id" : 11, + "request_status" : "ABORTED", + "skip_failures" : false, + "skip_service_check_failures" : false, + "start_time" : 1463781288984, + "suspended" : false, + "to_version" : "2.4.0.0-169", + "type" : "INTERNAL_REQUEST", + "upgrade_type" : "NON_ROLLING" + } + }, + { + "href" : "http://bdavm079.svl.ibm.com:8080/api/v1/clusters/bi/upgrades/12", + "Upgrade" : { + "cluster_name" : "bi", + "create_time" : 1463781341576, + "direction" : "DOWNGRADE", + "downgrade_allowed" : true, + "end_time" : 1463781371778, + "exclusive" : false, + "from_version" : "2.3.6.0-3712", + "pack" : "nonrolling-upgrade-2.4", + "progress_percent" : 100.0, + "request_context" : "Downgrading to 2.3.6.0-3712", + "request_id" : 12, + "request_status" : "COMPLETED", + "skip_failures" : false, + "skip_service_check_failures" : false, + "start_time" : 1463781342585, + "suspended" : false, + "to_version" : "2.3.6.0-3712", + "type" : "INTERNAL_REQUEST", + "upgrade_type" : "NON_ROLLING" + } + }, + { + "href" : "http://bdavm079.svl.ibm.com:8080/api/v1/clusters/bi/upgrades/13", + "Upgrade" : { + "cluster_name" : "bi", + "create_time" : 1464120656181, + "direction" : "UPGRADE", + "downgrade_allowed" : true, + "end_time" : 1464120881477, + "exclusive" : false, + "from_version" : "2.3.6.0-3712", + "pack" : "upgrade-2.4", + "progress_percent" : 100.0, + "request_context" : "Upgrading to 2.4.0.0-169", + "request_id" : 13, + "request_status" : "ABORTED", + "skip_failures" : false, + "skip_service_check_failures" : false, + "start_time" : 1464120657198, + "suspended" : false, + "to_version" : "2.4.0.0-169", + "type" : "INTERNAL_REQUEST", + "upgrade_type" : "ROLLING" + } + }, + { + "href" : "http://bdavm079.svl.ibm.com:8080/api/v1/clusters/bi/upgrades/14", + "Upgrade" : { + "cluster_name" : "bi", + "create_time" : 1464120881574, + "direction" : "DOWNGRADE", + "downgrade_allowed" : true, + "end_time" : 1464120918774, + "exclusive" : false, + "from_version" : "2.3.6.0-3712", + "pack" : "upgrade-2.4", + "progress_percent" : 100.0, + "request_context" : "Downgrading to 2.3.6.0-3712", + "request_id" : 14, + "request_status" : "COMPLETED", + "skip_failures" : false, + "skip_service_check_failures" : false, + "start_time" : 1464120882580, + "suspended" : false, + "to_version" : "2.3.6.0-3712", + "type" : "INTERNAL_REQUEST", + "upgrade_type" : "ROLLING" + } + }, + { + "href" : "http://bdavm079.svl.ibm.com:8080/api/v1/clusters/bi/upgrades/15", + "Upgrade" : { + "cluster_name" : "bi", + "create_time" : 1464120943986, + "direction" : "UPGRADE", + "downgrade_allowed" : true, + "end_time" : 1464121132856, + "exclusive" : false, + "from_version" : "2.3.6.0-3712", + "pack" : "upgrade-2.4", + "progress_percent" : 100.0, + "request_context" : "Upgrading to 2.4.0.0-169", + "request_id" : 15, + "request_status" : "ABORTED", + "skip_failures" : false, + "skip_service_check_failures" : false, + "start_time" : 1464120945002, + "suspended" : false, + "to_version" : "2.4.0.0-169", + "type" : "INTERNAL_REQUEST", + "upgrade_type" : "ROLLING" + } + }, + { + "href" : "http://bdavm079.svl.ibm.com:8080/api/v1/clusters/bi/upgrades/16", + "Upgrade" : { + "cluster_name" : "bi", + "create_time" : 1464121132981, + "direction" : "DOWNGRADE", + "downgrade_allowed" : true, + "end_time" : 1464121167178, + "exclusive" : false, + "from_version" : "2.3.6.0-3712", + "pack" : "upgrade-2.4", + "progress_percent" : 100.0, + "request_context" : "Downgrading to 2.3.6.0-3712", + "request_id" : 16, + "request_status" : "COMPLETED", + "skip_failures" : false, + "skip_service_check_failures" : false, + "start_time" : 1464121133988, + "suspended" : false, + "to_version" : "2.3.6.0-3712", + "type" : "INTERNAL_REQUEST", + "upgrade_type" : "ROLLING" + } + }, + { + "href" : "http://bdavm079.svl.ibm.com:8080/api/v1/clusters/bi/upgrades/17", + "Upgrade" : { + "cluster_name" : "bi", + "create_time" : 1464121207511, + "direction" : "UPGRADE", + "downgrade_allowed" : true, + "end_time" : 1464121301821, + "exclusive" : false, + "from_version" : "2.3.6.0-3712", + "pack" : "nonrolling-upgrade-2.4", + "progress_percent" : 100.0, + "request_context" : "Upgrading to 2.4.0.0-169", + "request_id" : 17, + "request_status" : "ABORTED", + "skip_failures" : false, + "skip_service_check_failures" : false, + "start_time" : 1464121208524, + "suspended" : false, + "to_version" : "2.4.0.0-169", + "type" : "INTERNAL_REQUEST", + "upgrade_type" : "NON_ROLLING" + } + }, + { + "href" : "http://bdavm079.svl.ibm.com:8080/api/v1/clusters/bi/upgrades/18", + "Upgrade" : { + "cluster_name" : "bi", + "create_time" : 1464121301933, + "direction" : "DOWNGRADE", + "downgrade_allowed" : true, + "end_time" : 1464121336149, + "exclusive" : false, + "from_version" : "2.3.6.0-3712", + "pack" : "nonrolling-upgrade-2.4", + "progress_percent" : 100.0, + "request_context" : "Downgrading to 2.3.6.0-3712", + "request_id" : 18, + "request_status" : "COMPLETED", + "skip_failures" : false, + "skip_service_check_failures" : false, + "start_time" : 1464121302941, + "suspended" : false, + "to_version" : "2.3.6.0-3712", + "type" : "INTERNAL_REQUEST", + "upgrade_type" : "NON_ROLLING" + } + } + ] + }; + + var upgradeParseResult = { + 'clusterName':'bi', + 'createTime':1464121301933, + "direction" : "DOWNGRADE", + "downgradeAllowed" : true, + "endTime" : 1464121336149, + "fromVersion" : "2.3.6.0-3712", + "requestId" : 18, + "requestStatus" : "COMPLETED", + "skipFailures" : false, + "skipServiceCheckFailures" : false, + "startTime" : 1464121302941, + "toVersion" : "2.3.6.0-3712", + "upgradeType" : "NON_ROLLING" + }; + + beforeEach(function () { + App.resetDsStoreTypeMap(App.StackUpgradeHistory); + sinon.stub(App.store, 'commit', Em.K); + }); + + afterEach(function(){ + App.store.commit.restore(); + }); + + it('Parse upgrade records returned by the Ambari server', function () { + App.stackUpgradeHistoryMapper.map(data); + var all_records = App.StackUpgradeHistory.find(); + var upgrades = all_records.toArray(); + expect(upgrades.length).to.eql(12); + var total_downgrades = 0; + var total_upgrades = 0; + upgrades.forEach(function(upgrade){ + var direction = upgrade.get('direction') + if ('DOWNGRADE' == direction){ + total_downgrades++; + } + if ('UPGRADE' == direction){ + total_upgrades++; + } + }); + expect(total_upgrades).to.eql(6); + expect(total_downgrades).to.eql(6); + + var record = App.StackUpgradeHistory.find().findProperty('requestId', 18); + Em.keys(upgradeParseResult).forEach(function (key) { + expect(record.get(key)).to.eql(upgradeParseResult[key]); + }); + }); + }); +}); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/ef418377/ambari-web/test/models/finished_upgrade_entity_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/models/finished_upgrade_entity_test.js b/ambari-web/test/models/finished_upgrade_entity_test.js new file mode 100644 index 0000000..a2a9527 --- /dev/null +++ b/ambari-web/test/models/finished_upgrade_entity_test.js @@ -0,0 +1,197 @@ +/** + * 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/finished_upgrade_entity'); + +function getModel() { + return App.finishedUpgradeEntity.create(); +} + +describe('App.finishedUpgradeEntity', function () { + var model; + + beforeEach(function () { + model = getModel(); + }); + + App.TestAliases.testAsComputedNotEqual(getModel(), 'isVisible', 'status', 'PENDING'); + + describe("#progress", function() { + it("progress_percent = 1.9", function() { + model.set('progress_percent', 1.9); + model.propertyDidChange('progress'); + expect(model.get('progress')).to.equal(1); + }); + it("progress_percent = 1", function() { + model.set('progress_percent', 1); + model.propertyDidChange('progress'); + expect(model.get('progress')).to.equal(1); + }); + }); + + describe("#isActive", function() { + it("status IN_PROGRESS", function() { + model.set('status', 'IN_PROGRESS'); + model.propertyDidChange('isActive'); + expect(model.get('isActive')).to.be.true; + }); + it("status PENDING", function() { + model.set('status', 'PENDING'); + model.propertyDidChange('isActive'); + expect(model.get('isActive')).to.be.false; + }); + }); + + describe('#isExpandableGroup', function () { + + var cases = [ + { + input: { + type: 'ITEM' + }, + isExpandableGroup: false, + title: 'not upgrade group' + }, + { + input: { + type: 'GROUP', + status: 'PENDING', + hasExpandableItems: false + }, + isExpandableGroup: false, + title: 'pending upgrade group without expandable items' + }, + { + input: { + type: 'GROUP', + status: 'ABORTED', + hasExpandableItems: false + }, + isExpandableGroup: true, + title: 'aborted upgrade group without expandable items' + }, + { + input: { + type: 'GROUP', + status: 'ABORTED', + hasExpandableItems: true + }, + isExpandableGroup: true, + title: 'aborted upgrade group with expandable items' + }, + { + input: { + type: 'GROUP', + status: 'IN_PROGRESS', + hasExpandableItems: false + }, + isExpandableGroup: true, + title: 'active upgrade group' + } + ]; + + cases.forEach(function (item) { + it(item.title, function () { + model.setProperties(item.input); + expect(model.get('isExpandableGroup')).to.equal(item.isExpandableGroup); + }); + }); + + }); + + describe('#upgradeGroupStatus', function () { + + var cases = [ + { + input: { + type: 'ITEM', + upgradeSuspended: false + }, + upgradeGroupStatus: undefined, + title: 'not upgrade group' + }, + { + input: { + type: 'GROUP', + status: 'PENDING', + hasExpandableItems: false, + upgradeSuspended: false + }, + upgradeGroupStatus: 'PENDING', + title: 'pending upgrade group' + }, + { + input: { + type: 'GROUP', + status: 'PENDING', + hasExpandableItems: true, + upgradeSuspended: false + }, + upgradeGroupStatus: 'SUBITEM_FAILED', + title: 'pending upgrade group with expandable items' + }, + { + input: { + type: 'GROUP', + status: 'ABORTED', + hasExpandableItems: false, + upgradeSuspended: false + }, + upgradeGroupStatus: 'ABORTED', + title: 'aborted upgrade group with expandable items' + }, + { + input: { + type: 'GROUP', + status: 'ABORTED', + hasExpandableItems: true, + upgradeSuspended: true + }, + upgradeGroupStatus: 'ABORTED', + title: 'aborted upgrade group with expandable items' + }, + { + input: { + type: 'GROUP', + status: 'IN_PROGRESS', + hasExpandableItems: false, + upgradeSuspended: false + }, + upgradeGroupStatus: 'IN_PROGRESS', + title: 'active upgrade' + } + ]; + + beforeEach(function() { + this.mock = sinon.stub(App, 'get'); + }); + afterEach(function() { + this.mock.restore(); + }); + + cases.forEach(function (item) { + it(item.title, function () { + this.mock.returns(item.input.upgradeSuspended); + model.setProperties(item.input); + expect(model.get('upgradeGroupStatus')).to.equal(item.upgradeGroupStatus); + }); + }); + + }); +}); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/ef418377/ambari-web/test/views/main/admin/stack_upgrade/upgrade_history_details_view_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/views/main/admin/stack_upgrade/upgrade_history_details_view_test.js b/ambari-web/test/views/main/admin/stack_upgrade/upgrade_history_details_view_test.js new file mode 100644 index 0000000..ab38e34 --- /dev/null +++ b/ambari-web/test/views/main/admin/stack_upgrade/upgrade_history_details_view_test.js @@ -0,0 +1,248 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +var App = require('app'); +require('views/main/admin/stack_upgrade/upgrade_history_details_view'); +var testHelpers = require('test/helpers'); + +describe('App.MainAdminStackUpgradeHistoryDetailsView', function () { + var view; + + beforeEach(function () { + view = App.MainAdminStackUpgradeHistoryDetailsView.create({ + controller: { + currentUpgradeRecord: App.StackUpgradeHistory.createRecord({ + 'requestId':1, + 'direction':'DOWNGRADE', + }), + } + }); + }); + + afterEach(function () { + view.destroy(); + }); + + describe("#overallProgress", function () { + it("progress is 1.9", function () { + view.set('controller.upgradeData', { + Upgrade: { + progress_percent: 1.9 + } + }); + expect(view.get('overallProgress')).to.equal(1); + }); + it("progress is 1", function () { + view.set('controller.upgradeData', { + Upgrade: { + progress_percent: 1 + } + }); + expect(view.get('overallProgress')).to.equal(1); + }); + }); + + describe("#willInsertElement()", function() { + beforeEach(function () { + sinon.spy(view.get('controller'), 'loadStackUpgradeRecord'); + }); + afterEach(function () { + view.get('controller').loadStackUpgradeRecord.restore(); + }); + it("load data by controller is called once", function() { + view.set('controller.currentUpgradeRecord', App.StackUpgradeHistory.createRecord({ + 'requestId':1, + 'direction':'DOWNGRADE', + })); + view.willInsertElement(); + expect(view.get('controller').loadStackUpgradeRecord.calledOnce).to.be.true; + }); + }); + + describe("#willDestroyElement()", function () { + it("reset ready flag", function () { + view.set('isReady', true); + view.willDestroyElement(); + expect(view.get('isReady')).to.be.false; + }); + }); + + describe("#upgradeStatusLabel", function () { + beforeEach(function () { + Em.setFullPath(view, 'controller.upgradeData.Upgrade', {}); + }); + + [ + { + data: { + status: 'QUEUED', + isDowngrade: false + }, + result: Em.I18n.t('admin.stackUpgrade.state.inProgress') + }, + { + data: { + status: 'PENDING', + isDowngrade: false + }, + result: Em.I18n.t('admin.stackUpgrade.state.inProgress') + }, + { + data: { + status: 'IN_PROGRESS', + isDowngrade: false + }, + result: Em.I18n.t('admin.stackUpgrade.state.inProgress') + }, + { + data: { + status: 'COMPLETED', + isDowngrade: false + }, + result: Em.I18n.t('admin.stackUpgrade.state.completed') + }, + { + data: { + status: 'ABORTED', + isDowngrade: false + }, + result: Em.I18n.t('admin.stackUpgrade.state.paused') + }, + { + data: { + status: 'TIMEDOUT', + isDowngrade: false + }, + result: Em.I18n.t('admin.stackUpgrade.state.paused') + }, + { + data: { + status: 'FAILED', + isDowngrade: false + }, + result: Em.I18n.t('admin.stackUpgrade.state.paused') + }, + { + data: { + status: 'HOLDING_FAILED', + isDowngrade: false + }, + result: Em.I18n.t('admin.stackUpgrade.state.paused') + }, + { + data: { + status: 'HOLDING_TIMEDOUT', + isDowngrade: false + }, + result: Em.I18n.t('admin.stackUpgrade.state.paused') + }, + { + data: { + status: 'HOLDING', + isDowngrade: false + }, + result: Em.I18n.t('admin.stackUpgrade.state.paused') + }, + { + data: { + status: '', + isDowngrade: false + }, + result: '' + }, + { + data: { + status: 'QUEUED', + isDowngrade: true + }, + result: Em.I18n.t('admin.stackUpgrade.state.inProgress.downgrade') + }, + { + data: { + status: 'PENDING', + isDowngrade: true + }, + result: Em.I18n.t('admin.stackUpgrade.state.inProgress.downgrade') + }, + { + data: { + status: 'IN_PROGRESS', + isDowngrade: true + }, + result: Em.I18n.t('admin.stackUpgrade.state.inProgress.downgrade') + }, + { + data: { + status: 'COMPLETED', + isDowngrade: true + }, + result: Em.I18n.t('admin.stackUpgrade.state.completed.downgrade') + }, + { + data: { + status: 'ABORTED', + isDowngrade: true + }, + result: Em.I18n.t('admin.stackUpgrade.state.paused.downgrade') + }, + { + data: { + status: 'TIMEDOUT', + isDowngrade: true + }, + result: Em.I18n.t('admin.stackUpgrade.state.paused.downgrade') + }, + { + data: { + status: 'FAILED', + isDowngrade: true + }, + result: Em.I18n.t('admin.stackUpgrade.state.paused.downgrade') + }, + { + data: { + status: 'HOLDING_FAILED', + isDowngrade: true + }, + result: Em.I18n.t('admin.stackUpgrade.state.paused.downgrade') + }, + { + data: { + status: 'HOLDING_TIMEDOUT', + isDowngrade: true + }, + result: Em.I18n.t('admin.stackUpgrade.state.paused.downgrade') + }, + { + data: { + status: 'HOLDING', + isDowngrade: true + }, + result: Em.I18n.t('admin.stackUpgrade.state.paused.downgrade') + } + ].forEach(function (test) { + it('status = ' + test.data.status + ", isDowngrade = " + test.data.isDowngrade, function () { + view.set('controller.isDowngrade', test.data.isDowngrade); + view.set('controller.upgradeData.Upgrade.request_status', test.data.status); + view.propertyDidChange('upgradeStatusLabel'); + expect(view.get('upgradeStatusLabel')).to.equal(test.result); + }); + }); + }); +}); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/ef418377/ambari-web/test/views/main/admin/stack_upgrade/upgrade_history_view_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/views/main/admin/stack_upgrade/upgrade_history_view_test.js b/ambari-web/test/views/main/admin/stack_upgrade/upgrade_history_view_test.js new file mode 100644 index 0000000..d68a854 --- /dev/null +++ b/ambari-web/test/views/main/admin/stack_upgrade/upgrade_history_view_test.js @@ -0,0 +1,173 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +var App = require('app'); +require('views/main/admin/stack_upgrade/upgrade_history_view'); +var testHelpers = require('test/helpers'); + +describe('App.MainAdminStackUpgradeHistoryView', function () { + var view; + + beforeEach(function () { + view = App.MainAdminStackUpgradeHistoryView.create(); + }); + + afterEach(function () { + view.destroy(); + }); + + describe("#filterBy()", function () { + var records = [ + Em.Object.create({ + requestStatus: "ABORTED", + direction: "UPGRADE" + }), + Em.Object.create({ + requestStatus: "ABORTED", + direction: "DOWNGRADE" + }), + Em.Object.create({ + requestStatus: "COMPLETED", + direction: "UPGRADE" + }), + Em.Object.create({ + requestStatus: "COMPLETED", + direction: "DOWNGRADE" + }) + ]; + + + beforeEach(function () { + this.mock = sinon.stub(App.StackUpgradeHistory, 'find'); + }); + + afterEach(function () { + this.mock.restore(); + }); + + it('All should return all records', function(){ + this.mock.returns(records); + var filteredResults = view.filterBy('ALL') + expect(filteredResults.length == 4).to.be.true + }); + + it('Filter aborted upgrades', function(){ + this.mock.returns(records); + var filteredResults = view.filterBy('UPGRADE_ABORTED') + expect(filteredResults.length == 1).to.be.true + }); + + it('Filter completed upgrades', function(){ + this.mock.returns(records); + var filteredResults = view.filterBy('UPGRADE_COMPLETED') + expect(filteredResults.length == 1).to.be.true + }); + + it('Filter aborted downgrades', function(){ + this.mock.returns(records); + var filteredResults = view.filterBy('DOWNGRADE_ABORTED') + expect(filteredResults.length == 1).to.be.true + }); + + it('Filter completed downgrades', function(){ + this.mock.returns(records); + var filteredResults = view.filterBy('DOWNGRADE_COMPLETED') + expect(filteredResults.length == 1).to.be.true + }); + }); + + describe("#didInsertElement()", function() { + beforeEach(function () { + sinon.stub(view, 'observesCategories', Em.K); + }); + afterEach(function () { + view.observesCategories.restore(); + }); + it("observesCategories is called once", function() { + view.didInsertElement(); + expect(view.observesCategories.calledOnce).to.be.true; + }); + }); + + describe("#observesCategories()", function () { + var mock = {format: Em.K}; + beforeEach(function () { + sinon.stub(Em.I18n, 't').returns(mock); + sinon.stub(mock, 'format').returns('label'); + sinon.stub(view, 'filterBy').returns([]); + view.set('categories', [ + Em.Object.create({ + labelKey: 'labelKey', + value: 'value', + isSelected: false + }) + ]); + view.observesCategories(); + }); + afterEach(function () { + Em.I18n.t.restore(); + mock.format.restore(); + view.filterBy.restore(); + }); + it("categories[0].label is updated", function () { + expect(view.get('categories')[0].get('label')).to.equal('label'); + }); + }); + + describe("#selectCategory()", function() { + var event; + beforeEach(function () { + event = { + context: Em.Object.create({ + isSelected: false, + value: 'ALL', + }) + }; + view.set('categories', [ + Em.Object.create({ + isSelected: true, + value: 'UPGRADE_COMPLETED', + }), + event.context + ]); + view.selectCategory(event); + }); + afterEach(function () { + }); + it("categories[0].isSelected false", function() { + expect(view.get('categories')[0].get('isSelected')).to.be.false; + }); + it("isSelected is true", function() { + expect(event.context.get('isSelected')).to.be.true; + }); + }); + + describe("#willInsertElement()", function() { + beforeEach(function () { + sinon.spy(view.get('controller'), 'loadStackUpgradeHistoryToModel'); + }); + afterEach(function () { + view.get('controller').loadStackUpgradeHistoryToModel.restore(); + }); + it("load data by controller is called once", function() { + view.willInsertElement(); + expect(view.get('controller').loadStackUpgradeHistoryToModel.calledOnce).to.be.true; + }); + }); +});