AMBARI-13715 Refactor Quick Links View. (atkach)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/e97b3216 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/e97b3216 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/e97b3216 Branch: refs/heads/trunk Commit: e97b321647e5966bdd94291ce454bf29b8cf2ed5 Parents: 4b0b104 Author: Andrii Tkach <[email protected]> Authored: Wed Nov 4 19:20:19 2015 +0200 Committer: Andrii Tkach <[email protected]> Committed: Wed Nov 4 19:20:19 2015 +0200 ---------------------------------------------------------------------- ambari-web/app/app.js | 7 +- ambari-web/app/assets/test/tests.js | 1 + ambari-web/app/models/quick_links.js | 54 +- ambari-web/app/utils/ajax/ajax.js | 2 +- ambari-web/app/utils/ember_reopen.js | 30 + .../app/views/common/quick_view_link_view.js | 586 ++++++------ .../admin/highAvailability/progress_view.js | 42 +- ambari-web/test/app_test.js | 32 +- .../test/views/common/chart/linear_time_test.js | 10 +- .../test/views/common/quick_link_view_test.js | 919 ++++++++++--------- .../highAvailability/progress_view_test.js | 171 ++++ ambari-web/test/views/main/admin_test.js | 10 +- 12 files changed, 1091 insertions(+), 773 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/e97b3216/ambari-web/app/app.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/app.js b/ambari-web/app/app.js index 16bcc28..12b25b9 100644 --- a/ambari-web/app/app.js +++ b/ambari-web/app/app.js @@ -52,9 +52,7 @@ module.exports = Em.Application.create({ * flag is true when upgrade process is running * @returns {boolean} */ - upgradeInProgress: function() { - return ["IN_PROGRESS"].contains(this.get('upgradeState')); - }.property('upgradeState'), + upgradeInProgress: Em.computed.equal('upgradeState', 'IN_PROGRESS'), /** * flag is true when upgrade process is waiting for user action @@ -228,8 +226,7 @@ module.exports = Em.Application.create({ * @type {bool} */ isHaEnabled: function () { - var isHDFSInstalled = App.Service.find().findProperty('serviceName','HDFS'); - return !!isHDFSInstalled && !this.HostComponent.find().someProperty('componentName', 'SECONDARY_NAMENODE'); + return App.Service.find('HDFS').get('isLoaded') && !App.HostComponent.find().someProperty('componentName', 'SECONDARY_NAMENODE'); }.property('router.clusterController.dataLoadList.services', 'router.clusterController.isServiceContentFullyLoaded'), /** http://git-wip-us.apache.org/repos/asf/ambari/blob/e97b3216/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 6617c97..4d60f80 100644 --- a/ambari-web/app/assets/test/tests.js +++ b/ambari-web/app/assets/test/tests.js @@ -266,6 +266,7 @@ var files = [ 'test/views/main/admin/highAvailability/nameNode/step6_view_test', 'test/views/main/admin/highAvailability/nameNode/step8_view_test', 'test/views/main/admin/highAvailability/nameNode/wizard_view_test', + 'test/views/main/admin/highAvailability/progress_view_test', 'test/views/common/host_progress_popup_body_view_test', 'test/views/common/configs/config_history_flow_test', 'test/views/common/configs/overriddenProperty_view_test', http://git-wip-us.apache.org/repos/asf/ambari/blob/e97b3216/ambari-web/app/models/quick_links.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/models/quick_links.js b/ambari-web/app/models/quick_links.js index 1aac608..eb9dfd6 100644 --- a/ambari-web/app/models/quick_links.js +++ b/ambari-web/app/models/quick_links.js @@ -22,7 +22,7 @@ var portRegex = '\\w*:(\\d+)'; App.QuickLinks = DS.Model.extend({ label: DS.attr('string'), url: DS.attr('string'), - service_id: DS.attr('string'), + serviceName: DS.attr('string'), template: DS.attr('string'), http_config: DS.attr('string'), https_config: DS.attr('string'), @@ -38,7 +38,7 @@ App.QuickLinks.FIXTURES = [ id:1, label:'NameNode UI', url:'%@://%@:%@', - service_id: 'HDFS', + service_name: 'HDFS', template:'%@://%@:%@', http_config: 'dfs.namenode.http-address', https_config: 'dfs.namenode.https-address', @@ -51,7 +51,7 @@ App.QuickLinks.FIXTURES = [ id:2, label:'NameNode logs', url:'%@://%@:%@/logs', - service_id: 'HDFS', + service_name: 'HDFS', template:'%@://%@:%@/logs', http_config: 'dfs.namenode.http-address', https_config: 'dfs.namenode.https-address', @@ -64,7 +64,7 @@ App.QuickLinks.FIXTURES = [ id:3, label:'NameNode JMX', url:'%@://%@:%@/jmx', - service_id: 'HDFS', + service_name: 'HDFS', template:'%@://%@:%@/jmx', http_config: 'dfs.namenode.http-address', https_config: 'dfs.namenode.https-address', @@ -77,7 +77,7 @@ App.QuickLinks.FIXTURES = [ id:4, label:'Thread Stacks', url:'%@://%@:%@/stacks', - service_id: 'HDFS', + service_name: 'HDFS', template:'%@://%@:%@/stacks', http_config: 'dfs.namenode.http-address', https_config: 'dfs.namenode.https-address', @@ -90,7 +90,7 @@ App.QuickLinks.FIXTURES = [ id:13, label:'HBase Master UI', url:'%@://%@:%@/master-status', - service_id: 'HBASE', + service_name: 'HBASE', template:'%@://%@:%@/master-status', http_config: 'hbase.master.info.port', site: 'hbase-site', @@ -101,7 +101,7 @@ App.QuickLinks.FIXTURES = [ id:14, label:'HBase Logs', url:'%@://%@:60010/logs', - service_id: 'HBASE', + service_name: 'HBASE', template:'%@://%@:%@/logs', http_config: 'hbase.master.info.port', site: 'hbase-site', @@ -112,7 +112,7 @@ App.QuickLinks.FIXTURES = [ id:15, label:'Zookeeper Info', url:'%@://%@:60010/zk.jsp', - service_id: 'HBASE', + service_name: 'HBASE', template:'%@://%@:%@/zk.jsp', http_config: 'hbase.master.info.port', site: 'hbase-site', @@ -123,7 +123,7 @@ App.QuickLinks.FIXTURES = [ id:16, label:'HBase Master JMX', url:'%@://%@:60010/jmx', - service_id: 'HBASE', + service_name: 'HBASE', template:'%@://%@:%@/jmx', http_config: 'hbase.master.info.port', site: 'hbase-site', @@ -134,7 +134,7 @@ App.QuickLinks.FIXTURES = [ id:17, label:'Debug Dump', url:'%@://%@:%@/dump', - service_id: 'HBASE', + service_name: 'HBASE', template:'%@://%@:%@/dump', http_config: 'hbase.master.info.port', site: 'hbase-site', @@ -145,7 +145,7 @@ App.QuickLinks.FIXTURES = [ id:18, label:'Thread Stacks', url:'%@://%@:%@/stacks', - service_id: 'HBASE', + service_name: 'HBASE', template:'%@://%@:%@/stacks', http_config: 'hbase.master.info.port', site: 'hbase-site', @@ -156,7 +156,7 @@ App.QuickLinks.FIXTURES = [ id:19, label:'Oozie Web UI', url:'%@://%@:%@/oozie?user.name=%@', - service_id: 'OOZIE', + service_name: 'OOZIE', template:'%@://%@:%@/oozie?user.name=%@', http_config: 'oozie.base.url', site: 'oozie-site', @@ -167,7 +167,7 @@ App.QuickLinks.FIXTURES = [ id:20, label:'Ganglia Web UI', url:'%@://%@/ganglia', - service_id: 'GANGLIA', + service_name: 'GANGLIA', template:'%@://%@/ganglia' }, @@ -175,7 +175,7 @@ App.QuickLinks.FIXTURES = [ id:23, label:'ResourceManager UI', url:'%@://%@:%@', - service_id: 'YARN', + service_name: 'YARN', template:'%@://%@:%@', http_config: 'yarn.resourcemanager.webapp.address', https_config: 'yarn.resourcemanager.webapp.https.address', @@ -189,7 +189,7 @@ App.QuickLinks.FIXTURES = [ id:24, label:'ResourceManager logs', url:'%@://%@:%@/logs', - service_id: 'YARN', + service_name: 'YARN', template:'%@://%@:%@/logs', http_config: 'yarn.resourcemanager.webapp.address', https_config: 'yarn.resourcemanager.webapp.https.address', @@ -202,7 +202,7 @@ App.QuickLinks.FIXTURES = [ id:25, label:'ResourceManager JMX', url:'%@://%@:%@/jmx', - service_id: 'YARN', + service_name: 'YARN', template:'%@://%@:%@/jmx', http_config: 'yarn.resourcemanager.webapp.address', https_config: 'yarn.resourcemanager.webapp.https.address', @@ -215,7 +215,7 @@ App.QuickLinks.FIXTURES = [ id:26, label:'Thread Stacks', url:'%@://%@:%@/stacks', - service_id: 'YARN', + service_name: 'YARN', template:'%@://%@:%@/stacks', http_config: 'yarn.resourcemanager.webapp.address', https_config: 'yarn.resourcemanager.webapp.https.address', @@ -228,7 +228,7 @@ App.QuickLinks.FIXTURES = [ id:27, label:'JobHistory UI', url:'%@://%@:%@', - service_id: 'MAPREDUCE2', + service_name: 'MAPREDUCE2', template:'%@://%@', http_config: 'mapreduce.jobhistory.webapp.address', https_config: 'mapreduce.jobhistory.webapp.https.address', @@ -240,7 +240,7 @@ App.QuickLinks.FIXTURES = [ id:28, label:'JobHistory logs', url:'%@://%@:%@/logs', - service_id: 'MAPREDUCE2', + service_name: 'MAPREDUCE2', template:'%@://%@/logs', http_config: 'mapreduce.jobhistory.webapp.address', https_config: 'mapreduce.jobhistory.webapp.https.address', @@ -252,7 +252,7 @@ App.QuickLinks.FIXTURES = [ id:29, label:'JobHistory JMX', url:'%@://%@:%@/jmx', - service_id: 'MAPREDUCE2', + service_name: 'MAPREDUCE2', template:'%@://%@/jmx', http_config: 'mapreduce.jobhistory.webapp.address', https_config: 'mapreduce.jobhistory.webapp.https.address', @@ -264,7 +264,7 @@ App.QuickLinks.FIXTURES = [ id:30, label:'Thread Stacks', url:'%@://%@:%@/stacks', - service_id: 'MAPREDUCE2', + service_name: 'MAPREDUCE2', template:'%@://%@/stacks', http_config: 'mapreduce.jobhistory.webapp.address', https_config: 'mapreduce.jobhistory.webapp.https.address', @@ -276,7 +276,7 @@ App.QuickLinks.FIXTURES = [ id:31, label:'Storm UI', url:'%@://%@:%@/', - service_id: 'STORM', + service_name: 'STORM', template:'%@://%@:%@/', http_config: 'ui.port', site: 'storm-site', @@ -287,7 +287,7 @@ App.QuickLinks.FIXTURES = [ id:32, label:'Falcon Web UI', url:'%@://%@:%@/index.html?user.name=%@', - service_id: 'FALCON', + service_name: 'FALCON', template:'%@://%@:%@/index.html?user.name=%@', http_config: 'falcon_port', site: 'falcon-env', @@ -298,7 +298,7 @@ App.QuickLinks.FIXTURES = [ id: 33, label:'Ranger Admin UI', url:'%@://%@:%@/', - service_id: 'RANGER', + service_name: 'RANGER', template:'%@://%@:%@/', http_config: 'http.service.port', https_config: 'https.service.port', @@ -311,7 +311,7 @@ App.QuickLinks.FIXTURES = [ id: 34, label:'Spark History Server UI', url:'%@://%@:%@/', - service_id: 'SPARK', + service_name: 'SPARK', template:'%@://%@:%@/', http_config: 'spark.history.ui.port', site: 'spark-defaults', @@ -322,7 +322,7 @@ App.QuickLinks.FIXTURES = [ id:35, label:'Accumulo Monitor UI', url:'%@://%@:%@/', - service_id: 'ACCUMULO', + service_name: 'ACCUMULO', template:'%@://%@:%@/', http_config: 'monitor.port.client', https_config: 'monitor.port.client', @@ -335,7 +335,7 @@ App.QuickLinks.FIXTURES = [ id:36, label:'Atlas Dashboard', url:'%@://%@:%@/#!/search?user.name=%@', - service_id: 'ATLAS', + service_name: 'ATLAS', template:'%@://%@:%@/#!/search?user.name=%@', http_config: 'atlas.server.http.port', https_config: 'atlas.server.https.port', http://git-wip-us.apache.org/repos/asf/ambari/blob/e97b3216/ambari-web/app/utils/ajax/ajax.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/utils/ajax/ajax.js b/ambari-web/app/utils/ajax/ajax.js index 4a3992e..9ab6f30 100644 --- a/ambari-web/app/utils/ajax/ajax.js +++ b/ambari-web/app/utils/ajax/ajax.js @@ -2310,7 +2310,7 @@ var urls = { 'mock': '' }, 'hosts.for_quick_links': { - 'real': '/clusters/{clusterName}/hosts?Hosts/host_name.in({masterHosts})&fields=Hosts/public_host_name,host_components/HostRoles/component_name{urlParams}&minimal_response=true', + 'real': '/clusters/{clusterName}/hosts?Hosts/host_name.in({masterHosts})&fields=Hosts/public_host_name{urlParams}&minimal_response=true', 'mock': '/data/hosts/quick_links.json' }, 'hosts.confirmed.install': { http://git-wip-us.apache.org/repos/asf/ambari/blob/e97b3216/ambari-web/app/utils/ember_reopen.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/utils/ember_reopen.js b/ambari-web/app/utils/ember_reopen.js index 08f61b8..b1bcdcf 100644 --- a/ambari-web/app/utils/ember_reopen.js +++ b/ambari-web/app/utils/ember_reopen.js @@ -205,3 +205,33 @@ Em.View.reopen({ Ember.TextArea.reopen({ attributeBindings: ['readonly'] }); + +/** + * + * A computed property that returns true if the provided dependent property + * is equal to the given value. + * Example* + * ```javascript + * var Hamster = Ember.Object.extend({ + * napTime: Ember.computed.equal('state', 'sleepy') + * }); + * var hamster = Hamster.create(); + * hamster.get('napTime'); // false + * hamster.set('state', 'sleepy'); + * hamster.get('napTime'); // true + * hamster.set('state', 'hungry'); + * hamster.get('napTime'); // false + * ``` + * @method equal + * @for Ember.computed + * @param {String} dependentKey + * @param {String|Number|Object} value + * @return {Ember.ComputedProperty} computed property which returns true if + * the original value for property is equal to the given value. + * @public + */ +Ember.computed.equal = function(dependentKey, value) { + return Ember.computed(dependentKey, function(key) { + return Ember.get(this, dependentKey) === value; + }).cacheable(); +}; http://git-wip-us.apache.org/repos/asf/ambari/blob/e97b3216/ambari-web/app/views/common/quick_view_link_view.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/common/quick_view_link_view.js b/ambari-web/app/views/common/quick_view_link_view.js index ad03526..adc1695 100644 --- a/ambari-web/app/views/common/quick_view_link_view.js +++ b/ambari-web/app/views/common/quick_view_link_view.js @@ -23,8 +23,78 @@ App.QuickViewLinks = Em.View.extend({ isLoaded: false, + /** + * service which has blank target of link + * @type {Array} + */ + servicesHasBlankTarget: [ + 'HDFS', + 'YARN', + 'MAPREDUCE2', + 'HBASE', + 'OOZIE', + 'STORM', + 'SPARK', + 'FALCON', + 'ACCUMULO', + 'ATLAS', + 'RANGER' + ], + + /** + * Updated quick links. Here we put correct hostname to url + * @type {Array} + */ + quickLinks: [], + + actualTags: [], + + configProperties: [], + + /** + * list of files that contains properties for enabling/disabling ssl + */ + requiredSiteNames: ['hadoop-env', 'yarn-env', 'hbase-env', 'oozie-env', 'mapred-env', 'storm-env', 'falcon-env', 'core-site', 'hdfs-site', 'hbase-site', 'oozie-site', 'yarn-site', 'mapred-site', 'storm-site', 'spark-defaults', 'accumulo-site', 'application-properties', 'ranger-admin-site', 'ranger-site', 'admin-properties'], + + /** + * @type {string} + */ + linkTarget: function () { + if (this.get('servicesHasBlankTarget').contains(this.get('content.serviceName'))) { + return "_blank"; + } + return ""; + }.property('content.serviceName'), + + /** + * @type {object} + */ + ambariProperties: function () { + return App.router.get('clusterController.ambariProperties'); + }.property().volatile(), + + didInsertElement: function () { + this.setQuickLinks(); + }, + + willDestroyElement: function () { + this.get('configProperties').clear(); + this.get('actualTags').clear(); + this.get('quickLinks').clear(); + }, + + setQuickLinks: function () { + if (App.get('router.clusterController.isServiceMetricsLoaded')) { + this.loadTags(); + } + }.observes('App.currentStackVersionNumber', 'App.singleNodeInstall', 'App.router.clusterController.isServiceMetricsLoaded'), + + /** + * call for configuration tags + * @returns {$.ajax} + */ loadTags: function () { - App.ajax.send({ + return App.ajax.send({ name: 'config.tags', sender: this, success: 'loadTagsSuccess', @@ -49,43 +119,54 @@ App.QuickViewLinks = Em.View.extend({ }); }, - loadTagsError: function() { + loadTagsError: function () { this.getQuickLinksHosts(); }, + /** + * call for public host names + * @returns {$.ajax} + */ getQuickLinksHosts: function () { var masterHosts = App.HostComponent.find().filterProperty('isMaster').mapProperty('hostName').uniq(); - App.ajax.send({ + return App.ajax.send({ name: 'hosts.for_quick_links', sender: this, data: { clusterName: App.get('clusterName'), masterHosts: masterHosts.join(','), - urlParams: ',host_components/metrics/hbase/master/IsActiveMaster' + urlParams: (this.get('content.serviceName') === 'HBASE') ? ',host_components/metrics/hbase/master/IsActiveMaster' : '' }, success: 'setQuickLinksSuccessCallback' }); }, - actualTags: [], - - configProperties: [], + setQuickLinksSuccessCallback: function (response) { + var hosts = this.getHosts(response, this.get('content.serviceName')); + if (hosts.length === 0 || Em.isNone(this.get('content.quickLinks'))) { + this.setEmptyLinks(); + } else if (hosts.length === 1) { + this.setSingleHostLinks(hosts); + } else { + this.setMultipleHostLinks(hosts); + } + }, /** - * list of files that contains properties for enabling/disabling ssl - */ - requiredSiteNames: ['hadoop-env','yarn-env','hbase-env','oozie-env','mapred-env','storm-env', 'falcon-env', 'core-site', 'hdfs-site', 'hbase-site', 'oozie-site', 'yarn-site', 'mapred-site', 'storm-site', 'spark-defaults', 'accumulo-site', 'application-properties', 'ranger-admin-site', 'ranger-site', 'admin-properties'], - /** * Get public host name by its host name. * * @method getPublicHostName * @param {Object[]} hosts - list of hosts from response - * @param {String} hostName - * @return {String} + * @param {string} hostName + * @return {string|null} **/ - getPublicHostName: function(hosts, hostName) { - return Em.get(hosts.findProperty('Hosts.host_name', hostName), 'Hosts.public_host_name'); + getPublicHostName: function (hosts, hostName) { + var host = hosts.findProperty('Hosts.host_name', hostName); + if (host) { + return Em.get(host, 'Hosts.public_host_name'); + } + return null; }, setConfigProperties: function () { @@ -97,276 +178,226 @@ App.QuickViewLinks = Em.View.extend({ return App.router.get('configurationController').getConfigsByTags(tags); }, - ambariProperties: function () { - return App.router.get('clusterController.ambariProperties'); - }, /** - * Updated quick links. Here we put correct hostname to url + * set empty links */ - quickLinks: [], - - didInsertElement: function () { - this.setQuickLinks(); + setEmptyLinks: function () { + var quickLinks = [{ + label: this.t('quick.links.error.label'), + url: 'javascript:alert("' + this.t('contact.administrator') + '");return false;' + }]; + this.set('quickLinks', quickLinks); + this.set('isLoaded', true); }, - willDestroyElement: function() { - this.get('configProperties').clear(); - this.get('actualTags').clear(); - this.get('quickLinks').clear(); - }, - - findComponentHost: function (components, componentName) { - var component = components.find(function (item) { - return item.host_components.someProperty('HostRoles.component_name', componentName); - }); - return component && component.Hosts.public_host_name; - }, - - setQuickLinks: function () { - if (App.get('router.clusterController.isServiceMetricsLoaded')) { - this.loadTags(); - } - }.observes('App.currentStackVersionNumber', 'App.singleNodeInstall', 'App.router.clusterController.isServiceMetricsLoaded'), - - setQuickLinksSuccessCallback: function (response) { - var self = this; - var quickLinks = []; - var hosts = this.setHost(response, this.get('content.serviceName')); - if (!hosts || !this.get('content.quickLinks')) { - quickLinks = [{ - label: this.t('quick.links.error.label'), - url: 'javascript:alert("' + this.t('contact.administrator') + '");return false;' - }]; - this.set('quickLinks', quickLinks); - this.set('isLoaded', true); - } else if (hosts.length == 1) { - - quickLinks = this.get('content.quickLinks').map(function (item) { - var protocol = self.setProtocol(item.get('service_id'), self.get('configProperties'), self.ambariProperties(), item); - var siteConfigs = {}; + /** + * set links that contain only one host + * @param {Array} hosts + */ + setSingleHostLinks: function (hosts) { + var quickLinks = this.get('content.quickLinks').map(function (item) { + var protocol = this.setProtocol(item.get('serviceName'), this.get('configProperties'), this.get('ambariProperties'), item); + var publicHostName = hosts[0].publicHostName; + var port = item.get('http_config') && this.setPort(item, protocol); + var siteConfigs = {}; - if (item.get('template')) { - var port = item.get('http_config') && self.setPort(item, protocol); - if (['FALCON', 'OOZIE', 'ATLAS'].contains(item.get('service_id'))) { - item.set('url', item.get('template').fmt(protocol, hosts[0], port, App.router.get('loginName'))); - } else if (item.get('service_id') === 'MAPREDUCE2') { - siteConfigs = self.get('configProperties').findProperty('type', item.get('site')).properties; - item.set('url', item.get('template').fmt(protocol, siteConfigs[item.get(protocol + '_config')])); - } else if (item.get('service_id') === 'RANGER') { - siteConfigs = self.get('configProperties').findProperty('type', 'admin-properties').properties; - if (siteConfigs['policymgr_external_url']) { - // external_url example: "http://c6404.ambari.apache.org:6080" - var hostAndPort = siteConfigs['policymgr_external_url'] && siteConfigs['policymgr_external_url'].split('://')[1]; - item.set('url', protocol + '://' + hostAndPort); - } else { - item.set('url', item.get('template').fmt(protocol, hosts[0], port)); - } + if (item.get('template')) { + if (item.get('serviceName') === 'MAPREDUCE2') { + siteConfigs = this.get('configProperties').findProperty('type', item.get('site')).properties; + item.set('url', item.get('template').fmt(protocol, siteConfigs[item.get(protocol + '_config')])); + } else if (item.get('serviceName') === 'RANGER') { + siteConfigs = this.get('configProperties').findProperty('type', 'admin-properties').properties; + if (siteConfigs['policymgr_external_url']) { + // external_url example: "http://c6404.ambari.apache.org:6080" + var hostAndPort = siteConfigs['policymgr_external_url'].split('://')[1]; + item.set('url', protocol + '://' + hostAndPort); } else { - item.set('url', item.get('template').fmt(protocol, hosts[0], port)); + item.set('url', item.get('template').fmt(protocol, publicHostName, port)); } + } else { + item.set('url', item.get('template').fmt(protocol, publicHostName, port, App.router.get('loginName'))); } - return item; - }); - this.set('quickLinks', quickLinks); - this.set('isLoaded', true); - } else { - // multiple hbase masters or HDFS HA enabled - var quickLinksArray = []; - hosts.forEach(function(host) { - var quickLinks = []; - self.get('content.quickLinks').forEach(function (item) { - var newItem = {}; - var protocol = self.setProtocol(item.get('service_id'), self.get('configProperties'), self.ambariProperties(), item); - if (item.get('template')) { - var port; - var hostNameRegExp = new RegExp('([\\w\\W]*):\\d+'); - if (item.get('service_id') === 'HDFS') { - var config; - var configPropertiesObject = self.get('configProperties').findProperty('type', item.get('site')); - if (configPropertiesObject && configPropertiesObject.properties) { - var properties = configPropertiesObject.properties; - var nameServiceId = properties['dfs.nameservices']; - var nnProperties = ['dfs.namenode.{0}-address.{1}.nn1', 'dfs.namenode.{0}-address.{1}.nn2'].map(function (c) { - return c.format(protocol, nameServiceId); - }); - var nnPropertiesLength = nnProperties.length; - for (var i = nnPropertiesLength; i--;) { - var propertyName = nnProperties[i]; - var hostNameMatch = properties[propertyName] && properties[propertyName].match(hostNameRegExp); - if (hostNameMatch && hostNameMatch[1] === host.publicHostName) { - config = propertyName; - break; - } + } + return item; + }, this); + this.set('quickLinks', quickLinks); + this.set('isLoaded', true); + }, + + /** + * set links that contain multiple hosts + * @param {Array} hosts + */ + setMultipleHostLinks: function (hosts) { + var quickLinksArray = []; + hosts.forEach(function (host) { + var quickLinks = []; + this.get('content.quickLinks').forEach(function (item) { + var newItem = {}; + var protocol = this.setProtocol(item.get('serviceName'), this.get('configProperties'), this.get('ambariProperties'), item); + if (item.get('template')) { + var port; + var hostNameRegExp = new RegExp('([\\w\\W]*):\\d+'); + if (item.get('serviceName') === 'HDFS') { + var config; + var configPropertiesObject = this.get('configProperties').findProperty('type', item.get('site')); + if (configPropertiesObject && configPropertiesObject.properties) { + var properties = configPropertiesObject.properties; + var nameServiceId = properties['dfs.nameservices']; + var nnProperties = ['dfs.namenode.{0}-address.{1}.nn1', 'dfs.namenode.{0}-address.{1}.nn2'].map(function (c) { + return c.format(protocol, nameServiceId); + }); + var nnPropertiesLength = nnProperties.length; + for (var i = nnPropertiesLength; i--;) { + var propertyName = nnProperties[i]; + var hostNameMatch = properties[propertyName] && properties[propertyName].match(hostNameRegExp); + if (hostNameMatch && hostNameMatch[1] === host.publicHostName) { + config = propertyName; + break; } } - port = self.setPort(item, protocol, config); - } else { - port = item.get('http_config') && self.setPort(item, protocol); - } - if (item.get('service_id')==='OOZIE') { - newItem.url = item.get('template').fmt(protocol, host.publicHostName, port, App.router.get('loginName')); - } else { - newItem.url = item.get('template').fmt(protocol, host.publicHostName, port); } - newItem.label = item.get('label'); + port = this.setPort(item, protocol, config); + } else { + port = item.get('http_config') && this.setPort(item, protocol); } - quickLinks.push(newItem); - }); - if (host.status) { - quickLinks.set('publicHostNameLabel', Em.I18n.t('quick.links.publicHostName').format(host.publicHostName, host.status)); - } else { - quickLinks.set('publicHostNameLabel', host.publicHostName); + if (item.get('serviceName') === 'OOZIE') { + newItem.url = item.get('template').fmt(protocol, host.publicHostName, port, App.router.get('loginName')); + } else { + newItem.url = item.get('template').fmt(protocol, host.publicHostName, port); + } + newItem.label = item.get('label'); } - quickLinksArray.push(quickLinks); + quickLinks.push(newItem); }, this); - this.set('quickLinksArray', quickLinksArray); - this.set('isLoaded', true); - } + if (host.status) { + quickLinks.set('publicHostNameLabel', Em.I18n.t('quick.links.publicHostName').format(host.publicHostName, host.status)); + } else { + quickLinks.set('publicHostNameLabel', host.publicHostName); + } + quickLinksArray.push(quickLinks); + }, this); + this.set('quickLinksArray', quickLinksArray); + this.set('isLoaded', true); + }, + + /** + * set status to hosts with OOZIE_SERVER + * @param {Array} hosts + * @returns {Array} + */ + processOozieHosts: function (hosts) { + var activeOozieServers = this.get('content.hostComponents') + .filterProperty('componentName', 'OOZIE_SERVER') + .filterProperty('workStatus', 'STARTED') + .mapProperty('hostName'); + + return hosts.filter(function (host) { + host.status = Em.I18n.t('quick.links.label.active'); + return activeOozieServers.contains(host.hostName); + }, this); + }, + + /** + * set status to hosts with NAMENODE + * @param {Array} hosts + * @returns {Array} + */ + processHdfsHosts: function (hosts) { + return hosts.map(function (host) { + if (host.hostName === Em.get(this, 'content.activeNameNode.hostName')) { + host.status = Em.I18n.t('quick.links.label.active'); + } else if (host.hostName === Em.get(this, 'content.standbyNameNode.hostName')) { + host.status = Em.I18n.t('quick.links.label.standby'); + } else if (host.hostName === Em.get(this, 'content.standbyNameNode2.hostName')) { + host.status = Em.I18n.t('quick.links.label.standby'); + } + return host; + }, this); + }, + + /** + * set status to hosts with HBASE_MASTER + * @param {Array} hosts + * @param {object} response + * @returns {Array} + */ + processHbaseHosts: function (hosts, response) { + return hosts.map(function (host) { + var isActiveMaster; + response.items.filterProperty('Hosts.host_name', host.hostName).filter(function (item) { + var hbaseMaster = item.host_components.findProperty('HostRoles.component_name', 'HBASE_MASTER'); + isActiveMaster = hbaseMaster && Em.get(hbaseMaster, 'metrics.hbase.master.IsActiveMaster'); + }); + if (isActiveMaster === 'true') { + host.status = Em.I18n.t('quick.links.label.active'); + } else if (isActiveMaster === 'false') { + host.status = Em.I18n.t('quick.links.label.standby'); + } + return host; + }, this); + }, + + /** + * set status to hosts with RESOURCEMANAGER + * @param {Array} hosts + * @returns {Array} + */ + processYarnHosts: function (hosts) { + return hosts.map(function (host) { + var resourceManager = this.get('content.hostComponents') + .filterProperty('componentName', 'RESOURCEMANAGER') + .findProperty('hostName', host.hostName); + var haStatus = resourceManager && resourceManager.get('haStatus'); + if (haStatus === 'ACTIVE') { + host.status = Em.I18n.t('quick.links.label.active'); + } else if (haStatus === 'STANDBY') { + host.status = Em.I18n.t('quick.links.label.standby'); + } + return host; + }, this); }, /** * sets public host names for required masters of current service - * @param {String} serviceName - selected serviceName + * @param {string} serviceName - selected serviceName * @param {JSON} response * @returns {Array} containing hostName(s) - * @method setHost + * @method getHosts */ - setHost: function(response, serviceName) { + getHosts: function (response, serviceName) { if (App.get('singleNodeInstall')) { - return [App.get('singleNodeAlias')]; + return [{ + hostName: App.get('singleNodeAlias'), + publicHostName: App.get('singleNodeAlias') + }]; } var hosts = []; - var host; switch (serviceName) { case 'OOZIE': - // active OOZIE components - var components = this.get('content.hostComponents').filterProperty('componentName','OOZIE_SERVER').filterProperty('workStatus', 'STARTED'); - if (components && components.length > 1) { - components.forEach(function (component) { - hosts.push({ - 'publicHostName': response.items.findProperty('Hosts.host_name', component.get('hostName')).Hosts.public_host_name, - 'status': Em.I18n.t('quick.links.label.active') - }); - }); - } else if (components && components.length === 1) { - host = this.findComponentHost(response.items, 'OOZIE_SERVER'); - if (host) { - hosts[0] = host; - } - } + hosts = this.processOozieHosts(this.findHosts('OOZIE_SERVER', response)); break; case "HDFS": - if (this.get('content.snameNode')) { - // not HA - host = this.findComponentHost(response.items, 'NAMENODE'); - if (host) { - hosts[0] = host; - } - } else { - // HA enabled, need both two namenodes hosts - this.get('content.hostComponents').filterProperty('componentName', 'NAMENODE').forEach(function (component) { - hosts.push({'publicHostName': response.items.findProperty('Hosts.host_name', component.get('hostName')).Hosts.public_host_name}); - }); - // assign each namenode status label - if (this.get('content.activeNameNode')) { - hosts.findProperty('publicHostName', this.getPublicHostName(response.items, this.get('content.activeNameNode.hostName'))).status = Em.I18n.t('quick.links.label.active'); - } - if (this.get('content.standbyNameNode')) { - hosts.findProperty('publicHostName', this.getPublicHostName(response.items, this.get('content.standbyNameNode.hostName'))).status = Em.I18n.t('quick.links.label.standby'); - } - if (this.get('content.standbyNameNode2')) { - hosts.findProperty('publicHostName', this.getPublicHostName(response.items, this.get('content.standbyNameNode2.hostName'))).status = Em.I18n.t('quick.links.label.standby'); - } - } + hosts = this.processHdfsHosts(this.findHosts('NAMENODE', response)); break; case "HBASE": - var masterComponents = response.items.filter(function (item) { - return item.host_components.someProperty('HostRoles.component_name', 'HBASE_MASTER'); - }); - var activeMaster, standbyMasters, otherMasters; - activeMaster = masterComponents.filter(function (item) { - return item.host_components.someProperty('metrics.hbase.master.IsActiveMaster', 'true'); - }); - standbyMasters = masterComponents.filter(function (item) { - return item.host_components.someProperty('metrics.hbase.master.IsActiveMaster', 'false'); - }); - otherMasters = masterComponents.filter(function (item) { - return !(item.host_components.someProperty('metrics.hbase.master.IsActiveMaster', 'true') || item.host_components.someProperty('metrics.hbase.master.IsActiveMaster', 'false')); - }); - if (masterComponents.length > 1) { - // need all hbase_masters hosts in quick links - if (activeMaster) { - activeMaster.forEach(function (item) { - hosts.push({'publicHostName': item.Hosts.public_host_name, 'status': Em.I18n.t('quick.links.label.active')}); - }); - } - if (standbyMasters) { - standbyMasters.forEach(function (item) { - hosts.push({'publicHostName': item.Hosts.public_host_name, 'status': Em.I18n.t('quick.links.label.standby')}); - }); - } - if (otherMasters) { - otherMasters.forEach(function (item) { - hosts.push({'publicHostName': item.Hosts.public_host_name}); - }); - } - } - else { - if (masterComponents[0]) { - host = masterComponents[0].Hosts.public_host_name; - if (host) { - hosts[0] = host; - } - } - } + hosts = this.processHbaseHosts(this.findHosts('HBASE_MASTER', response), response); break; case "YARN": - if (App.get('isRMHaEnabled')) { - this.get('content.hostComponents').filterProperty('componentName', 'RESOURCEMANAGER').forEach(function (component) { - var newHost = {'publicHostName': response.items.findProperty('Hosts.host_name', component.get('hostName')).Hosts.public_host_name}; - var status = ''; - switch (component.get('haStatus')) { - case 'ACTIVE': - status = Em.I18n.t('quick.links.label.active'); - break; - case 'STANDBY': - status = Em.I18n.t('quick.links.label.standby'); - break; - } - if (status) { - newHost.status = status; - } - hosts.push(newHost); - }, this); - } else { - host = this.findComponentHost(response.items, "RESOURCEMANAGER"); - if (host) { - hosts[0] = host; - } - } + hosts = this.processYarnHosts(this.findHosts('RESOURCEMANAGER', response)); break; case "STORM": - host = this.findComponentHost(response.items, "STORM_UI_SERVER"); - if (host) { - hosts[0] = host; - } + hosts = this.findHosts('STORM_UI_SERVER', response); break; case "ACCUMULO": - host = this.findComponentHost(response.items, "ACCUMULO_MONITOR"); - if (host) { - hosts[0] = host; - } + hosts = this.findHosts('ACCUMULO_MONITOR', response); break; case "ATLAS": - host = this.findComponentHost(response.items, "ATLAS_SERVER"); - if (host) { - hosts[0] = host; - } + hosts = this.findHosts('ATLAS_SERVER', response); break; default: - var service = App.StackService.find().findProperty('serviceName', serviceName); - if (service && service.get('hasMaster') && App.Service.find(serviceName).get('hostComponents').someProperty('isMaster')) { - hosts[0] = this.findComponentHost(response.items, this.get('content.hostComponents') && this.get('content.hostComponents').findProperty('isMaster', true).get('componentName')); + if (this.get('content.hostComponents').someProperty('isMaster')) { + hosts = this.findHosts(this.get('content.hostComponents').findProperty('isMaster').get('componentName'), response); } break; } @@ -374,8 +405,30 @@ App.QuickViewLinks = Em.View.extend({ }, /** + * find host public names + * @param {string} componentName + * @param {object} response + * @returns {Array} + */ + findHosts: function (componentName, response) { + var hosts = []; + this.get('content.hostComponents') + .filterProperty('componentName', componentName) + .forEach(function (component) { + var host = this.getPublicHostName(response.items, component.get('hostName')); + if (host) { + hosts.push({ + hostName: component.get('hostName'), + publicHostName: host + }); + } + }, this); + return hosts; + }, + + /** * services that supports security. this array is used to find out protocol. - * becides GANGLIA, YARN, MAPREDUCE2, ACCUMULO. These services use + * besides GANGLIA, YARN, MAPREDUCE2, ACCUMULO. These services use * their properties to know protocol */ servicesSupportsHttps: ["HDFS", "HBASE"], @@ -383,22 +436,20 @@ App.QuickViewLinks = Em.View.extend({ /** * setProtocol - if cluster is secure for some services (GANGLIA, MAPREDUCE2, YARN and servicesSupportsHttps) * protocol becomes "https" otherwise "http" (by default) - * @param {String} service_id - service name + * @param {String} serviceName - service name * @param {Object} configProperties * @param {Object} ambariProperties * @returns {string} "https" or "http" only! * @method setProtocol + * @param item */ - setProtocol: function (service_id, configProperties, ambariProperties, item) { + setProtocol: function (serviceName, configProperties, ambariProperties, item) { var hadoopSslEnabled = false; if (configProperties && configProperties.length > 0) { var hdfsSite = configProperties.findProperty('type', 'hdfs-site'); hadoopSslEnabled = (hdfsSite && Em.get(hdfsSite, 'properties') && hdfsSite.properties['dfs.http.policy'] === 'HTTPS_ONLY'); } - switch (service_id) { - case "GANGLIA": - return (ambariProperties && ambariProperties['ganglia.https'] == "true") ? "https" : "http"; - break; + switch (serviceName) { case "YARN": var yarnProperties = configProperties && configProperties.findProperty('type', 'yarn-site'); if (yarnProperties && yarnProperties.properties) { @@ -480,7 +531,7 @@ App.QuickViewLinks = Em.View.extend({ } break; default: - return this.get('servicesSupportsHttps').contains(service_id) && hadoopSslEnabled ? "https" : "http"; + return this.get('servicesSupportsHttps').contains(serviceName) && hadoopSslEnabled ? "https" : "http"; } }, @@ -489,7 +540,7 @@ App.QuickViewLinks = Em.View.extend({ * @param item * @param protocol * @param config - * @returns {*} + * @returns {string} * @method setPort */ setPort: function (item, protocol, config) { @@ -505,7 +556,7 @@ App.QuickViewLinks = Em.View.extend({ var site = configProperties.findProperty('type', item.get('site')); var propertyValue = site && site.properties && site.properties[configProp]; if (!propertyValue) { - if (item.get('service_id') == 'RANGER') { + if (item.get('serviceName') == 'RANGER') { // HDP 2.3 var adminSite = configProperties.findProperty('type', 'ranger-admin-site'); if (protocol === 'https') { @@ -524,28 +575,5 @@ App.QuickViewLinks = Em.View.extend({ var portValue = propertyValue.match(re); return portValue[1]; - }, - - linkTarget: function () { - switch (this.get('content.serviceName').toLowerCase()) { - case "hdfs": - case "yarn": - case "mapreduce2": - case "hbase": - case "oozie": - case "ganglia": - case "storm": - case "spark": - case "falcon": - case "accumulo": - case "atlas": - case "ranger": - return "_blank"; - break; - default: - return ""; - break; - } - }.property('service') - + } }); http://git-wip-us.apache.org/repos/asf/ambari/blob/e97b3216/ambari-web/app/views/main/admin/highAvailability/progress_view.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/main/admin/highAvailability/progress_view.js b/ambari-web/app/views/main/admin/highAvailability/progress_view.js index dba80dc..9d8b7cb 100644 --- a/ambari-web/app/views/main/admin/highAvailability/progress_view.js +++ b/ambari-web/app/views/main/admin/highAvailability/progress_view.js @@ -21,32 +21,44 @@ var App = require('app'); App.HighAvailabilityProgressPageView = Em.View.extend(App.wizardProgressPageViewMixin, { + /** + * @type {string} + */ + notice: Em.I18n.t('admin.highAvailability.wizard.progressPage.notice.inProgress'), + + /** + * @type {string} + */ + noticeClass: 'alert alert-info', + didInsertElement: function () { this.get('controller').loadStep(); }, + /** + * @type {string} + */ headerTitle: function () { var currentStep = App.router.get('highAvailabilityWizardController.currentStep'); - if (currentStep == 1) { + if (currentStep === 1) { return Em.I18n.t('admin.highAvailability.wizard.rollback.header.title'); } else { return Em.I18n.t('admin.highAvailability.wizard.step' + currentStep + '.header.title'); } }.property(), + /** + * @type {string} + */ noticeInProgress: function () { var currentStep = App.router.get('highAvailabilityWizardController.currentStep'); - if (currentStep == 1) { + if (currentStep === 1) { return Em.I18n.t('admin.highAvailability.rollback.notice.inProgress'); } else { return Em.I18n.t('admin.highAvailability.wizard.step' + currentStep + '.notice.inProgress'); } }.property(), - notice: Em.I18n.t('admin.highAvailability.wizard.progressPage.notice.inProgress'), - - noticeClass: 'alert alert-info', - onStatusChange: function () { var status = this.get('controller.status'); if (status === 'COMPLETED') { @@ -61,6 +73,9 @@ App.HighAvailabilityProgressPageView = Em.View.extend(App.wizardProgressPageView } }.observes('controller.status'), + /** + * @type {Em.View} + */ taskView: Em.View.extend({ icon: '', iconColor: '', @@ -78,8 +93,7 @@ App.HighAvailabilityProgressPageView = Em.View.extend(App.wizardProgressPageView }.property('content.progress'), onStatus: function () { - var linkClass = !!this.get('content.requestIds.length') ? 'active-link' : 'active-text'; - this.set('linkClass', linkClass); + this.set('linkClass', Boolean(this.get('content.requestIds.length')) ? 'active-link' : 'active-text'); if (this.get('content.status') === 'IN_PROGRESS') { this.set('icon', 'icon-cog'); this.set('iconColor', 'text-info'); @@ -96,16 +110,10 @@ App.HighAvailabilityProgressPageView = Em.View.extend(App.wizardProgressPageView } }.observes('content.status', 'content.hosts.length'), - showProgressBar: function () { - return this.get('content.status') === "IN_PROGRESS"; - }.property('content.status'), + showProgressBar: Em.computed.equal('content.status', 'IN_PROGRESS'), - hidePercent: function() { - return this.get('content.command') === 'testDBConnection'; - }.property('content.command'), + hidePercent: Em.computed.equal('content.command', 'testDBConnection'), - showDBTooltip: function() { - return this.get('content.command') !== 'testDBConnection'; - }.property('content.command') + showDBTooltip: Em.computed.not('hidePercent') }) }); http://git-wip-us.apache.org/repos/asf/ambari/blob/e97b3216/ambari-web/test/app_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/app_test.js b/ambari-web/test/app_test.js index 4f202c4..46d9932 100644 --- a/ambari-web/test/app_test.js +++ b/ambari-web/test/app_test.js @@ -26,10 +26,6 @@ describe('App', function () { describe('#stackVersionURL', function () { - App.QuickViewLinks.reopen({ - loadTags: function () { - } - }); App.set('defaultStackVersion', "HDP-1.2.2"); App.set('currentStackVersion', "HDP-1.2.2"); @@ -153,29 +149,21 @@ describe('App', function () { describe('#isHaEnabled when HDFS is installed:', function () { beforeEach(function () { - sinon.stub(App.Service, 'find', function () { - return [ - { - id: 'HDFS', - serviceName: 'HDFS' - } - ]; - }); + sinon.stub(App.Service, 'find').returns(Em.Object.create({'isLoaded': true})); + this.mock = sinon.stub(App.HostComponent, 'find'); }); - afterEach(function () { App.Service.find.restore(); + this.mock.restore(); }); it('if hadoop stack version higher than 2 then isHaEnabled should be true', function () { + this.mock.returns([]); App.propertyDidChange('isHaEnabled'); expect(App.get('isHaEnabled')).to.equal(true); }); it('if cluster has SECONDARY_NAMENODE then isHaEnabled should be false', function () { - App.store.load(App.HostComponent, { - id: 'SECONDARY_NAMENODE', - component_name: 'SECONDARY_NAMENODE' - }); + this.mock.returns([Em.Object.create({componentName: 'SECONDARY_NAMENODE'})]); App.propertyDidChange('isHaEnabled'); expect(App.get('isHaEnabled')).to.equal(false); }); @@ -184,16 +172,8 @@ describe('App', function () { describe('#isHaEnabled when HDFS is not installed:', function () { beforeEach(function () { - sinon.stub(App.Service, 'find', function () { - return [ - { - id: 'ZOOKEEPER', - serviceName: 'ZOOKEEPER' - } - ]; - }); + sinon.stub(App.Service, 'find').returns(Em.Object.create({'isLoaded': false})); }); - afterEach(function () { App.Service.find.restore(); }); http://git-wip-us.apache.org/repos/asf/ambari/blob/e97b3216/ambari-web/test/views/common/chart/linear_time_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/views/common/chart/linear_time_test.js b/ambari-web/test/views/common/chart/linear_time_test.js index 60d02ee..1d4e7f4 100644 --- a/ambari-web/test/views/common/chart/linear_time_test.js +++ b/ambari-web/test/views/common/chart/linear_time_test.js @@ -26,27 +26,31 @@ describe('App.ChartLinearTimeView', function () { describe('#transformData', function () { var result; + var data = [[1, 1200000000], [2, 1200000000], [3, 1200000000]]; + var name = 'abc'; beforeEach(function () { - var data = [[1, 1200000000], [2, 1200000000], [3, 1200000000]]; - var name = 'abc'; sinon.stub(App.router, 'get').withArgs('userSettingsController.userSettings.timezone').returns('(UTC+00:00) Greenwich'); - result = chartLinearTimeView.transformData(data, name); + sinon.stub(App, 'dateTimeWithTimeZone').returns(1); }); afterEach(function () { App.router.get.restore(); + App.dateTimeWithTimeZone.restore(); }); it('"name" should be "abc" ', function () { + result = chartLinearTimeView.transformData(data, name); expect(result.name).to.equal('abc'); }); it('data size should be 3 ', function () { + result = chartLinearTimeView.transformData(data, name); expect(result.data.length).to.equal(3); }); it('data[0].y should be 1 ', function () { + result = chartLinearTimeView.transformData(data, name); expect(result.data[0].y).to.equal(1); }) http://git-wip-us.apache.org/repos/asf/ambari/blob/e97b3216/ambari-web/test/views/common/quick_link_view_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/views/common/quick_link_view_test.js b/ambari-web/test/views/common/quick_link_view_test.js index 5462c0c..fc6b118 100644 --- a/ambari-web/test/views/common/quick_link_view_test.js +++ b/ambari-web/test/views/common/quick_link_view_test.js @@ -21,50 +21,513 @@ require('views/common/quick_view_link_view'); describe('App.QuickViewLinks', function () { - var quickViewLinks = App.QuickViewLinks.create({}); + var quickViewLinks = App.QuickViewLinks.create({ + content: Em.Object.create() + }); + + describe("#linkTarget", function () { + it("blank link", function () { + quickViewLinks.set('content.serviceName', 'HDFS'); + quickViewLinks.propertyDidChange('linkTarget'); + expect(quickViewLinks.get('linkTarget')).to.equal('_blank'); + }); + it("non-blank link", function () { + quickViewLinks.set('content.serviceName', 'S1'); + quickViewLinks.propertyDidChange('linkTarget'); + expect(quickViewLinks.get('linkTarget')).to.be.empty; + }); + }); + + describe("#ambariProperties", function () { + beforeEach(function () { + sinon.stub(App.router, 'get').returns({p: 1}); + }); + afterEach(function () { + App.router.get.restore(); + }); + it("", function () { + expect(quickViewLinks.get('ambariProperties')).to.eql({p: 1}); + }); + }); + + describe("#didInsertElement()", function () { + beforeEach(function () { + sinon.stub(App.router, 'get').returns({p: 1}); + sinon.stub(quickViewLinks, 'setQuickLinks'); + }); + afterEach(function () { + App.router.get.restore(); + quickViewLinks.setQuickLinks.restore(); + }); + it("", function () { + quickViewLinks.didInsertElement(); + expect(quickViewLinks.setQuickLinks.calledOnce).to.be.true; + }); + }); + + describe("#willDestroyElement()", function () { + it("", function () { + quickViewLinks.setProperties({ + configProperties: [{}], + actualTags: [""], + quickLinks: [{}] + }); + quickViewLinks.willDestroyElement(); + expect(quickViewLinks.get('configProperties')).to.be.empty; + expect(quickViewLinks.get('actualTags')).to.be.empty; + expect(quickViewLinks.get('quickLinks')).to.be.empty; + }); + }); + + describe("#setQuickLinks()", function () { + beforeEach(function () { + this.mock = sinon.stub(App, 'get'); + sinon.stub(quickViewLinks, 'loadTags', Em.K); + }); + afterEach(function () { + this.mock.restore(); + quickViewLinks.loadTags.restore(); + }); + it("data loaded", function () { + this.mock.returns(true); + quickViewLinks.setQuickLinks(); + expect(quickViewLinks.loadTags.calledOnce).to.be.true; + }); + it("data not loaded", function () { + this.mock.returns(false); + quickViewLinks.setQuickLinks(); + expect(quickViewLinks.loadTags.called).to.be.false; + }); + }); + + describe("#loadTags()", function () { + beforeEach(function () { + sinon.stub(App.ajax, 'send'); + }); + afterEach(function () { + App.ajax.send.restore(); + }); + it("call $.ajax", function () { + quickViewLinks.loadTags(); + expect(App.ajax.send.calledWith({ + name: 'config.tags', + sender: quickViewLinks, + success: 'loadTagsSuccess', + error: 'loadTagsError' + })).to.be.true; + }); + }); + + describe("#loadTagsSuccess()", function () { + beforeEach(function () { + sinon.stub(quickViewLinks, 'setConfigProperties', function () { + return { + done: function (callback) { + callback(); + } + } + }); + sinon.stub(quickViewLinks, 'getQuickLinksHosts'); + }); + afterEach(function () { + quickViewLinks.setConfigProperties.restore(); + quickViewLinks.getQuickLinksHosts.restore(); + }); + it("", function () { + var data = { + Clusters: { + desired_configs: { + site1: { + tag: 'tag1' + } + } + } + }; + quickViewLinks.loadTagsSuccess(data); + expect(quickViewLinks.get('actualTags')[0]).to.eql(Em.Object.create({ + siteName: 'site1', + tagName: 'tag1' + })); + expect(quickViewLinks.setConfigProperties.calledOnce).to.be.true; + expect(quickViewLinks.getQuickLinksHosts.calledOnce).to.be.true; + }); + }); + + describe("#loadTagsError()", function () { + beforeEach(function () { + sinon.stub(quickViewLinks, 'getQuickLinksHosts'); + }); + afterEach(function () { + quickViewLinks.getQuickLinksHosts.restore(); + }); + it("call getQuickLinksHosts", function () { + quickViewLinks.loadTagsError(); + expect(quickViewLinks.getQuickLinksHosts.calledOnce).to.be.true; + }); + }); + + describe("#getQuickLinksHosts()", function () { + beforeEach(function () { + sinon.stub(App.ajax, 'send'); + sinon.stub(App.HostComponent, 'find').returns([ + Em.Object.create({ + isMaster: true, + hostName: 'host1' + }) + ]); + }); + afterEach(function () { + App.ajax.send.restore(); + App.HostComponent.find.restore(); + }); + it("call $.ajax", function () { + quickViewLinks.getQuickLinksHosts(); + expect(App.ajax.send.calledWith({ + name: 'hosts.for_quick_links', + sender: quickViewLinks, + data: { + clusterName: App.get('clusterName'), + masterHosts: 'host1', + urlParams: '' + }, + success: 'setQuickLinksSuccessCallback' + })).to.be.true; + }); + it("call $.ajax, HBASE service", function () { + quickViewLinks.set('content.serviceName', 'HBASE'); + quickViewLinks.getQuickLinksHosts(); + expect(App.ajax.send.calledWith({ + name: 'hosts.for_quick_links', + sender: quickViewLinks, + data: { + clusterName: App.get('clusterName'), + masterHosts: 'host1', + urlParams: ',host_components/metrics/hbase/master/IsActiveMaster' + }, + success: 'setQuickLinksSuccessCallback' + })).to.be.true; + }); + }); + + describe("#setQuickLinksSuccessCallback()", function () { + beforeEach(function () { + this.mock = sinon.stub(quickViewLinks, 'getHosts'); + sinon.stub(quickViewLinks, 'setEmptyLinks'); + sinon.stub(quickViewLinks, 'setSingleHostLinks'); + sinon.stub(quickViewLinks, 'setMultipleHostLinks'); + quickViewLinks.set('content.quickLinks', []); + }); + afterEach(function () { + this.mock.restore(); + quickViewLinks.setEmptyLinks.restore(); + quickViewLinks.setSingleHostLinks.restore(); + quickViewLinks.setMultipleHostLinks.restore(); + }); + it("no hosts", function () { + this.mock.returns([]); + quickViewLinks.setQuickLinksSuccessCallback(); + expect(quickViewLinks.setEmptyLinks.calledOnce).to.be.true; + }); + it("quickLinks is null", function () { + this.mock.returns([{}]); + quickViewLinks.set('content.quickLinks', null); + quickViewLinks.setQuickLinksSuccessCallback(); + expect(quickViewLinks.setEmptyLinks.calledOnce).to.be.true; + }); + it("single host", function () { + this.mock.returns([{hostName: 'host1'}]); + quickViewLinks.setQuickLinksSuccessCallback(); + expect(quickViewLinks.setSingleHostLinks.calledWith([{hostName: 'host1'}])).to.be.true; + }); + it("multiple hosts", function () { + this.mock.returns([{hostName: 'host1'}, {hostName: 'host2'}]); + quickViewLinks.setQuickLinksSuccessCallback(); + expect(quickViewLinks.setMultipleHostLinks.calledWith( + [{hostName: 'host1'}, {hostName: 'host2'}] + )).to.be.true; + }); + }); + + describe("#getPublicHostName()", function () { + it("host present", function () { + var hosts = [{ + Hosts: { + host_name: 'host1', + public_host_name: 'public_name' + } + }]; + expect(quickViewLinks.getPublicHostName(hosts, 'host1')).to.equal('public_name'); + }); + it("host absent", function () { + expect(quickViewLinks.getPublicHostName([], 'host1')).to.be.null; + }); + }); + + describe("#setConfigProperties()", function () { + var mock = {getConfigsByTags: Em.K}; + beforeEach(function () { + sinon.stub(App.router, 'get').returns(mock); + sinon.spy(mock, 'getConfigsByTags'); + }); + afterEach(function () { + mock.getConfigsByTags.restore(); + App.router.get.restore(); + }); + it("", function () { + quickViewLinks.set('actualTags', [{siteName: 'hdfs-site'}]); + quickViewLinks.setConfigProperties(); + expect(mock.getConfigsByTags.calledWith([{siteName: 'hdfs-site'}])).to.be.true; + }); + }); + + describe("#setEmptyLinks()", function () { + it("", function () { + quickViewLinks.setEmptyLinks(); + expect(quickViewLinks.get('quickLinks')).to.eql([{ + label: quickViewLinks.t('quick.links.error.label'), + url: 'javascript:alert("' + quickViewLinks.t('contact.administrator') + '");return false;' + }]); + expect(quickViewLinks.get('isLoaded')).to.be.true; + }); + }); + + describe("#processOozieHosts()", function () { + it("", function () { + quickViewLinks.set('content.hostComponents', [Em.Object.create({ + componentName: 'OOZIE_SERVER', + workStatus: 'STARTED', + hostName: 'host1' + })]); + var host = {hostName: 'host1'}; + quickViewLinks.processOozieHosts([host]); + expect(host.status).to.equal(Em.I18n.t('quick.links.label.active')); + }); + }); + + describe("#processHdfsHosts()", function () { + beforeEach(function () { + quickViewLinks.set('content.activeNameNode', null); + quickViewLinks.set('content.standbyNameNode', null); + quickViewLinks.set('content.standbyNameNode2', null); + }); + it("active namenode host", function () { + quickViewLinks.set('content.activeNameNode', Em.Object.create({hostName: 'host1'})); + var host = {hostName: 'host1'}; + quickViewLinks.processHdfsHosts([host]); + expect(host.status).to.equal(Em.I18n.t('quick.links.label.active')); + }); + it("standby namenode host", function () { + quickViewLinks.set('content.standbyNameNode', Em.Object.create({hostName: 'host1'})); + var host = {hostName: 'host1'}; + quickViewLinks.processHdfsHosts([host]); + expect(host.status).to.equal(Em.I18n.t('quick.links.label.standby')); + }); + it("second standby namenode host", function () { + quickViewLinks.set('content.standbyNameNode2', Em.Object.create({hostName: 'host1'})); + var host = {hostName: 'host1'}; + quickViewLinks.processHdfsHosts([host]); + expect(host.status).to.equal(Em.I18n.t('quick.links.label.standby')); + }); + }); + + describe("#processHbaseHosts()", function () { + it("isActiveMaster is true", function () { + var response = { + items: [ + { + Hosts: { + host_name: 'host1' + }, + host_components: [ + { + HostRoles: { + component_name: 'HBASE_MASTER' + }, + metrics: { + hbase: { + master: { + IsActiveMaster: 'true' + } + } + } + } + ] + } + ] + }; + var host = {hostName: 'host1'}; + quickViewLinks.processHbaseHosts([host], response); + expect(host.status).to.equal(Em.I18n.t('quick.links.label.active')); + }); + it("isActiveMaster is false", function () { + var response = { + items: [ + { + Hosts: { + host_name: 'host1' + }, + host_components: [ + { + HostRoles: { + component_name: 'HBASE_MASTER' + }, + metrics: { + hbase: { + master: { + IsActiveMaster: 'false' + } + } + } + } + ] + } + ] + }; + var host = {hostName: 'host1'}; + quickViewLinks.processHbaseHosts([host], response); + expect(host.status).to.equal(Em.I18n.t('quick.links.label.standby')); + }); + it("isActiveMaster is undefined", function () { + var response = { + items: [ + { + Hosts: { + host_name: 'host1' + }, + host_components: [ + { + HostRoles: { + component_name: 'HBASE_MASTER' + } + } + ] + } + ] + }; + var host = {hostName: 'host1'}; + quickViewLinks.processHbaseHosts([host], response); + expect(host.status).to.be.undefined; + }); + }); + + describe("#processYarnHosts()", function () { + it("haStatus is ACTIVE", function () { + quickViewLinks.set('content.hostComponents', [Em.Object.create({ + componentName: 'RESOURCEMANAGER', + hostName: 'host1', + haStatus: 'ACTIVE' + })]); + var host = {hostName: 'host1'}; + quickViewLinks.processYarnHosts([host]); + expect(host.status).to.equal(Em.I18n.t('quick.links.label.active')); + }); + it("haStatus is STANDBY", function () { + quickViewLinks.set('content.hostComponents', [Em.Object.create({ + componentName: 'RESOURCEMANAGER', + hostName: 'host1', + haStatus: 'STANDBY' + })]); + var host = {hostName: 'host1'}; + quickViewLinks.processYarnHosts([host]); + expect(host.status).to.equal(Em.I18n.t('quick.links.label.standby')); + }); + it("haStatus is undefined", function () { + quickViewLinks.set('content.hostComponents', [Em.Object.create({ + componentName: 'RESOURCEMANAGER', + hostName: 'host1' + })]); + var host = {hostName: 'host1'}; + quickViewLinks.processYarnHosts([host]); + expect(host.status).to.be.undefined; + }); + }); - describe('#setProtocol', function() { + describe("#findHosts()", function () { + beforeEach(function () { + sinon.stub(quickViewLinks, 'getPublicHostName').returns('public_name'); + }); + afterEach(function () { + quickViewLinks.getPublicHostName.restore(); + }); + it("", function () { + quickViewLinks.set('content.hostComponents', [Em.Object.create({ + componentName: 'C1', + hostName: 'host1' + })]); + expect(quickViewLinks.findHosts('C1', {})).to.eql([{ + hostName: 'host1', + publicHostName: 'public_name' + }]); + }); + }); + + describe('#setProtocol', function () { var tests = [ - { serviceName: "GANGLIA", ambariProperties: { 'ganglia.https': 'true' }, m: "https for ganglia", result: "https" }, - { serviceName: "GANGLIA", ambariProperties: { 'ganglia.https': 'false' }, m: "http for ganglia 1", result: "http" }, - { serviceName: "GANGLIA", m: "http for ganglia 2", result: "http" }, - { serviceName: "YARN", configProperties: [ - { type: 'yarn-site', properties: { 'yarn.http.policy': 'HTTPS_ONLY' }} - ], m: "https for yarn", result: "https" }, - { serviceName: "YARN", configProperties: [ - { type: 'yarn-site', properties: { 'yarn.http.policy': 'HTTP_ONLY' }} - ], m: "http for yarn", result: "http" }, - { serviceName: "YARN", configProperties: [ - { type: 'yarn-site', properties: { 'yarn.http.policy': 'HTTP_ONLY' }} - ], m: "http for yarn (overrides hadoop.ssl.enabled)", result: "http" }, - { serviceName: "YARN", configProperties: [ - { type: 'yarn-site', properties: { 'yarn.http.policy': 'HTTPS_ONLY' }} - ], m: "https for yarn (overrides hadoop.ssl.enabled)", result: "https" }, - { serviceName: "MAPREDUCE2", configProperties: [ - { type: 'mapred-site', properties: { 'mapreduce.jobhistory.http.policy': 'HTTPS_ONLY' }} - ], m: "https for mapreduce2", result: "https" }, - { serviceName: "MAPREDUCE2", configProperties: [ - { type: 'mapred-site', properties: { 'mapreduce.jobhistory.http.policy': 'HTTP_ONLY' }} - ], m: "http for mapreduce2", result: "http" }, - { serviceName: "ANYSERVICE", configProperties: [ - { type: 'hdfs-site', properties: { 'dfs.http.policy': 'HTTPS_ONLY' }} - ], m: "https for anyservice", servicesSupportsHttps: ["ANYSERVICE"], result: "https" }, - { serviceName: "RANGER", configProperties: [ - { type: 'ranger-site', properties: { 'http.enabled': 'true' }} - ], m: "http for ranger (HDP2.2)", result: "http" }, - { serviceName: "RANGER", configProperties: [ - { type: 'ranger-site', properties: { 'http.enabled': 'false' }} - ], m: "https for ranger (HDP2.2)", result: "https" }, - { serviceName: "RANGER", configProperties: [ - { type: 'ranger-admin-site', properties: { 'ranger.service.http.enabled': 'true', 'ranger.service.https.attrib.ssl.enabled': 'false'}} - ], m: "http for ranger (HDP2.3)", result: "http" }, - { serviceName: "RANGER", configProperties: [ - { type: 'ranger-admin-site', properties: { 'ranger.service.http.enabled': 'false', 'ranger.service.https.attrib.ssl.enabled': 'true'}} - ], m: "https for ranger (HDP2.3)", result: "https" } + { + serviceName: "YARN", configProperties: [ + {type: 'yarn-site', properties: {'yarn.http.policy': 'HTTPS_ONLY'}} + ], m: "https for yarn", result: "https" + }, + { + serviceName: "YARN", configProperties: [ + {type: 'yarn-site', properties: {'yarn.http.policy': 'HTTP_ONLY'}} + ], m: "http for yarn", result: "http" + }, + { + serviceName: "YARN", configProperties: [ + {type: 'yarn-site', properties: {'yarn.http.policy': 'HTTP_ONLY'}} + ], m: "http for yarn (overrides hadoop.ssl.enabled)", result: "http" + }, + { + serviceName: "YARN", configProperties: [ + {type: 'yarn-site', properties: {'yarn.http.policy': 'HTTPS_ONLY'}} + ], m: "https for yarn (overrides hadoop.ssl.enabled)", result: "https" + }, + { + serviceName: "MAPREDUCE2", configProperties: [ + {type: 'mapred-site', properties: {'mapreduce.jobhistory.http.policy': 'HTTPS_ONLY'}} + ], m: "https for mapreduce2", result: "https" + }, + { + serviceName: "MAPREDUCE2", configProperties: [ + {type: 'mapred-site', properties: {'mapreduce.jobhistory.http.policy': 'HTTP_ONLY'}} + ], m: "http for mapreduce2", result: "http" + }, + { + serviceName: "ANYSERVICE", configProperties: [ + {type: 'hdfs-site', properties: {'dfs.http.policy': 'HTTPS_ONLY'}} + ], m: "https for anyservice", servicesSupportsHttps: ["ANYSERVICE"], result: "https" + }, + { + serviceName: "RANGER", configProperties: [ + {type: 'ranger-site', properties: {'http.enabled': 'true'}} + ], m: "http for ranger (HDP2.2)", result: "http" + }, + { + serviceName: "RANGER", configProperties: [ + {type: 'ranger-site', properties: {'http.enabled': 'false'}} + ], m: "https for ranger (HDP2.2)", result: "https" + }, + { + serviceName: "RANGER", configProperties: [ + { + type: 'ranger-admin-site', + properties: {'ranger.service.http.enabled': 'true', 'ranger.service.https.attrib.ssl.enabled': 'false'} + } + ], m: "http for ranger (HDP2.3)", result: "http" + }, + { + serviceName: "RANGER", configProperties: [ + { + type: 'ranger-admin-site', + properties: {'ranger.service.http.enabled': 'false', 'ranger.service.https.attrib.ssl.enabled': 'true'} + } + ], m: "https for ranger (HDP2.3)", result: "https" + } ]; - tests.forEach(function(t) { - it(t.m, function() { + tests.forEach(function (t) { + it(t.m, function () { quickViewLinks.set('servicesSupportsHttps', t.servicesSupportsHttps); expect(quickViewLinks.setProtocol(t.serviceName, t.configProperties, t.ambariProperties)).to.equal(t.result); }); @@ -161,384 +624,12 @@ describe('App.QuickViewLinks', function () { quickViewLinks.set('configProperties', []); }); - testData.forEach(function(item) { + testData.forEach(function (item) { it(item.service_id + ' ' + item.protocol, function () { quickViewLinks.set('configProperties', item.configProperties || []); expect(quickViewLinks.setPort(item, item.protocol, item.config)).to.equal(item.result); }) - },this); - }); - - describe('#setHost', function () { - - var quickViewLinks = App.QuickViewLinks.create({ - content: Em.Object.create() - }), - cases = [ - { - singleNodeInstall: true, - hosts: ['host0'], - title: 'single node install' - }, - { - response: { - items: [ - { - host_components: [ - { - HostRoles: { - component_name: 'STORM_UI_SERVER' - } - } - ], - Hosts: { - public_host_name: 'host3' - } - } - ] - }, - serviceName: 'STORM', - hosts: ['host3'] - }, - { - serviceName: 'PIG', - hosts: [], - title: 'client only service' - }, - { - response: { - items: [ - { - host_components: [ - { - HostRoles: { - component_name: 'ZOOKEEPER_SERVER' - } - } - ], - Hosts: { - public_host_name: 'host4' - } - } - ] - }, - serviceName: 'ZOOKEEPER', - hosts: ['host4'], - setup: function () { - quickViewLinks.set('content', { - hostComponents: [ - Em.Object.create({ - componentName: 'ZOOKEEPER_SERVER', - isMaster: true - }) - ] - }); - }, - title: 'service with master component, except HDFS, HBase, YARN and Storm' - }, - { - response: { - items: [ - { - host_components: [ - { - HostRoles: { - component_name: 'NAMENODE' - } - } - ], - Hosts: { - public_host_name: 'host5' - } - } - ] - }, - serviceName: 'HDFS', - hosts: ['host5'], - setup: function () { - quickViewLinks.set('content', { - snameNode: true - }); - }, - title: 'HDFS, HA disabled' - }, - { - response: { - items: [ - { - host_components: [ - { - HostRoles: { - component_name: 'NAMENODE' - } - } - ], - Hosts: { - host_name: 'host6', - public_host_name: 'host6' - } - }, - { - host_components: [ - { - HostRoles: { - component_name: 'NAMENODE' - } - } - ], - Hosts: { - host_name: 'host7', - public_host_name: 'host7' - } - }, - { - host_components: [ - { - HostRoles: { - component_name: 'NAMENODE' - } - } - ], - Hosts: { - host_name: 'host8', - public_host_name: 'host8' - } - } - ] - }, - serviceName: 'HDFS', - multipleMasters: true, - hosts: ['host6', 'host7', 'host8'], - setup: function () { - quickViewLinks.set('content', { - hostComponents: [ - Em.Object.create({ - componentName: 'NAMENODE', - hostName: 'host6' - }), - Em.Object.create({ - componentName: 'NAMENODE', - hostName: 'host7' - }), - Em.Object.create({ - componentName: 'NAMENODE', - hostName: 'host8' - }) - ], - activeNameNode: { - hostName: 'host6' - }, - standbyNameNode: { - hostName: 'host7' - }, - standbyNameNode2: { - hostName: 'host8' - } - }); - }, - title: 'HDFS, HA enabled' - }, - { - response: { - items: [ - { - host_components: [ - { - HostRoles: { - component_name: 'RESOURCEMANAGER' - } - } - ], - Hosts: { - public_host_name: 'host9' - } - } - ] - }, - serviceName: 'YARN', - hosts: ['host9'], - title: 'YARN, HA disabled' - }, - { - response: { - items: [ - { - host_components: [ - { - HostRoles: { - component_name: 'RESOURCEMANAGER' - } - } - ], - Hosts: { - host_name: 'host10', - public_host_name: 'host10' - } - }, - { - host_components: [ - { - HostRoles: { - component_name: 'RESOURCEMANAGER' - } - } - ], - Hosts: { - host_name: 'host11', - public_host_name: 'host11' - } - }, - { - host_components: [ - { - HostRoles: { - component_name: 'RESOURCEMANAGER' - } - } - ], - Hosts: { - host_name: 'host12', - public_host_name: 'host12' - } - } - ] - }, - serviceName: 'YARN', - multipleMasters: true, - hosts: ['host10', 'host11', 'host12'], - setup: function () { - quickViewLinks.set('content', { - hostComponents: [ - Em.Object.create({ - componentName: 'RESOURCEMANAGER', - hostName: 'host10' - }), - Em.Object.create({ - componentName: 'RESOURCEMANAGER', - hostName: 'host11' - }), - Em.Object.create({ - componentName: 'RESOURCEMANAGER', - hostName: 'host12' - }) - ] - }); - }, - title: 'YARN, HA enabled' - }, - { - response: { - items: [ - { - host_components: [ - { - HostRoles: { - component_name: 'HBASE_MASTER' - }, - metrics: { - hbase: { - master: { - IsActiveMaster: true - } - } - } - } - ], - Hosts: { - host_name: 'host13', - public_host_name: 'host13' - } - }, - { - host_components: [ - { - HostRoles: { - component_name: 'HBASE_MASTER' - }, - metrics: { - hbase: { - master: { - IsActiveMaster: false - } - } - } - } - ], - Hosts: { - host_name: 'host14', - public_host_name: 'host14' - } - }, - { - host_components: [ - { - HostRoles: { - component_name: 'HBASE_MASTER' - } - } - ], - Hosts: { - host_name: 'host15', - public_host_name: 'host15' - } - } - ] - }, - serviceName: 'HBASE', - multipleMasters: true, - hosts: ['host13', 'host14', 'host15'] - } - ]; - - before(function () { - sinon.stub(App.StackService, 'find', function () { - return [ - Em.Object.create({ - serviceName: 'ZOOKEEPER', - hasMaster: true - }), - Em.Object.create({ - serviceName: 'PIG', - hasMaster: false - }) - ]; - }); - sinon.stub(App.Service, 'find', function () { - return Em.Object.create({ - hostComponents: Em.A([ - Em.Object.create({ - isMaster: true - }) - ]) - }); - }); - }); - - after(function () { - App.StackService.find.restore(); - App.Service.find.restore(); - }); - - afterEach(function () { - App.get.restore(); - }); - - cases.forEach(function (item) { - it(item.title || item.serviceName, function () { - if (item.setup) { - item.setup(); - } - sinon.stub(App, 'get').withArgs('singleNodeInstall').returns(item.singleNodeInstall). - withArgs('singleNodeAlias').returns('host0'). - withArgs('isRMHaEnabled').returns(item.multipleMasters); - if (item.multipleMasters) { - expect(quickViewLinks.setHost(item.response, item.serviceName).mapProperty('publicHostName')).to.eql(item.hosts); - } else { - expect(quickViewLinks.setHost(item.response, item.serviceName)).to.eql(item.hosts); - } - }); - }); - + }, this); }); }); http://git-wip-us.apache.org/repos/asf/ambari/blob/e97b3216/ambari-web/test/views/main/admin/highAvailability/progress_view_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/views/main/admin/highAvailability/progress_view_test.js b/ambari-web/test/views/main/admin/highAvailability/progress_view_test.js new file mode 100644 index 0000000..2da16d9 --- /dev/null +++ b/ambari-web/test/views/main/admin/highAvailability/progress_view_test.js @@ -0,0 +1,171 @@ +/** + * 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/highAvailability/progress_view'); + +describe('App.HighAvailabilityProgressPageView', function () { + + var view = App.HighAvailabilityProgressPageView.create({ + controller: Em.Object.create({ + loadStep: Em.K + }) + }); + + + describe("#didInsertElement()", function () { + beforeEach(function () { + sinon.spy(view.get('controller'), 'loadStep'); + }); + afterEach(function () { + view.get('controller').loadStep.restore(); + }); + it("", function () { + view.didInsertElement(); + expect(view.get('controller').loadStep.calledOnce).to.be.true; + }); + }); + + describe("#headerTitle", function () { + beforeEach(function () { + this.mock = sinon.stub(App.router, 'get'); + }); + afterEach(function () { + this.mock.restore(); + }); + it("currentStep is 1", function () { + this.mock.returns(1); + view.propertyDidChange('headerTitle'); + expect(view.get('headerTitle')).to.equal(Em.I18n.t('admin.highAvailability.wizard.rollback.header.title')); + }); + it("currentStep is 2", function () { + this.mock.returns(2); + view.propertyDidChange('headerTitle'); + expect(view.get('headerTitle')).to.equal(Em.I18n.t('admin.highAvailability.wizard.step2.header.title')); + }); + }); + + describe("#noticeInProgress", function () { + beforeEach(function () { + this.mock = sinon.stub(App.router, 'get'); + }); + afterEach(function () { + this.mock.restore(); + }); + it("currentStep is 1", function () { + this.mock.returns(1); + view.propertyDidChange('noticeInProgress'); + expect(view.get('noticeInProgress')).to.equal(Em.I18n.t('admin.highAvailability.rollback.notice.inProgress')); + }); + it("currentStep is 2", function () { + this.mock.returns(2); + view.propertyDidChange('noticeInProgress'); + expect(view.get('noticeInProgress')).to.equal(Em.I18n.t('admin.highAvailability.wizard.step2.notice.inProgress')); + }); + }); + + describe("#onStatusChange()", function() { + it("COMPLETED status", function() { + view.reopen({ + noticeCompleted: 'noticeCompleted' + }); + view.set('controller.status', 'COMPLETED'); + expect(view.get('notice')).to.equal('noticeCompleted'); + expect(view.get('noticeClass')).to.equal('alert alert-success'); + }); + it("FAILED status", function() { + view.reopen({ + noticeFailed: 'noticeFailed' + }); + view.set('controller.status', 'FAILED'); + expect(view.get('notice')).to.equal('noticeFailed'); + expect(view.get('noticeClass')).to.equal('alert alert-error'); + }); + it("IN_PROGRESS status", function() { + view.reopen({ + noticeInProgress: 'noticeInProgress' + }); + view.set('controller.status', 'IN_PROGRESS'); + expect(view.get('notice')).to.equal('noticeInProgress'); + expect(view.get('noticeClass')).to.equal('alert alert-info'); + }); + }); + + describe("#taskView", function() { + var taskView = view.get('taskView').create({ + content: Em.Object.create() + }); + + describe("#didInsertElement()", function () { + beforeEach(function () { + sinon.spy(taskView, 'onStatus'); + }); + afterEach(function () { + taskView.onStatus.restore(); + }); + it("", function () { + taskView.didInsertElement(); + expect(taskView.onStatus.calledOnce).to.be.true; + }); + }); + + describe("#barWidth", function () { + it("currentStep is 1", function () { + taskView.set('content.progress', 1); + taskView.propertyDidChange('barWidth'); + expect(taskView.get('barWidth')).to.equal('width: 1%;'); + }); + }); + + describe("#onStatus", function() { + it("IN_PROGRESS status", function() { + taskView.set('content.status', 'IN_PROGRESS'); + taskView.set('content.requestIds', []); + taskView.onStatus(); + expect(taskView.get('linkClass')).to.equal('active-text'); + expect(taskView.get('icon')).to.equal('icon-cog'); + expect(taskView.get('iconColor')).to.equal('text-info'); + }); + it("FAILED status", function() { + taskView.set('content.status', 'FAILED'); + taskView.set('content.requestIds', [{}]); + taskView.onStatus(); + expect(taskView.get('linkClass')).to.equal('active-link'); + expect(taskView.get('icon')).to.equal('icon-exclamation-sign'); + expect(taskView.get('iconColor')).to.equal('text-error'); + }); + it("COMPLETED status", function() { + taskView.set('content.status', 'COMPLETED'); + taskView.set('content.requestIds', []); + taskView.onStatus(); + expect(taskView.get('linkClass')).to.equal('active-text'); + expect(taskView.get('icon')).to.equal('icon-ok'); + expect(taskView.get('iconColor')).to.equal('text-success'); + }); + it("else status", function() { + taskView.set('content.status', ''); + taskView.set('content.requestIds', []); + taskView.onStatus(); + expect(taskView.get('linkClass')).to.equal('not-active-link'); + expect(taskView.get('icon')).to.equal('icon-cog'); + expect(taskView.get('iconColor')).to.be.empty; + }); + }); + }); +});
