Repository: ambari Updated Branches: refs/heads/trunk ab48cfbf0 -> 93b6119cf
AMBARI-8308. Alerts UI: Summary Page. Fill Status and Last Triggered columns (onechiporenko) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/93b6119c Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/93b6119c Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/93b6119c Branch: refs/heads/trunk Commit: 93b6119cfb37253dfe5006bc61591dbd56354300 Parents: ab48cfb Author: Oleg Nechiporenko <onechipore...@apache.org> Authored: Thu Nov 13 16:03:34 2014 +0200 Committer: Oleg Nechiporenko <onechipore...@apache.org> Committed: Thu Nov 13 16:03:34 2014 +0200 ---------------------------------------------------------------------- .../app/assets/data/alerts/alert_summary.json | 93 ++++++++++++++ ambari-web/app/assets/test/tests.js | 3 + .../controllers/global/cluster_controller.js | 4 +- .../app/controllers/global/update_controller.js | 12 ++ .../main/alert_definitions_controller.js | 51 -------- ambari-web/app/mappers.js | 1 + .../mappers/alert_definition_summary_mapper.js | 51 ++++++++ .../app/mappers/alert_definitions_mapper.js | 16 ++- ambari-web/app/models/alert_definition.js | 40 ++++-- ambari-web/app/templates/main/alerts.hbs | 2 +- ambari-web/app/views/common/filter_view.js | 9 ++ ambari-web/app/views/common/sort_view.js | 24 +++- .../app/views/main/alert_definitions_view.js | 35 ++---- .../global/update_controller_test.js | 2 +- .../alert_definition_summary_mapper_test.js | 125 +++++++++++++++++++ ambari-web/test/models/alert_definition_test.js | 60 +++++++++ .../test/views/common/filter_view_test.js | 30 ++++- ambari-web/test/views/common/sort_view_test.js | 68 ++++++++++ 18 files changed, 531 insertions(+), 95 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/93b6119c/ambari-web/app/assets/data/alerts/alert_summary.json ---------------------------------------------------------------------- diff --git a/ambari-web/app/assets/data/alerts/alert_summary.json b/ambari-web/app/assets/data/alerts/alert_summary.json new file mode 100644 index 0000000..b870999 --- /dev/null +++ b/ambari-web/app/assets/data/alerts/alert_summary.json @@ -0,0 +1,93 @@ +{ + "href" : "http://localhost:8080/api/v1/clusters/c1/alerts?format=groupedSummary", + "alerts_summary_grouped" : [ + { + "definition_id" : 34, + "definition_name" : "yarn_resourcemanager_webui", + "summary" : { + "OK" : { + "count" : 1, + "original_timestamp" : 1415732283450 + }, + "WARNING" : { + "count" : 0, + "original_timestamp" : 0 + }, + "CRITICAL" : { + "count" : 0, + "original_timestamp" : 0 + }, + "UNKNOWN" : { + "count" : 0, + "original_timestamp" : 0 + } + } + }, + { + "definition_id" : 12, + "definition_name" : "ganglia_monitor_mapreduce_history_server", + "summary" : { + "OK" : { + "count" : 1, + "original_timestamp" : 1415735183450 + }, + "WARNING" : { + "count" : 3, + "original_timestamp" : 1415735183450 + }, + "CRITICAL" : { + "count" : 1, + "original_timestamp" : 1415755183450 + }, + "UNKNOWN" : { + "count" : 2, + "original_timestamp" : 1412335183450 + } + } + }, + { + "definition_id" : 1, + "definition_name" : "ganglia_monitor_hdfs_namenode", + "summary" : { + "OK" : { + "count" : 2, + "original_timestamp" : 1415735183450 + }, + "WARNING" : { + "count" : 1, + "original_timestamp" : 1415735183450 + }, + "CRITICAL" : { + "count" : 3, + "original_timestamp" : 1415855183450 + }, + "UNKNOWN" : { + "count" : 2, + "original_timestamp" : 1412335183450 + } + } + }, + { + "definition_id" : 1, + "definition_name" : "ganglia_monitor_hbase_master", + "summary" : { + "OK" : { + "count" : 2, + "original_timestamp" : 1415735183450 + }, + "WARNING" : { + "count" : 2, + "original_timestamp" : 1415735183450 + }, + "CRITICAL" : { + "count" : 3, + "original_timestamp" : 1415355183450 + }, + "UNKNOWN" : { + "count" : 2, + "original_timestamp" : 1412335183450 + } + } + } + ] +} http://git-wip-us.apache.org/repos/asf/ambari/blob/93b6119c/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 aab4bf2..6e2a10c 100644 --- a/ambari-web/app/assets/test/tests.js +++ b/ambari-web/app/assets/test/tests.js @@ -103,6 +103,7 @@ var files = ['test/init_model_test', 'test/controllers/wizard/stack_upgrade/step3_controller_test', 'test/login_test', 'test/router_test', + 'test/mappers/alert_definition_summary_mapper_test', 'test/mappers/server_data_mapper_test', 'test/mappers/hosts_mapper_test', 'test/mappers/service_mapper_test', @@ -138,6 +139,7 @@ var files = ['test/init_model_test', 'test/views/common/quick_link_view_test', 'test/views/common/rolling_restart_view_test', 'test/views/common/modal_popup_test', + 'test/views/common/sort_view_test', 'test/views/common/configs/config_history_flow_test', 'test/views/main/dashboard_test', 'test/views/main/menu_test', @@ -192,6 +194,7 @@ var files = ['test/init_model_test', 'test/models/service/hdfs_test', 'test/models/service/yarn_test', 'test/models/alert_test', + 'test/models/alert_definition_test', 'test/models/authentication_test', 'test/models/cluster_states_test', 'test/models/config_group_test', http://git-wip-us.apache.org/repos/asf/ambari/blob/93b6119c/ambari-web/app/controllers/global/cluster_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/global/cluster_controller.js b/ambari-web/app/controllers/global/cluster_controller.js index 1cebb43..7469d5b 100644 --- a/ambari-web/app/controllers/global/cluster_controller.js +++ b/ambari-web/app/controllers/global/cluster_controller.js @@ -341,7 +341,9 @@ App.ClusterController = Em.Controller.extend({ self.updateLoadStatus('serviceMetrics'); updater.updateAlertDefinitions(function () { - self.updateLoadStatus('alertDefinitions'); + updater.updateAlertDefinitionSummary(function() { + self.updateLoadStatus('alertDefinitions'); + }); }); }); }); http://git-wip-us.apache.org/repos/asf/ambari/blob/93b6119c/ambari-web/app/controllers/global/update_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/global/update_controller.js b/ambari-web/app/controllers/global/update_controller.js index bd67e01..711d994 100644 --- a/ambari-web/app/controllers/global/update_controller.js +++ b/ambari-web/app/controllers/global/update_controller.js @@ -129,6 +129,7 @@ App.UpdateController = Em.Controller.extend({ App.updater.run(this, 'graphsUpdate', 'isWorking'); App.updater.run(this, 'updateComponentConfig', 'isWorking'); App.updater.run(this, 'updateAlertDefinitions', 'isWorking', App.alertDefinitionsUpdateInterval); + App.updater.run(this, 'updateAlertDefinitionSummary', 'isWorking', App.alertDefinitionsUpdateInterval); } }.observes('isWorking'), /** @@ -453,5 +454,16 @@ App.UpdateController = Em.Controller.extend({ App.HttpClient.get(url, App.alertDefinitionsMapper, { complete: callback }); + }, + + updateAlertDefinitionSummary: function(callback) { + var testUrl = '/data/alerts/alert_summary.json'; + var realUrl = '/alerts?format=groupedSummary'; + var url = this.getUrl(testUrl, realUrl); + + App.HttpClient.get(url, App.alertDefinitionSummaryMapper, { + complete: callback + }); } + }); http://git-wip-us.apache.org/repos/asf/ambari/blob/93b6119c/ambari-web/app/controllers/main/alert_definitions_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/main/alert_definitions_controller.js b/ambari-web/app/controllers/main/alert_definitions_controller.js index 94ce3df..64163f4 100644 --- a/ambari-web/app/controllers/main/alert_definitions_controller.js +++ b/ambari-web/app/controllers/main/alert_definitions_controller.js @@ -50,57 +50,6 @@ App.MainAlertDefinitionsController = Em.ArrayController.extend({ App.ScriptAlertDefinition.find().toArray()); }.property('mapperTimestamp'), - /** - * Object for lastTriggered-filter - * @type {Em.Object} - */ - modifiedFilter: Em.Object.create({ - optionValue: 'Any', - filterModified: function () { - var time = ""; - var curTime = new Date().getTime(); - - switch (this.get('optionValue')) { - case 'Past 1 hour': - time = curTime - 3600000; - break; - case 'Past 1 Day': - time = curTime - 86400000; - break; - case 'Past 2 Days': - time = curTime - 172800000; - break; - case 'Past 7 Days': - time = curTime - 604800000; - break; - case 'Past 14 Days': - time = curTime - 1209600000; - break; - case 'Past 30 Days': - time = curTime - 2592000000; - break; - case 'Custom': - case 'Custom2': - customDatePopup.showCustomDatePopup(this, this.get('actualValues')); - break; - case 'Any': - time = ""; - break; - } - if (this.get('modified') !== "Custom") { - this.set("actualValues.startTime", time); - this.set("actualValues.endTime", ''); - } - }.observes('optionValue'), - cancel: function () { - this.set('optionValue', 'Any'); - }, - actualValues: Em.Object.create({ - startTime: "", - endTime: "" - }) - }), - toggleState: Em.K }); http://git-wip-us.apache.org/repos/asf/ambari/blob/93b6119c/ambari-web/app/mappers.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/mappers.js b/ambari-web/app/mappers.js index 917dedf..9aec70f 100644 --- a/ambari-web/app/mappers.js +++ b/ambari-web/app/mappers.js @@ -35,5 +35,6 @@ require('mappers/component_config_mapper'); require('mappers/components_state_mapper'); require('mappers/service_config_version_mapper'); require('mappers/alert_definitions_mapper'); +require('mappers/alert_definition_summary_mapper'); require('mappers/alert_instances_mapper'); require('mappers/root_service_mapper'); http://git-wip-us.apache.org/repos/asf/ambari/blob/93b6119c/ambari-web/app/mappers/alert_definition_summary_mapper.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/mappers/alert_definition_summary_mapper.js b/ambari-web/app/mappers/alert_definition_summary_mapper.js new file mode 100644 index 0000000..8b9680d --- /dev/null +++ b/ambari-web/app/mappers/alert_definition_summary_mapper.js @@ -0,0 +1,51 @@ +/** + * 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.alertDefinitionSummaryMapper = App.QuickDataMapper.create({ + + config: {}, + + map: function(data) { + if (!data.alerts_summary_grouped) return; + var alertDefinitions = Array.prototype.concat.call( + Array.prototype, App.PortAlertDefinition.find().toArray(), + App.MetricsAlertDefinition.find().toArray(), + App.WebAlertDefinition.find().toArray(), + App.AggregateAlertDefinition.find().toArray(), + App.ScriptAlertDefinition.find().toArray() + ); + data.alerts_summary_grouped.forEach(function(alertDefinitionSummary) { + var alertDefinition = alertDefinitions.findProperty('id', alertDefinitionSummary.definition_id); + if (alertDefinition) { + var summary = {}, + timestamp = 0; + Em.keys(alertDefinitionSummary.summary).forEach(function(status) { + summary[status] = alertDefinitionSummary.summary[status].count; + if (alertDefinitionSummary.summary[status].original_timestamp > timestamp) { + timestamp = alertDefinitionSummary.summary[status].original_timestamp; + } + }); + alertDefinition.setProperties({ + summary: summary, + lastTriggered: parseInt(timestamp) + }); + } + }); + } +}); http://git-wip-us.apache.org/repos/asf/ambari/blob/93b6119c/ambari-web/app/mappers/alert_definitions_mapper.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/mappers/alert_definitions_mapper.js b/ambari-web/app/mappers/alert_definitions_mapper.js index fa23cae..847cbd3 100644 --- a/ambari-web/app/mappers/alert_definitions_mapper.js +++ b/ambari-web/app/mappers/alert_definitions_mapper.js @@ -27,7 +27,7 @@ App.alertDefinitionsMapper = App.QuickDataMapper.create({ metricsUriModel: App.AlertMetricsUriDefinition, config: { - id: 'AlertDefinition.name', + id: 'AlertDefinition.id', name: 'AlertDefinition.name', label: 'AlertDefinition.label', service_id: 'AlertDefinition.service_name', @@ -75,6 +75,13 @@ App.alertDefinitionsMapper = App.QuickDataMapper.create({ var alertReportDefinitions = []; var alertMetricsSourceDefinitions = []; var alertMetricsUriDefinitions = []; + var alertDefinitions = Array.prototype.concat.call( + Array.prototype, App.PortAlertDefinition.find().toArray(), + App.MetricsAlertDefinition.find().toArray(), + App.WebAlertDefinition.find().toArray(), + App.AggregateAlertDefinition.find().toArray(), + App.ScriptAlertDefinition.find().toArray() + ); json.items.forEach(function (item) { var convertedReportDefinitions = []; @@ -94,6 +101,13 @@ App.alertDefinitionsMapper = App.QuickDataMapper.create({ item.reporting = convertedReportDefinitions; var alertDefinition = this.parseIt(item, this.get('config')); + var oldAlertDefinition = alertDefinitions.findProperty('id', alertDefinition.id); + if (oldAlertDefinition) { + // new values will be parsed in the another mapper, so for now just use old values + alertDefinition.summary = oldAlertDefinition.get('summary'); + alertDefinition.last_triggered = oldAlertDefinition.get('lastTriggered'); + } + // map properties dependent on Alert Definition type switch (item.AlertDefinition.source.type) { case 'PORT': http://git-wip-us.apache.org/repos/asf/ambari/blob/93b6119c/ambari-web/app/models/alert_definition.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/models/alert_definition.js b/ambari-web/app/models/alert_definition.js index ea1f1c4..81e5e60 100644 --- a/ambari-web/app/models/alert_definition.js +++ b/ambari-web/app/models/alert_definition.js @@ -18,7 +18,6 @@ var App = require('app'); var dateUtils = require('utils/date'); -var dataUtils = require('utils/data_manipulation'); App.AlertDefinition = DS.Model.extend({ @@ -31,34 +30,49 @@ App.AlertDefinition = DS.Model.extend({ interval: DS.attr('number'), type: DS.attr('string'), reporting: DS.hasMany('App.AlertReportDefinition'), - alerts: DS.hasMany('App.AlertInstance'), + lastTriggered: DS.attr('number'), + + /** + * Counts of alert grouped by their status + * Format: + * <code> + * { + * "CRITICAL": 1, + * "OK": 1, + * "UNKNOWN": 0, + * "WARN": 0 + * } + * </code> + * @type {object} + */ + summary: {}, /** * Formatted timestamp for latest alert triggering for current alertDefinition * @type {string} */ - lastTriggered: function () { - return dateUtils.dateFormat(Math.max.apply(Math, this.get('alerts').mapProperty('latestTimestamp'))); - }.property('alerts.@each.latestTimestamp'), + lastTriggeredFormatted: function () { + return dateUtils.dateFormat(this.get('lastTriggered')); + }.property('lastTriggered'), /** * Status generates from child-alerts - * Format: 1 OK / 2 WARN / 1 CRIT / 1 DISABLED / 1 UNKNOWN + * Format: 1 OK / 2 WARN / 1 CRIT / 1 UNKNOWN * If some there are no alerts with some state, this state isn't shown * Order is equal to example * @type {string} */ status: function () { var typeIcons = this.get('typeIcons'), - ordered = ['OK', 'WARNING', 'CRITICAL', 'DISABLED', 'UNKNOWN'], - grouped = dataUtils.groupPropertyValues(this.get('alerts'), 'state'); - return ordered.map(function (state) { - if (grouped[state]) { - return grouped[state].length + ' <span class="' + typeIcons[state] + ' alert-state-' + state + '"></span>'; + order = this.get('order'), + summary = this.get('summary'); + return order.map(function (state) { + if (summary[state]) { + return summary[state] + ' <span class="' + typeIcons[state] + ' alert-state-' + state + '"></span>'; } return null; }).compact().join(' / '); - }.property('alerts.@each.state'), + }.property('summary'), /** * List of css-classes for alert types @@ -72,6 +86,8 @@ App.AlertDefinition = DS.Model.extend({ 'UNKNOWN': 'icon-question-sign' }, + order: ['OK', 'WARNING', 'CRITICAL', 'UNKNOWN'], + // todo: in future be mapped from server response description: 'Description for the Alert Definition.', // todo: in future be mapped from server response http://git-wip-us.apache.org/repos/asf/ambari/blob/93b6119c/ambari-web/app/templates/main/alerts.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/main/alerts.hbs b/ambari-web/app/templates/main/alerts.hbs index 4ceb216..8faa8fe 100644 --- a/ambari-web/app/templates/main/alerts.hbs +++ b/ambari-web/app/templates/main/alerts.hbs @@ -49,7 +49,7 @@ </td> <td>{{{alertDefinition.status}}}</td> <td>{{alertDefinition.service.serviceName}}</td> - <td>{{alertDefinition.lastTriggered}}</td> + <td>{{alertDefinition.lastTriggeredFormatted}}</td> <td class="last"> <a href="#" {{action "toggleState" alertDefinition target="controller"}} {{bindAttr class="alertDefinition.enabled:enabled:disabled"}}> <span class="icon-off"></span> http://git-wip-us.apache.org/repos/asf/ambari/blob/93b6119c/ambari-web/app/views/common/filter_view.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/common/filter_view.js b/ambari-web/app/views/common/filter_view.js index be5d069..3a818d8 100644 --- a/ambari-web/app/views/common/filter_view.js +++ b/ambari-web/app/views/common/filter_view.js @@ -593,6 +593,15 @@ module.exports = { return true; }; break; + case 'alert_status': + /** + * origin - alertDefinition.summary + * compareValue - "OK|WARN..." + */ + return function (origin, compareValue) { + return !!origin[compareValue] && origin[compareValue] > 0; + }; + break; case 'string': default: return function (origin, compareValue) { http://git-wip-us.apache.org/repos/asf/ambari/blob/93b6119c/ambari-web/app/views/common/sort_view.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/common/sort_view.js b/ambari-web/app/views/common/sort_view.js index 30edb5b..e66630c 100644 --- a/ambari-web/app/views/common/sort_view.js +++ b/ambari-web/app/views/common/sort_view.js @@ -168,6 +168,28 @@ var wrapperView = Em.View.extend({ } }; break; + case 'alert_status': + func = function(a, b) { + var a_summary = a.get('summary'), + b_summary = b.get('summary'), + st_order = a.get('order'), + ret = 0; + for(var i = 0; i < st_order.length; i++) { + var a_v = Em.isNone(a_summary[st_order[i]]) ? 0 : a_summary[st_order[i]], + b_v = Em.isNone(b_summary[st_order[i]]) ? 0 : b_summary[st_order[i]]; + ret = b_v - a_v; + if (ret !== 0) { + break; + } + } + if (order) { + return ret; + } + else { + return -ret; + } + }; + break; default: func = function (a, b) { if (order) { @@ -183,7 +205,7 @@ var wrapperView = Em.View.extend({ return 1; return 0; } - } + }; } return func; } http://git-wip-us.apache.org/repos/asf/ambari/blob/93b6119c/ambari-web/app/views/main/alert_definitions_view.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/main/alert_definitions_view.js b/ambari-web/app/views/main/alert_definitions_view.js index b8e8ef4..6e9c276 100644 --- a/ambari-web/app/views/main/alert_definitions_view.js +++ b/ambari-web/app/views/main/alert_definitions_view.js @@ -36,7 +36,7 @@ App.MainAlertDefinitionsView = App.TableView.extend({ return this.get('content.length'); }.property('content.length'), - colPropAssoc: ['', 'label', 'state', 'service.serviceName', 'lastTriggered'], + colPropAssoc: ['', 'label', 'summary', 'service.serviceName', 'lastTriggered'], sortView: sort.wrapperView, @@ -56,9 +56,9 @@ App.MainAlertDefinitionsView = App.TableView.extend({ */ statusSort: sort.fieldView.extend({ column: 2, - name: 'status', + name: 'summary', displayName: Em.I18n.t('common.status'), - type: 'string' + type: 'alert_status' }), /** @@ -78,9 +78,9 @@ App.MainAlertDefinitionsView = App.TableView.extend({ */ lastTriggeredSort: sort.fieldView.extend({ column: 4, - name: 'memory', + name: 'lastTriggered', displayName: Em.I18n.t('alerts.table.header.lastTriggered'), - type: 'date' + type: 'number' }), /** @@ -129,7 +129,7 @@ App.MainAlertDefinitionsView = App.TableView.extend({ } ], onChangeValue: function () { - this.get('parentView').updateFilter(this.get('column'), this.get('value'), 'select'); + this.get('parentView').updateFilter(this.get('column'), this.get('value'), 'alert_status'); } }), @@ -164,12 +164,6 @@ App.MainAlertDefinitionsView = App.TableView.extend({ */ triggeredFilterView: filters.createSelectView({ column: 4, - triggeredOnSameValue: [ - { - values: ['Custom', 'Custom2'], - displayAs: 'Custom' - } - ], appliedEmptyValue: ["", ""], fieldType: 'filter-input-width,modified-filter', content: [ @@ -200,23 +194,12 @@ App.MainAlertDefinitionsView = App.TableView.extend({ { value: 'Past 30 Days', label: 'Past 30 Days' - }, - { - value: 'Custom', - label: 'Custom' - }, - { - value: 'Custom2', - label: 'Custom2' } ], emptyValue: 'Any', - valueBinding: "controller.modifiedFilter.optionValue", - startTimeBinding: "controller.modifiedFilter.actualValues.startTime", - endTimeBinding: "controller.modifiedFilter.actualValues.endTime", - onTimeChange: function () { - this.get('parentView').updateFilter(this.get('column'), [this.get('controller.modifiedFilter.actualValues.startTime'), this.get('controller.modifiedFilter.actualValues.endTime')], 'range'); - }.observes('controller.modifiedFilter.actualValues.startTime', 'controller.modifiedFilter.actualValues.endTime') + onChangeValue: function () { + this.get('parentView').updateFilter(this.get('column'), this.get('value'), 'date'); + } }), /** http://git-wip-us.apache.org/repos/asf/ambari/blob/93b6119c/ambari-web/test/controllers/global/update_controller_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/controllers/global/update_controller_test.js b/ambari-web/test/controllers/global/update_controller_test.js index 960a83f..7b8c3a3 100644 --- a/ambari-web/test/controllers/global/update_controller_test.js +++ b/ambari-web/test/controllers/global/update_controller_test.js @@ -62,7 +62,7 @@ describe('App.UpdateController', function () { it('isWorking = true', function () { controller.set('isWorking', true); - expect(App.updater.run.callCount).to.equal(7); + expect(App.updater.run.callCount).to.equal(8); }); }); http://git-wip-us.apache.org/repos/asf/ambari/blob/93b6119c/ambari-web/test/mappers/alert_definition_summary_mapper_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/mappers/alert_definition_summary_mapper_test.js b/ambari-web/test/mappers/alert_definition_summary_mapper_test.js new file mode 100644 index 0000000..36e8d2d --- /dev/null +++ b/ambari-web/test/mappers/alert_definition_summary_mapper_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('mappers/alert_definition_summary_mapper'); + +describe('App.alertDefinitionSummaryMapper', function () { + + describe('#map', function() { + + var testModels = [ + App.PortAlertDefinition.createRecord({id: 1, type: 'PORT'}), + App.MetricsAlertDefinition.createRecord({id: 2, type: 'METRICS'}), + App.WebAlertDefinition.createRecord({id: 3, type: 'WEB'}), + App.AggregateAlertDefinition.createRecord({id: 4, type: 'AGGREGATE'}), + App.ScriptAlertDefinition.createRecord({id: 5, type: 'SCRIPT'}) + ], + dataToMap = { + alerts_summary_grouped: [ + { + definition_id: 1, + summary: { + OK: {count: 1, original_timestamp: 1}, + WARNING: {count: 1, original_timestamp: 2}, + CRITICAL: {count: 0, original_timestamp: 0}, + UNKNOWN: {count: 0, original_timestamp: 0} + } + }, + { + definition_id: 2, + summary: { + OK: {count: 1, original_timestamp: 1}, + WARNING: {count: 5, original_timestamp: 2}, + CRITICAL: {count: 1, original_timestamp: 1}, + UNKNOWN: {count: 1, original_timestamp: 3} + } + }, + { + definition_id: 3, + summary: { + OK: {count: 1, original_timestamp: 1}, + WARNING: {count: 2, original_timestamp: 2}, + CRITICAL: {count: 3, original_timestamp: 4}, + UNKNOWN: {count: 4, original_timestamp: 3} + } + }, + { + definition_id: 4, + summary: { + OK: {count: 4, original_timestamp: 1}, + WARNING: {count: 3, original_timestamp: 2}, + CRITICAL: {count: 2, original_timestamp: 1}, + UNKNOWN: {count: 1, original_timestamp: 2} + } + }, + { + definition_id: 5, + summary: { + OK: {count: 1, original_timestamp: 1}, + WARNING: {count: 1, original_timestamp: 2}, + CRITICAL: {count: 1, original_timestamp: 3}, + UNKNOWN: {count: 1, original_timestamp: 4} + } + } + ] + }; + + beforeEach(function() { + + sinon.stub(App.PortAlertDefinition, 'find', function() {return testModels.filterProperty('type', 'PORT');}); + sinon.stub(App.MetricsAlertDefinition, 'find', function() {return testModels.filterProperty('type', 'METRICS');}); + sinon.stub(App.WebAlertDefinition, 'find', function() {return testModels.filterProperty('type', 'WEB');}); + sinon.stub(App.AggregateAlertDefinition, 'find', function() {return testModels.filterProperty('type', 'AGGREGATE');}); + sinon.stub(App.ScriptAlertDefinition, 'find', function() {return testModels.filterProperty('type', 'SCRIPT');}); + + }); + + afterEach(function() { + + App.PortAlertDefinition.find.restore(); + App.MetricsAlertDefinition.find.restore(); + App.WebAlertDefinition.find.restore(); + App.AggregateAlertDefinition.find.restore(); + App.ScriptAlertDefinition.find.restore(); + + }); + + it('should map summary info for each alert', function() { + + App.alertDefinitionSummaryMapper.map(dataToMap); + expect(App.PortAlertDefinition.find().findProperty('id', 1).get('lastTriggered')).to.equal(2); + expect(App.PortAlertDefinition.find().findProperty('id', 1).get('summary')).to.eql({OK: 1, WARNING: 1, CRITICAL: 0, UNKNOWN: 0}); + + expect(App.MetricsAlertDefinition.find().findProperty('id', 2).get('lastTriggered')).to.equal(3); + expect(App.MetricsAlertDefinition.find().findProperty('id', 2).get('summary')).to.eql({OK: 1, WARNING: 5, CRITICAL: 1, UNKNOWN: 1}); + + expect(App.WebAlertDefinition.find().findProperty('id', 3).get('lastTriggered')).to.equal(4); + expect(App.WebAlertDefinition.find().findProperty('id', 3).get('summary')).to.eql({OK: 1, WARNING: 2, CRITICAL: 3, UNKNOWN: 4}); + + expect(App.AggregateAlertDefinition.find().findProperty('id', 4).get('lastTriggered')).to.equal(2); + expect(App.AggregateAlertDefinition.find().findProperty('id', 4).get('summary')).to.eql({OK: 4, WARNING: 3, CRITICAL: 2, UNKNOWN: 1}); + + expect(App.ScriptAlertDefinition.find().findProperty('id', 5).get('lastTriggered')).to.equal(4); + expect(App.ScriptAlertDefinition.find().findProperty('id', 5).get('summary')).to.eql({OK: 1, WARNING: 1, CRITICAL: 1, UNKNOWN: 1}); + + }); + + }); + +}); http://git-wip-us.apache.org/repos/asf/ambari/blob/93b6119c/ambari-web/test/models/alert_definition_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/models/alert_definition_test.js b/ambari-web/test/models/alert_definition_test.js new file mode 100644 index 0000000..04a9c8e --- /dev/null +++ b/ambari-web/test/models/alert_definition_test.js @@ -0,0 +1,60 @@ +/** + * 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/alert_definition'); + +var model; + +describe('App.AlertDefinition', function() { + + beforeEach(function() { + + model = App.AlertDefinition.createRecord(); + + }); + + describe('#status', function() { + + Em.A([ + { + summary: {OK: 1, UNKNOWN: 1, WARNING: 2}, + m: 'No CRITICAL', + e: '1 <span class="icon-ok-sign alert-state-OK"></span> / ' + + '2 <span class="icon-warning-sign alert-state-WARNING"></span> / ' + + '1 <span class="icon-question-sign alert-state-UNKNOWN"></span>' + }, + { + summary: {WARNING: 2, CRITICAL: 3, UNKNOWN: 1, OK: 1}, + m: 'All states exists', + e: '1 <span class="icon-ok-sign alert-state-OK"></span> / ' + + '2 <span class="icon-warning-sign alert-state-WARNING"></span> / ' + + '3 <span class="icon-remove alert-state-CRITICAL"></span> / ' + + '1 <span class="icon-question-sign alert-state-UNKNOWN"></span>' + } + ]).forEach(function(test) { + it(test.m, function() { + model.set('summary', test.summary); + expect(model.get('status')).to.equal(test.e); + }); + }); + + }); + +}); http://git-wip-us.apache.org/repos/asf/ambari/blob/93b6119c/ambari-web/test/views/common/filter_view_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/views/common/filter_view_test.js b/ambari-web/test/views/common/filter_view_test.js index aa077bb..48ad66f 100644 --- a/ambari-web/test/views/common/filter_view_test.js +++ b/ambari-web/test/views/common/filter_view_test.js @@ -22,7 +22,6 @@ require('utils/helper'); describe('filters.getFilterByType', function () { - describe('ambari-bandwidth', function () { var filter = filters.getFilterByType('ambari-bandwidth'); @@ -465,4 +464,33 @@ describe('filters.getFilterByType', function () { }) }); }); + + describe('alert_status', function () { + + var filter = filters.getFilterByType('alert_status'); + + Em.A([ + { + origin: {OK: 1}, + compareValue: 'OK', + e: true + }, + { + origin: {WARN: 1}, + compareValue: 'OK', + e: false + }, + { + origin: {WARN: 0}, + compareValue: 'WARN', + e: false + } + ]).forEach(function(test, i) { + it('test #' + (i + 1), function() { + expect(filter(test.origin, test.compareValue)).to.equal(test.e); + }); + }); + + }); + }); http://git-wip-us.apache.org/repos/asf/ambari/blob/93b6119c/ambari-web/test/views/common/sort_view_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/views/common/sort_view_test.js b/ambari-web/test/views/common/sort_view_test.js new file mode 100644 index 0000000..f7d5f27 --- /dev/null +++ b/ambari-web/test/views/common/sort_view_test.js @@ -0,0 +1,68 @@ +/** + * 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 sort = require('views/common/sort_view'); +require('utils/misc'); +require('utils/string_utils'); + +describe('#wrapperView', function () { + + describe('#getSortFunc', function () { + + describe('alert_status', function () { + + var property = Em.Object.create({type: 'alert_status'}); + + Em.A([ + { + a: App.AlertDefinition.createRecord({summary: {OK: 1, WARNING: 1}}), + b: App.AlertDefinition.createRecord({summary: {WARNING: 1}}), + order: true, + e: -1 + }, + { + a: App.AlertDefinition.createRecord({summary: {OK: 1, WARNING: 2}}), + b: App.AlertDefinition.createRecord({summary: {OK: 1, WARNING: 1}}), + order: true, + e: -1 + }, + { + a: App.AlertDefinition.createRecord({summary: {OK: 1, WARNING: 1}}), + b: App.AlertDefinition.createRecord({summary: {WARNING: 1}}), + order: false, + e: 1 + }, + { + a: App.AlertDefinition.createRecord({summary: {OK: 1, WARNING: 2}}), + b: App.AlertDefinition.createRecord({summary: {OK: 1, WARNING: 1}}), + order: false, + e: 1 + } + ]).forEach(function(test, i) { + it('test #' + (i + 1), function () { + var func = sort.wrapperView.create().getSortFunc(property, test.order); + expect(func(test.a, test.b)).to.equal(test.e); + }); + }); + + }); + + }); + +});