You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by ab...@apache.org on 2015/04/29 14:10:21 UTC
[2/4] ambari git commit: AMBARI-10826 Move App.ServiceConfigProperty
object to separate file. (ababiichuk)
http://git-wip-us.apache.org/repos/asf/ambari/blob/11a09c57/ambari-web/app/utils/configs/config_property_helper.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/configs/config_property_helper.js b/ambari-web/app/utils/configs/config_property_helper.js
new file mode 100644
index 0000000..76b294f
--- /dev/null
+++ b/ambari-web/app/utils/configs/config_property_helper.js
@@ -0,0 +1,554 @@
+/**
+ * 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');
+
+module.exports = {
+
+ initialValue: function (configProperty, localDB, dependencies) {
+ var masterComponentHostsInDB = localDB.masterComponentHosts;
+ var slaveComponentHostsInDB = localDB.slaveComponentHosts;
+ var isOnlyFirstOneNeeded = true;
+ var hostWithPort = "([\\w|\\.]*)(?=:)";
+ var hostWithPrefix = ":\/\/" + hostWithPort;
+ switch (configProperty.get('name')) {
+ case 'namenode_host':
+ configProperty.set('value', masterComponentHostsInDB.filterProperty('component', 'NAMENODE').mapProperty('hostName'));
+ break;
+ case 'dfs.namenode.rpc-address':
+ case 'dfs.http.address':
+ case 'dfs.namenode.http-address':
+ case 'dfs.https.address':
+ case 'dfs.namenode.https-address':
+ var nnHost = masterComponentHostsInDB.findProperty('component', 'NAMENODE').hostName;
+ this.setDefaultValue(configProperty, hostWithPort,nnHost);
+ break;
+ case 'fs.default.name':
+ case 'fs.defaultFS':
+ case 'hbase.rootdir':
+ case 'instance.volumes':
+ var nnHost = masterComponentHostsInDB.filterProperty('component', 'NAMENODE').mapProperty('hostName');
+ this.setDefaultValue(configProperty, hostWithPrefix,'://' + nnHost);
+ break;
+ case 'snamenode_host':
+ // Secondary NameNode does not exist when NameNode HA is enabled
+ var snn = masterComponentHostsInDB.findProperty('component', 'SECONDARY_NAMENODE');
+ if (snn) {
+ configProperty.set('value', snn.hostName);
+ }
+ break;
+ case 'dfs.secondary.http.address':
+ case 'dfs.namenode.secondary.http-address':
+ var snnHost = masterComponentHostsInDB.findProperty('component', 'SECONDARY_NAMENODE');
+ if (snnHost) {
+ this.setDefaultValue(configProperty, hostWithPort,snnHost.hostName);
+ }
+ break;
+ case 'datanode_hosts':
+ configProperty.set('value', slaveComponentHostsInDB.findProperty('componentName', 'DATANODE').hosts.mapProperty('hostName'));
+ break;
+ case 'nfsgateway_hosts':
+ var gwyHost = slaveComponentHostsInDB.findProperty('componentName', 'NFS_GATEWAY');
+ if(gwyHost) {
+ configProperty.set('value', gwyHost.hosts.mapProperty('hostName'));
+ }
+ break;
+ case 'hs_host':
+ configProperty.set('value', masterComponentHostsInDB.filterProperty('component', 'HISTORYSERVER').mapProperty('hostName'));
+ break;
+ case 'yarn.log.server.url':
+ var hsHost = masterComponentHostsInDB.filterProperty('component', 'HISTORYSERVER').mapProperty('hostName');
+ this.setDefaultValue(configProperty, hostWithPrefix,'://' + hsHost);
+ break;
+ case 'mapreduce.jobhistory.webapp.address':
+ case 'mapreduce.jobhistory.address':
+ var hsHost = masterComponentHostsInDB.filterProperty('component', 'HISTORYSERVER').mapProperty('hostName');
+ this.setDefaultValue(configProperty, hostWithPort,hsHost);
+ break;
+ case 'rm_host':
+ configProperty.set('value', masterComponentHostsInDB.findProperty('component', 'RESOURCEMANAGER').hostName);
+ break;
+ case 'ats_host':
+ var atsHost = masterComponentHostsInDB.findProperty('component', 'APP_TIMELINE_SERVER');
+ if (atsHost)
+ configProperty.set('value', atsHost.hostName);
+ else
+ configProperty.set('value', 'false');
+ break;
+ case 'yarn.resourcemanager.hostname':
+ var rmHost = masterComponentHostsInDB.findProperty('component', 'RESOURCEMANAGER').hostName;
+ configProperty.set('defaultValue',rmHost);
+ configProperty.set('value',configProperty.get('defaultValue'));
+ break;
+ case 'yarn.resourcemanager.resource-tracker.address':
+ case 'yarn.resourcemanager.webapp.https.address':
+ case 'yarn.resourcemanager.webapp.address':
+ case 'yarn.resourcemanager.scheduler.address':
+ case 'yarn.resourcemanager.address':
+ case 'yarn.resourcemanager.admin.address':
+ var rmHost = masterComponentHostsInDB.findProperty('component', 'RESOURCEMANAGER').hostName;
+ this.setDefaultValue(configProperty, hostWithPort,rmHost);
+ break;
+ case 'yarn.timeline-service.webapp.address':
+ case 'yarn.timeline-service.webapp.https.address':
+ case 'yarn.timeline-service.address':
+ var atsHost = masterComponentHostsInDB.findProperty('component', 'APP_TIMELINE_SERVER');
+ if (atsHost && atsHost.hostName) {
+ this.setDefaultValue(configProperty, hostWithPort,atsHost.hostName);
+ }
+ break;
+ case 'nm_hosts':
+ configProperty.set('value', slaveComponentHostsInDB.findProperty('componentName', 'NODEMANAGER').hosts.mapProperty('hostName'));
+ break;
+ case 'jobtracker_host':
+ configProperty.set('value', masterComponentHostsInDB.findProperty('component', 'JOBTRACKER').hostName);
+ break;
+ case 'mapred.job.tracker':
+ case 'mapred.job.tracker.http.address':
+ var jtHost = masterComponentHostsInDB.findProperty('component', 'JOBTRACKER').hostName;
+ this.setDefaultValue(configProperty, hostWithPort,jtHost);
+ break;
+ case 'mapreduce.history.server.http.address':
+ var jtHost = masterComponentHostsInDB.findProperty('component', 'HISTORYSERVER').hostName;
+ this.setDefaultValue(configProperty, hostWithPort,jtHost);
+ break;
+ case 'tasktracker_hosts':
+ configProperty.set('value', slaveComponentHostsInDB.findProperty('componentName', 'TASKTRACKER').hosts.mapProperty('hostName'));
+ break;
+ case 'hbasemaster_host':
+ configProperty.set('value', masterComponentHostsInDB.filterProperty('component', 'HBASE_MASTER').mapProperty('hostName'));
+ break;
+ case 'regionserver_hosts':
+ configProperty.set('value', slaveComponentHostsInDB.findProperty('componentName', 'HBASE_REGIONSERVER').hosts.mapProperty('hostName'));
+ break;
+ case 'hivemetastore_host':
+ configProperty.set('value', masterComponentHostsInDB.filterProperty('component', 'HIVE_METASTORE').mapProperty('hostName'));
+ break;
+ case 'hive_ambari_host':
+ configProperty.set('value', masterComponentHostsInDB.findProperty('component', 'HIVE_SERVER').hostName);
+ break;
+ case 'hive_master_hosts':
+ var hostNames = masterComponentHostsInDB.filter(function (masterComponent) {
+ return ['HIVE_METASTORE', 'HIVE_SERVER'].contains(masterComponent.component);
+ });
+ configProperty.set('value', hostNames.mapProperty('hostName').uniq().join(','));
+ break;
+ case 'hive_database':
+ var newMySQLDBOption = configProperty.get('options').findProperty('displayName', 'New MySQL Database');
+ if (newMySQLDBOption) {
+ var isNewMySQLDBOptionHidden = !App.get('supports.alwaysEnableManagedMySQLForHive') && App.get('router.currentState.name') != 'configs' &&
+ !App.get('isManagedMySQLForHiveEnabled');
+ if (isNewMySQLDBOptionHidden && configProperty.get('value') == 'New MySQL Database') {
+ configProperty.set('value', 'Existing MySQL Database');
+ }
+ Em.set(newMySQLDBOption, 'hidden', isNewMySQLDBOptionHidden);
+ }
+ break;
+ case 'oozieserver_host':
+ configProperty.set('value', masterComponentHostsInDB.filterProperty('component', 'OOZIE_SERVER').mapProperty('hostName'));
+ break;
+ case 'oozie.base.url':
+ var oozieHost = masterComponentHostsInDB.findProperty('component', 'OOZIE_SERVER').hostName;
+ this.setDefaultValue(configProperty, hostWithPrefix,'://' + oozieHost);
+ break;
+ case 'webhcatserver_host':
+ configProperty.set('value', masterComponentHostsInDB.findProperty('component', 'WEBHCAT_SERVER').hostName);
+ break;
+ case 'oozie_ambari_host':
+ configProperty.set('value', masterComponentHostsInDB.findProperty('component', 'OOZIE_SERVER').hostName);
+ break;
+ case 'hadoop_host':
+ configProperty.set('value', masterComponentHostsInDB.filterProperty('component', 'NAMENODE').mapProperty('hostName'));
+ break;
+ case 'hive_existing_mysql_host':
+ case 'hive_existing_postgresql_host':
+ case 'hive_existing_oracle_host':
+ case 'hive_existing_mssql_server_host':
+ case 'hive_existing_mssql_server_2_host':
+ var hiveServerHost = masterComponentHostsInDB.findProperty('component', 'HIVE_SERVER').hostName;
+ configProperty.set('value', hiveServerHost).set('defaultValue', hiveServerHost);
+ break;
+ case 'hive.metastore.uris':
+ var hiveMSUris = this.getHiveMetastoreUris(masterComponentHostsInDB, dependencies['hive.metastore.uris']);
+ if (hiveMSUris) {
+ this.setDefaultValue(configProperty, "(.*)", hiveMSUris);
+ }
+ break;
+ case 'oozie_existing_mysql_host':
+ case 'oozie_existing_postgresql_host':
+ case 'oozie_existing_oracle_host':
+ case 'oozie_existing_mssql_server_host':
+ case 'oozie_existing_mssql_server_2_host':
+ var oozieServerHost = masterComponentHostsInDB.findProperty('component', 'OOZIE_SERVER').hostName;
+ configProperty.set('value', oozieServerHost).set('defaultValue', oozieServerHost);
+ break;
+ case 'storm.zookeeper.servers':
+ case 'zookeeperserver_hosts':
+ configProperty.set('value', masterComponentHostsInDB.filterProperty('component', 'ZOOKEEPER_SERVER').mapProperty('hostName'));
+ break;
+ case 'nimbus.host':
+ configProperty.set('value', masterComponentHostsInDB.findProperty('component', 'NIMBUS').hostName);
+ break;
+ case 'falconserver_host':
+ configProperty.set('value', masterComponentHostsInDB.findProperty('component', 'FALCON_SERVER').hostName);
+ break;
+ case 'drpcserver_host':
+ var drpcHost = masterComponentHostsInDB.findProperty('component', 'DRPC_SERVER');
+ if (drpcHost) {
+ configProperty.set('value', drpcHost.hostName);
+ }
+ break;
+ case 'stormuiserver_host':
+ configProperty.set('value', masterComponentHostsInDB.findProperty('component', 'STORM_UI_SERVER').hostName);
+ break;
+ case 'storm_rest_api_host':
+ var stormRresApiHost = masterComponentHostsInDB.findProperty('component', 'STORM_REST_API');
+ if(stormRresApiHost) {
+ configProperty.set('value', stormRresApiHost.hostName);
+ }
+ break;
+ case 'supervisor_hosts':
+ configProperty.set('value', slaveComponentHostsInDB.findProperty('componentName', 'SUPERVISOR').hosts.mapProperty('hostName'));
+ break;
+ case 'knox_gateway_host':
+ configProperty.set('value', masterComponentHostsInDB.filterProperty('component', 'KNOX_GATEWAY').mapProperty('hostName'));
+ break;
+ case 'kafka_broker_hosts':
+ configProperty.set('value', masterComponentHostsInDB.filterProperty('component', 'KAFKA_BROKER').mapProperty('hostName'));
+ break;
+ case 'kafka.ganglia.metrics.host':
+ var gangliaHost = masterComponentHostsInDB.findProperty('component', 'GANGLIA_SERVER');
+ if (gangliaHost) {
+ configProperty.set('value', gangliaHost.hostName);
+ }
+ break;
+ case 'hbase.zookeeper.quorum':
+ if (configProperty.get('filename') == 'hbase-site.xml') {
+ var zkHosts = masterComponentHostsInDB.filterProperty('component', 'ZOOKEEPER_SERVER').mapProperty('hostName');
+ this.setDefaultValue(configProperty, "(\\w*)", zkHosts);
+ }
+ break;
+ case 'yarn.resourcemanager.zk-address':
+ var value = masterComponentHostsInDB.findProperty('component', 'ZOOKEEPER_SERVER').hostName + ':' + dependencies.clientPort;
+ configProperty.setProperties({
+ value: value,
+ defaultValue: value
+ });
+ break;
+ case 'zookeeper.connect':
+ case 'hive.zookeeper.quorum':
+ case 'templeton.zookeeper.hosts':
+ case 'hadoop.registry.zk.quorum':
+ case 'hive.cluster.delegation.token.store.zookeeper.connectString':
+ case 'instance.zookeeper.host': // for accumulo
+ var zkHosts = masterComponentHostsInDB.filterProperty('component', 'ZOOKEEPER_SERVER').mapProperty('hostName');
+ var zkHostPort = zkHosts;
+ var regex = "\\w*:(\\d+)"; //regex to fetch the port
+ var portValue = configProperty.get('defaultValue').match(new RegExp(regex));
+ if (!portValue) return;
+ if (portValue[1]) {
+ for ( var i = 0; i < zkHosts.length; i++ ) {
+ zkHostPort[i] = zkHosts[i] + ":" + portValue[1];
+ }
+ }
+ this.setDefaultValue(configProperty, "(.*)", zkHostPort);
+ break;
+ case 'templeton.hive.properties':
+ var hiveMSUris = this.getHiveMetastoreUris(masterComponentHostsInDB, dependencies['hive.metastore.uris']).replace(',', '\\,');
+ if (/\/\/localhost:/g.test(configProperty.get('value'))) {
+ configProperty.set('defaultValue', configProperty.get('value') + ',hive.metastore.execute.setugi=true');
+ }
+ this.setDefaultValue(configProperty, "(hive\\.metastore\\.uris=)([^\\,]+)", "$1" + hiveMSUris);
+ break;
+ case 'dfs.name.dir':
+ case 'dfs.namenode.name.dir':
+ case 'dfs.data.dir':
+ case 'dfs.datanode.data.dir':
+ case 'yarn.nodemanager.local-dirs':
+ case 'yarn.nodemanager.log-dirs':
+ case 'mapred.local.dir':
+ case 'log.dirs': // for Kafka Broker
+ this.unionAllMountPoints(configProperty, !isOnlyFirstOneNeeded, localDB);
+ break;
+ case 'hbase.tmp.dir':
+ if (configProperty.get('filename') == 'hbase-site.xml') {
+ this.unionAllMountPoints(configProperty, isOnlyFirstOneNeeded, localDB);
+ }
+ break;
+ case 'fs.checkpoint.dir':
+ case 'dfs.namenode.checkpoint.dir':
+ case 'yarn.timeline-service.leveldb-timeline-store.path':
+ case 'dataDir':
+ case 'oozie_data_dir':
+ case 'storm.local.dir':
+ case '*.falcon.graph.storage.directory':
+ case '*.falcon.graph.serialize.path':
+ this.unionAllMountPoints(configProperty, isOnlyFirstOneNeeded, localDB);
+ break;
+ case '*.broker.url':
+ var falconServerHost = masterComponentHostsInDB.findProperty('component', 'FALCON_SERVER').hostName;
+ this.setDefaultValue(configProperty, 'localhost', falconServerHost);
+ break;
+ case 'RANGER_HOST':
+ var rangerAdminHost = masterComponentHostsInDB.findProperty('component', 'RANGER_ADMIN');
+ if(rangerAdminHost) {
+ configProperty.set('value', rangerAdminHost.hostName);
+ } else {
+ configProperty.set('isVisible', 'false');
+ configProperty.set('isRequired', 'false');
+ }
+ break;
+ }
+ },
+
+ /**
+ * Get hive.metastore.uris initial value
+ * @param hosts
+ * @param defaultValue
+ * @returns {string}
+ */
+ getHiveMetastoreUris: function (hosts, defaultValue) {
+ var hiveMSHosts = hosts.filterProperty('component', 'HIVE_METASTORE').mapProperty('hostName'),
+ hiveMSUris = hiveMSHosts,
+ regex = "\\w*:(\\d+)",
+ portValue = defaultValue && defaultValue.match(new RegExp(regex));
+
+ if (!portValue) return '';
+ if (portValue[1]) {
+ for (var i = 0; i < hiveMSHosts.length; i++) {
+ hiveMSUris[i] = "thrift://" + hiveMSHosts[i] + ":" + portValue[1];
+ }
+ }
+ return hiveMSUris.join(',');
+ },
+
+ /**
+ * @param regex : String
+ * @param replaceWith : String
+ * @param configProperty
+ */
+ setDefaultValue: function(configProperty, regex, replaceWith) {
+ var defaultValue = configProperty.get('defaultValue');
+ var re = new RegExp(regex);
+ defaultValue = defaultValue.replace(re,replaceWith);
+ configProperty.set('defaultValue',defaultValue);
+ configProperty.set('value',configProperty.get('defaultValue'));
+ },
+
+ unionAllMountPoints: function (configProperty, isOnlyFirstOneNeeded, localDB) {
+ var hostname = '';
+ var mountPointsPerHost = [];
+ var mountPointAsRoot;
+ var masterComponentHostsInDB = localDB.masterComponentHosts;
+ var slaveComponentHostsInDB = localDB.slaveComponentHosts;
+ var hostsInfo = localDB.hosts; // which we are setting in installerController in step3.
+ //all hosts should be in local storage without using App.Host model
+ App.Host.find().forEach(function(item){
+ if(!hostsInfo[item.get('id')]){
+ hostsInfo[item.get('id')] = {
+ name: item.get('id'),
+ cpu: item.get('cpu'),
+ memory: item.get('memory'),
+ disk_info: item.get('diskInfo'),
+ bootStatus: "REGISTERED",
+ isInstalled: true
+ };
+ }
+ });
+ var temp = '';
+ var setOfHostNames = [];
+ var components = [];
+ switch (configProperty.get('name')) {
+ case 'dfs.namenode.name.dir':
+ case 'dfs.name.dir':
+ components = masterComponentHostsInDB.filterProperty('component', 'NAMENODE');
+ components.forEach(function (component) {
+ setOfHostNames.push(component.hostName);
+ }, this);
+ break;
+ case 'fs.checkpoint.dir':
+ case 'dfs.namenode.checkpoint.dir':
+ components = masterComponentHostsInDB.filterProperty('component', 'SECONDARY_NAMENODE');
+ components.forEach(function (component) {
+ setOfHostNames.push(component.hostName);
+ }, this);
+ break;
+ case 'dfs.data.dir':
+ case 'dfs.datanode.data.dir':
+ temp = slaveComponentHostsInDB.findProperty('componentName', 'DATANODE');
+ temp.hosts.forEach(function (host) {
+ setOfHostNames.push(host.hostName);
+ }, this);
+ break;
+ case 'mapred.local.dir':
+ temp = slaveComponentHostsInDB.findProperty('componentName', 'TASKTRACKER') || slaveComponentHostsInDB.findProperty('componentName', 'NODEMANAGER');
+ temp.hosts.forEach(function (host) {
+ setOfHostNames.push(host.hostName);
+ }, this);
+ break;
+ case 'yarn.nodemanager.log-dirs':
+ case 'yarn.nodemanager.local-dirs':
+ temp = slaveComponentHostsInDB.findProperty('componentName', 'NODEMANAGER');
+ temp.hosts.forEach(function (host) {
+ setOfHostNames.push(host.hostName);
+ }, this);
+ break;
+ case 'yarn.timeline-service.leveldb-timeline-store.path':
+ components = masterComponentHostsInDB.filterProperty('component', 'APP_TIMELINE_SERVER');
+ components.forEach(function (component) {
+ setOfHostNames.push(component.hostName);
+ }, this);
+ break;
+ case 'dataDir':
+ components = masterComponentHostsInDB.filterProperty('component', 'ZOOKEEPER_SERVER');
+ components.forEach(function (component) {
+ setOfHostNames.push(component.hostName);
+ }, this);
+ break;
+ case 'oozie_data_dir':
+ components = masterComponentHostsInDB.filterProperty('component', 'OOZIE_SERVER');
+ components.forEach(function (component) {
+ setOfHostNames.push(component.hostName);
+ }, this);
+ break;
+ case 'hbase.tmp.dir':
+ temp = slaveComponentHostsInDB.findProperty('componentName', 'HBASE_REGIONSERVER');
+ temp.hosts.forEach(function (host) {
+ setOfHostNames.push(host.hostName);
+ }, this);
+ break;
+ case 'storm.local.dir':
+ temp = slaveComponentHostsInDB.findProperty('componentName', 'SUPERVISOR');
+ temp.hosts.forEach(function (host) {
+ setOfHostNames.push(host.hostName);
+ }, this);
+ components = masterComponentHostsInDB.filterProperty('component', 'NIMBUS');
+ components.forEach(function (component) {
+ setOfHostNames.push(component.hostName);
+ }, this);
+ break;
+ case '*.falcon.graph.storage.directory':
+ case '*.falcon.graph.serialize.path':
+ components = masterComponentHostsInDB.filterProperty('component', 'FALCON_SERVER');
+ components.forEach(function (component) {
+ setOfHostNames.push(component.hostName);
+ }, this);
+ break;
+ case 'log.dirs':
+ components = masterComponentHostsInDB.filterProperty('component', 'KAFKA_BROKER');
+ components.forEach(function (component) {
+ setOfHostNames.push(component.hostName);
+ }, this);
+ break;
+ }
+
+ // In Add Host Wizard, if we did not select this slave component for any host, then we don't process any further.
+ if (setOfHostNames.length === 0) {
+ return;
+ }
+
+ var allMountPoints = [];
+ for (var i = 0; i < setOfHostNames.length; i++) {
+ hostname = setOfHostNames[i];
+
+ mountPointsPerHost = hostsInfo[hostname].disk_info;
+
+ mountPointAsRoot = mountPointsPerHost.findProperty('mountpoint', '/');
+
+ // If Server does not send any host details information then atleast one mountpoint should be presumed as root
+ // This happens in a single container Linux Docker environment.
+ if (!mountPointAsRoot) {
+ mountPointAsRoot = {mountpoint: '/'};
+ }
+
+ mountPointsPerHost = mountPointsPerHost.filter(function (mPoint) {
+ return !(['/', '/home'].contains(mPoint.mountpoint)
+ || ['/etc/resolv.conf', '/etc/hostname', '/etc/hosts'].contains(mPoint.mountpoint) // docker specific mount points
+ || mPoint.mountpoint && (mPoint.mountpoint.startsWith('/boot') || mPoint.mountpoint.startsWith('/mnt'))
+ || ['devtmpfs', 'tmpfs', 'vboxsf', 'CDFS'].contains(mPoint.type)
+ || mPoint.available == 0);
+ });
+
+ mountPointsPerHost.forEach(function (mPoint) {
+ if( !allMountPoints.findProperty("mountpoint", mPoint.mountpoint)) {
+ allMountPoints.push(mPoint);
+ }
+ }, this);
+ }
+ if (allMountPoints.length == 0) {
+ allMountPoints.push(mountPointAsRoot);
+ }
+ configProperty.set('value', '');
+ var winRegex = /^([a-z]):\\?$/;
+ if (!isOnlyFirstOneNeeded) {
+ allMountPoints.forEach(function (eachDrive) {
+ var mPoint = configProperty.get('value');
+ if (!mPoint) {
+ mPoint = "";
+ }
+ if (eachDrive.mountpoint === "/") {
+ mPoint += configProperty.get('defaultDirectory') + "\n";
+ } else if(winRegex.test(eachDrive.mountpoint.toLowerCase())) {
+ switch (configProperty.get('name')) {
+ case 'dfs.name.dir':
+ case 'dfs.namenode.name.dir':
+ case 'dfs.data.dir':
+ case 'dfs.datanode.data.dir':
+ var winDriveUrl = eachDrive.mountpoint.toLowerCase().replace(winRegex, "file:///$1:");
+ mPoint += winDriveUrl + configProperty.get('defaultDirectory') + "\n";
+ break;
+ default:
+ var winDrive = eachDrive.mountpoint.toLowerCase().replace(winRegex, "$1:");
+ var winDir = configProperty.get('defaultDirectory').replace(/\//g, "\\");
+ mPoint += winDrive + winDir + "\n";
+ }
+ } else {
+ mPoint += eachDrive.mountpoint + configProperty.get('defaultDirectory') + "\n";
+ }
+ configProperty.set('value', mPoint);
+ configProperty.set('defaultValue', mPoint);
+ }, this);
+ } else {
+ var mPoint = allMountPoints[0].mountpoint;
+ if (mPoint === "/") {
+ mPoint = configProperty.get('defaultDirectory');
+ } else if(winRegex.test(mPoint.toLowerCase())) {
+ switch (configProperty.get('name')) {
+ case 'fs.checkpoint.dir':
+ case 'dfs.namenode.checkpoint.dir':
+ var winDriveUrl = mPoint.toLowerCase().replace(winRegex, "file:///$1:");
+ mPoint = winDriveUrl + configProperty.get('defaultDirectory') + "\n";
+ break;
+ case 'zk_data_dir':
+ var winDrive = mPoint.toLowerCase().replace(winRegex, "$1:");
+ var winDir = configProperty.get('defaultDirectory').replace(/\//g, "\\\\");
+ mPoint = winDrive + winDir + "\n";
+ break;
+ default:
+ var winDrive = mPoint.toLowerCase().replace(winRegex, "$1:");
+ var winDir = configProperty.get('defaultDirectory').replace(/\//g, "\\");
+ mPoint = winDrive + winDir + "\n";
+ }
+ } else {
+ mPoint = mPoint + configProperty.get('defaultDirectory');
+ }
+ configProperty.set('value', mPoint);
+ configProperty.set('defaultValue', mPoint);
+ }
+ }
+};
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/11a09c57/ambari-web/test/models/configs/objects/service_config_category_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/models/configs/objects/service_config_category_test.js b/ambari-web/test/models/configs/objects/service_config_category_test.js
new file mode 100644
index 0000000..449c874
--- /dev/null
+++ b/ambari-web/test/models/configs/objects/service_config_category_test.js
@@ -0,0 +1,184 @@
+
+/**
+ * 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 configPropertyHelper = require('utils/configs/config_property_helper');
+
+require('models/configs/objects/service_config_category');
+require('models/configs/objects/service_config_property');
+
+var serviceConfigCategory,
+ nameCases = [
+ {
+ name: 'DataNode',
+ primary: 'DATANODE'
+ },
+ {
+ name: 'TaskTracker',
+ primary: 'TASKTRACKER'
+ },
+ {
+ name: 'RegionServer',
+ primary: 'HBASE_REGIONSERVER'
+ },
+ {
+ name: 'name',
+ primary: null
+ }
+ ],
+ components = [
+ {
+ name: 'NameNode',
+ master: true
+ },
+ {
+ name: 'SNameNode',
+ master: true
+ },
+ {
+ name: 'JobTracker',
+ master: true
+ },
+ {
+ name: 'HBase Master',
+ master: true
+ },
+ {
+ name: 'Oozie Master',
+ master: true
+ },
+ {
+ name: 'Hive Metastore',
+ master: true
+ },
+ {
+ name: 'WebHCat Server',
+ master: true
+ },
+ {
+ name: 'ZooKeeper Server',
+ master: true
+ },
+ {
+ name: 'Ganglia',
+ master: true
+ },
+ {
+ name: 'DataNode',
+ slave: true
+ },
+ {
+ name: 'TaskTracker',
+ slave: true
+ },
+ {
+ name: 'RegionServer',
+ slave: true
+ }
+ ],
+ masters = components.filterProperty('master'),
+ slaves = components.filterProperty('slave'),
+ groupsData = {
+ groups: [
+ Em.Object.create({
+ errorCount: 1
+ }),
+ Em.Object.create({
+ errorCount: 2
+ })
+ ]
+ };
+
+describe('App.ServiceConfigCategory', function () {
+
+ beforeEach(function () {
+ serviceConfigCategory = App.ServiceConfigCategory.create();
+ });
+
+ describe('#primaryName', function () {
+ nameCases.forEach(function (item) {
+ it('should return ' + item.primary, function () {
+ serviceConfigCategory.set('name', item.name);
+ expect(serviceConfigCategory.get('primaryName')).to.equal(item.primary);
+ })
+ });
+ });
+
+ describe('#isForMasterComponent', function () {
+ masters.forEach(function (item) {
+ it('should be true for ' + item.name, function () {
+ serviceConfigCategory.set('name', item.name);
+ expect(serviceConfigCategory.get('isForMasterComponent')).to.be.true;
+ });
+ });
+ it('should be false', function () {
+ serviceConfigCategory.set('name', 'name');
+ expect(serviceConfigCategory.get('isForMasterComponent')).to.be.false;
+ });
+ });
+
+ describe('#isForSlaveComponent', function () {
+ slaves.forEach(function (item) {
+ it('should be true for ' + item.name, function () {
+ serviceConfigCategory.set('name', item.name);
+ expect(serviceConfigCategory.get('isForSlaveComponent')).to.be.true;
+ });
+ });
+ it('should be false', function () {
+ serviceConfigCategory.set('name', 'name');
+ expect(serviceConfigCategory.get('isForSlaveComponent')).to.be.false;
+ });
+ });
+
+ describe('#slaveErrorCount', function () {
+ it('should be 0', function () {
+ serviceConfigCategory.set('slaveConfigs', []);
+ expect(serviceConfigCategory.get('slaveErrorCount')).to.equal(0);
+ });
+ it('should sum all errorCount values', function () {
+ serviceConfigCategory.set('slaveConfigs', groupsData);
+ expect(serviceConfigCategory.get('slaveErrorCount')).to.equal(3);
+ });
+ });
+
+ describe('#errorCount', function () {
+ it('should sum all errors for category', function () {
+ serviceConfigCategory.reopen({
+ slaveErrorCount: 1
+ });
+ expect(serviceConfigCategory.get('errorCount')).to.equal(1);
+ serviceConfigCategory.set('nonSlaveErrorCount', 2);
+ expect(serviceConfigCategory.get('errorCount')).to.equal(3);
+ serviceConfigCategory.set('slaveErrorCount', 0);
+ expect(serviceConfigCategory.get('errorCount')).to.equal(2);
+ });
+ });
+
+ describe('#isAdvanced', function () {
+ it('should be true', function () {
+ serviceConfigCategory.set('name', 'Advanced');
+ expect(serviceConfigCategory.get('isAdvanced')).to.be.true;
+ });
+ it('should be false', function () {
+ serviceConfigCategory.set('name', 'name');
+ expect(serviceConfigCategory.get('isAdvanced')).to.be.false;
+ });
+ });
+
+});
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/11a09c57/ambari-web/test/models/configs/objects/service_config_property_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/models/configs/objects/service_config_property_test.js b/ambari-web/test/models/configs/objects/service_config_property_test.js
new file mode 100644
index 0000000..9235d6e
--- /dev/null
+++ b/ambari-web/test/models/configs/objects/service_config_property_test.js
@@ -0,0 +1,474 @@
+/**
+ * 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 configPropertyHelper = require('utils/configs/config_property_helper');
+
+require('models/configs/objects/service_config_category');
+require('models/configs/objects/service_config_property');
+
+var serviceConfigProperty,
+ serviceConfigPropertyInit,
+ configsData = [
+ Ember.Object.create({
+ category: 'c0',
+ overrides: [
+ {
+ error: true,
+ errorMessage: 'error'
+ },
+ {
+ error: true
+ },
+ {}
+ ]
+ }),
+ Ember.Object.create({
+ category: 'c1',
+ isValid: false,
+ isVisible: true
+ }),
+ Ember.Object.create({
+ category: 'c0',
+ isValid: true,
+ isVisible: true
+ }),
+ Ember.Object.create({
+ category: 'c1',
+ isValid: false,
+ isVisible: false
+ })
+ ],
+
+ components = [
+ {
+ name: 'NameNode',
+ master: true
+ },
+ {
+ name: 'SNameNode',
+ master: true
+ },
+ {
+ name: 'JobTracker',
+ master: true
+ },
+ {
+ name: 'HBase Master',
+ master: true
+ },
+ {
+ name: 'Oozie Master',
+ master: true
+ },
+ {
+ name: 'Hive Metastore',
+ master: true
+ },
+ {
+ name: 'WebHCat Server',
+ master: true
+ },
+ {
+ name: 'ZooKeeper Server',
+ master: true
+ },
+ {
+ name: 'Ganglia',
+ master: true
+ },
+ {
+ name: 'DataNode',
+ slave: true
+ },
+ {
+ name: 'TaskTracker',
+ slave: true
+ },
+ {
+ name: 'RegionServer',
+ slave: true
+ }
+ ],
+ overridableFalseData = [
+ {
+ isOverridable: false
+ },
+ {
+ isEditable: false,
+ overrides: configsData[0].overrides
+ },
+ {
+ displayType: 'masterHost'
+ }
+ ],
+ overridableTrueData = [
+ {
+ isOverridable: true,
+ isEditable: true
+ }, {
+ isOverridable: true,
+ overrides: []
+ },
+ {
+ isOverridable: true
+ }
+ ],
+ overriddenFalseData = [
+ {
+ overrides: null,
+ isOriginalSCP: true
+ },
+ {
+ overrides: [],
+ isOriginalSCP: true
+ }
+ ],
+ overriddenTrueData = [
+ {
+ overrides: configsData[0].overrides
+ },
+ {
+ isOriginalSCP: false
+ }
+ ],
+ removableFalseData = [
+ {
+ isEditable: false
+ },
+ {
+ hasOverrides: true
+ },
+ {
+ isUserProperty: false,
+ isOriginalSCP: true
+ }
+ ],
+ removableTrueData = [
+ {
+ isEditable: true,
+ hasOverrides: false,
+ isUserProperty: true
+ },
+ {
+ isEditable: true,
+ hasOverrides: false,
+ isOriginalSCP: false
+ }
+ ],
+ initPropertyData = [
+ {
+ initial: {
+ displayType: 'password',
+ value: 'value'
+ },
+ result: {
+ retypedPassword: 'value'
+ }
+ },
+ {
+ initial: {
+ id: 'puppet var',
+ value: '',
+ defaultValue: 'default'
+ },
+ result: {
+ value: 'default'
+ }
+ }
+ ],
+ notDefaultFalseData = [
+ {
+ isEditable: false
+ },
+ {
+ defaultValue: null
+ },
+ {
+ value: 'value',
+ defaultValue: 'value'
+ }
+ ],
+ notDefaultTrueData = {
+ isEditable: true,
+ value: 'value',
+ defaultValue: 'default'
+ },
+ types = ['masterHost', 'slaveHosts', 'masterHosts', 'slaveHost', 'radio button'],
+ classCases = [
+ {
+ initial: {
+ displayType: 'checkbox'
+ },
+ viewClass: App.ServiceConfigCheckbox
+ },
+ {
+ initial: {
+ displayType: 'checkbox',
+ dependentConfigPattern: 'somPattern'
+ },
+ viewClass: App.ServiceConfigCheckboxWithDependencies
+ },
+ {
+ initial: {
+ displayType: 'password'
+ },
+ viewClass: App.ServiceConfigPasswordField
+ },
+ {
+ initial: {
+ displayType: 'combobox'
+ },
+ viewClass: App.ServiceConfigComboBox
+ },
+ {
+ initial: {
+ displayType: 'radio button'
+ },
+ viewClass: App.ServiceConfigRadioButtons
+ },
+ {
+ initial: {
+ displayType: 'directories'
+ },
+ viewClass: App.ServiceConfigTextArea
+ },
+ {
+ initial: {
+ displayType: 'content'
+ },
+ viewClass: App.ServiceConfigTextAreaContent
+
+ },
+ {
+ initial: {
+ displayType: 'multiLine'
+ },
+ viewClass: App.ServiceConfigTextArea
+ },
+ {
+ initial: {
+ displayType: 'custom'
+ },
+ viewClass: App.ServiceConfigBigTextArea
+ },
+ {
+ initial: {
+ displayType: 'masterHost'
+ },
+ viewClass: App.ServiceConfigMasterHostView
+ },
+ {
+ initial: {
+ displayType: 'masterHosts'
+ },
+ viewClass: App.ServiceConfigMasterHostsView
+ },
+ {
+ initial: {
+ displayType: 'slaveHosts'
+ },
+ viewClass: App.ServiceConfigSlaveHostsView
+ },
+ {
+ initial: {
+ unit: true,
+ displayType: 'type'
+ },
+ viewClass: App.ServiceConfigTextFieldWithUnit
+ },
+ {
+ initial: {
+ unit: false,
+ displayType: 'type'
+ },
+ viewClass: App.ServiceConfigTextField
+ },
+ {
+ initial: {
+ unit: false,
+ displayType: 'supportTextConnection'
+ },
+ viewClass: App.checkConnectionView
+ }
+ ];
+
+describe('App.ServiceConfigProperty', function () {
+
+ beforeEach(function () {
+ serviceConfigProperty = App.ServiceConfigProperty.create();
+ });
+
+ describe('#overrideErrorTrigger', function () {
+ it('should be an increment', function () {
+ serviceConfigProperty.set('overrides', configsData[0].overrides);
+ expect(serviceConfigProperty.get('overrideErrorTrigger')).to.equal(1);
+ serviceConfigProperty.set('overrides', []);
+ expect(serviceConfigProperty.get('overrideErrorTrigger')).to.equal(2);
+ });
+ });
+
+ describe('#isPropertyOverridable', function () {
+ overridableFalseData.forEach(function (item) {
+ it('should be false', function () {
+ Em.keys(item).forEach(function (prop) {
+ serviceConfigProperty.set(prop, item[prop]);
+ });
+ expect(serviceConfigProperty.get('isPropertyOverridable')).to.be.false;
+ });
+ });
+ overridableTrueData.forEach(function (item) {
+ it('should be true', function () {
+ Em.keys(item).forEach(function (prop) {
+ serviceConfigProperty.set(prop, item[prop]);
+ });
+ expect(serviceConfigProperty.get('isPropertyOverridable')).to.be.true;
+ });
+ });
+ });
+
+ describe('#isOverridden', function () {
+ overriddenFalseData.forEach(function (item) {
+ it('should be false', function () {
+ Em.keys(item).forEach(function (prop) {
+ serviceConfigProperty.set(prop, item[prop]);
+ });
+ expect(serviceConfigProperty.get('isOverridden')).to.be.false;
+ });
+ });
+ overriddenTrueData.forEach(function (item) {
+ it('should be true', function () {
+ Em.keys(item).forEach(function (prop) {
+ serviceConfigProperty.set(prop, item[prop]);
+ });
+ expect(serviceConfigProperty.get('isOverridden')).to.be.true;
+ });
+ });
+ });
+
+ describe('#isRemovable', function () {
+ removableFalseData.forEach(function (item) {
+ it('should be false', function () {
+ Em.keys(item).forEach(function (prop) {
+ serviceConfigProperty.set(prop, item[prop]);
+ });
+ expect(serviceConfigProperty.get('isRemovable')).to.be.false;
+ });
+ });
+ removableTrueData.forEach(function (item) {
+ it('should be true', function () {
+ Em.keys(item).forEach(function (prop) {
+ serviceConfigProperty.set(prop, item[prop]);
+ });
+ expect(serviceConfigProperty.get('isRemovable')).to.be.true;
+ });
+ });
+ });
+
+ describe('#init', function () {
+ initPropertyData.forEach(function (item) {
+ it('should set initial data', function () {
+ serviceConfigPropertyInit = App.ServiceConfigProperty.create(item.initial);
+ Em.keys(item.result).forEach(function (prop) {
+ expect(serviceConfigPropertyInit.get(prop)).to.equal(item.result[prop]);
+ });
+ });
+ });
+ });
+
+ describe('#isNotDefaultValue', function () {
+ notDefaultFalseData.forEach(function (item) {
+ it('should be false', function () {
+ Em.keys(item).forEach(function (prop) {
+ serviceConfigProperty.set(prop, item[prop]);
+ });
+ expect(serviceConfigProperty.get('isNotDefaultValue')).to.be.false;
+ });
+ });
+ it('should be true', function () {
+ Em.keys(notDefaultTrueData).forEach(function (prop) {
+ serviceConfigProperty.set(prop, notDefaultTrueData[prop]);
+ });
+ expect(serviceConfigProperty.get('isNotDefaultValue')).to.be.true;
+ });
+ });
+
+ describe('#cantBeUndone', function () {
+ types.forEach(function (item) {
+ it('should be true', function () {
+ serviceConfigProperty.set('displayType', item);
+ expect(serviceConfigProperty.get('cantBeUndone')).to.be.true;
+ });
+ });
+ it('should be false', function () {
+ serviceConfigProperty.set('displayType', 'type');
+ expect(serviceConfigProperty.get('cantBeUndone')).to.be.false;
+ });
+ });
+
+ describe('#isValid', function () {
+ it('should be true', function () {
+ serviceConfigProperty.set('errorMessage', '');
+ expect(serviceConfigProperty.get('isValid')).to.be.true;
+ });
+ it('should be false', function () {
+ serviceConfigProperty.set('errorMessage', 'message');
+ expect(serviceConfigProperty.get('isValid')).to.be.false;
+ });
+ });
+
+ describe('#viewClass', function () {
+ classCases.forEach(function (item) {
+ it ('should be ' + item.viewClass, function () {
+ Em.keys(item.initial).forEach(function (prop) {
+ serviceConfigProperty.set(prop, item.initial[prop]);
+ });
+ expect(serviceConfigProperty.get('viewClass')).to.eql(item.viewClass);
+ });
+ });
+ });
+
+ describe('#validate', function () {
+ it('not required', function () {
+ serviceConfigProperty.setProperties({
+ isRequired: false,
+ value: ''
+ });
+ expect(serviceConfigProperty.get('errorMessage')).to.be.empty;
+ expect(serviceConfigProperty.get('error')).to.be.false;
+ });
+ it('should validate', function () {
+ serviceConfigProperty.setProperties({
+ isRequired: true,
+ value: 'value'
+ });
+ expect(serviceConfigProperty.get('errorMessage')).to.be.empty;
+ expect(serviceConfigProperty.get('error')).to.be.false;
+ });
+ it('should fail', function () {
+ serviceConfigProperty.setProperties({
+ isRequired: true,
+ value: 'value'
+ });
+ serviceConfigProperty.set('value', '');
+ expect(serviceConfigProperty.get('errorMessage')).to.equal('This is required');
+ expect(serviceConfigProperty.get('error')).to.be.true;
+ });
+ });
+
+});
http://git-wip-us.apache.org/repos/asf/ambari/blob/11a09c57/ambari-web/test/models/configs/objects/service_config_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/models/configs/objects/service_config_test.js b/ambari-web/test/models/configs/objects/service_config_test.js
new file mode 100644
index 0000000..cfa015c
--- /dev/null
+++ b/ambari-web/test/models/configs/objects/service_config_test.js
@@ -0,0 +1,165 @@
+/**
+ * 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 configPropertyHelper = require('utils/configs/config_property_helper');
+
+require('models/configs/objects/service_config');
+
+var serviceConfig,
+ group,
+ configsData = [
+ Ember.Object.create({
+ category: 'c0',
+ overrides: [
+ {
+ error: true,
+ errorMessage: 'error'
+ },
+ {
+ error: true
+ },
+ {}
+ ]
+ }),
+ Ember.Object.create({
+ category: 'c1',
+ isValid: false,
+ isVisible: true
+ }),
+ Ember.Object.create({
+ category: 'c0',
+ isValid: true,
+ isVisible: true
+ }),
+ Ember.Object.create({
+ category: 'c1',
+ isValid: false,
+ isVisible: false
+ })
+ ],
+ configCategoriesData = [
+ Em.Object.create({
+ name: 'c0',
+ slaveErrorCount: 1
+ }),
+ Em.Object.create({
+ name: 'c1',
+ slaveErrorCount: 2
+ })
+ ],
+ components = [
+ {
+ name: 'NameNode',
+ master: true
+ },
+ {
+ name: 'SNameNode',
+ master: true
+ },
+ {
+ name: 'JobTracker',
+ master: true
+ },
+ {
+ name: 'HBase Master',
+ master: true
+ },
+ {
+ name: 'Oozie Master',
+ master: true
+ },
+ {
+ name: 'Hive Metastore',
+ master: true
+ },
+ {
+ name: 'WebHCat Server',
+ master: true
+ },
+ {
+ name: 'ZooKeeper Server',
+ master: true
+ },
+ {
+ name: 'Ganglia',
+ master: true
+ },
+ {
+ name: 'DataNode',
+ slave: true
+ },
+ {
+ name: 'TaskTracker',
+ slave: true
+ },
+ {
+ name: 'RegionServer',
+ slave: true
+ }
+ ],
+ masters = components.filterProperty('master'),
+ slaves = components.filterProperty('slave'),
+ groupNoErrorsData = [].concat(configsData.slice(2)),
+ groupErrorsData = [configsData[1]];
+
+describe('App.ServiceConfig', function () {
+
+ beforeEach(function () {
+ serviceConfig = App.ServiceConfig.create();
+ });
+
+ describe('#errorCount', function () {
+ it('should be 0', function () {
+ serviceConfig.setProperties({
+ configs: [],
+ configCategories: []
+ });
+ expect(serviceConfig.get('errorCount')).to.equal(0);
+ });
+ it('should sum counts of all errors', function () {
+ serviceConfig.setProperties({
+ configs: configsData,
+ configCategories: configCategoriesData
+ });
+ expect(serviceConfig.get('errorCount')).to.equal(6);
+ expect(serviceConfig.get('configCategories').findProperty('name', 'c0').get('nonSlaveErrorCount')).to.equal(2);
+ expect(serviceConfig.get('configCategories').findProperty('name', 'c1').get('nonSlaveErrorCount')).to.equal(1);
+ });
+ });
+
+});
+
+describe('App.Group', function () {
+
+ beforeEach(function () {
+ group = App.Group.create();
+ });
+
+ describe('#errorCount', function () {
+ it('should be 0', function () {
+ group.set('properties', groupNoErrorsData);
+ expect(group.get('errorCount')).to.equal(0);
+ });
+ it('should be 1', function () {
+ group.set('properties', groupErrorsData);
+ expect(group.get('errorCount')).to.equal(1);
+ });
+ });
+
+});