Repository: ambari Updated Branches: refs/heads/trunk 7ffa43ef5 -> 0d676b323
AMBARI-13211. Host checks does not report all errors in the very first check after Ambari Agent gets installed/registered. Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/0d676b32 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/0d676b32 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/0d676b32 Branch: refs/heads/trunk Commit: 0d676b3234a5f31c5b11d6b52e6648e44b39e09d Parents: 7ffa43e Author: Alex Antonenko <hiv...@gmail.com> Authored: Tue Oct 6 20:17:20 2015 +0300 Committer: Alex Antonenko <hiv...@gmail.com> Committed: Tue Oct 6 20:17:29 2015 +0300 ---------------------------------------------------------------------- .../custom_actions/scripts/check_host.py | 2 +- .../app/controllers/wizard/step3_controller.js | 303 +++++++++++- .../test/controllers/wizard/step3_test.js | 488 +++++++++++++++++++ 3 files changed, 790 insertions(+), 3 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/0d676b32/ambari-server/src/main/resources/custom_actions/scripts/check_host.py ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/custom_actions/scripts/check_host.py b/ambari-server/src/main/resources/custom_actions/scripts/check_host.py index 6f9a66c..8b49725 100644 --- a/ambari-server/src/main/resources/custom_actions/scripts/check_host.py +++ b/ambari-server/src/main/resources/custom_actions/scripts/check_host.py @@ -448,7 +448,7 @@ class CheckHost(Script): print "Last Agent Env check started." hostInfo = HostInfo() last_agent_env_check_structured_output = { } - hostInfo.register(last_agent_env_check_structured_output) + hostInfo.register(last_agent_env_check_structured_output, False, False) print "Last Agent Env check completed successfully." return last_agent_env_check_structured_output http://git-wip-us.apache.org/repos/asf/ambari/blob/0d676b32/ambari-web/app/controllers/wizard/step3_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/wizard/step3_controller.js b/ambari-web/app/controllers/wizard/step3_controller.js index 054a364..b3645e9 100644 --- a/ambari-web/app/controllers/wizard/step3_controller.js +++ b/ambari-web/app/controllers/wizard/step3_controller.js @@ -71,6 +71,8 @@ App.WizardStep3Controller = Em.Controller.extend(App.ReloadPopupMixin, { registrationStartedAt: null, + hostCheckResult: null, + requestId: 0, /** @@ -1081,6 +1083,13 @@ App.WizardStep3Controller = Em.Controller.extend(App.ReloadPopupMixin, { installedPackages: installed_packages ? installed_packages : [] }; })); + + console.log("Host check result available"); + this.set("hostCheckResult", data); //store the data so that it can be used later on in the getHostInfo handling logic. + /** + * Still need to get host info for checks that the host check does not perform currently + * Such as the OS type check and the disk space check + * */ this.getHostInfo(); } else if (data.Requests.inputs.indexOf("host_resolution_check") != -1) { this.parseHostNameResolution(data); @@ -1091,6 +1100,288 @@ App.WizardStep3Controller = Em.Controller.extend(App.ReloadPopupMixin, { } }, + parseHostCheckWarnings: function (data) { + data = App.get('testMode') ? data : this.filterHostsData(data); + var warnings = []; + var warning; + var hosts = []; + var warningCategories = { + fileFoldersWarnings: {}, + packagesWarnings: {}, + processesWarnings: {}, + servicesWarnings: {}, + usersWarnings: {}, + alternativeWarnings: {} + }; + + var hostsPackagesData = this.get('hostsPackagesData'); + data.tasks.sortPropertyLight('Tasks.host_name').forEach(function (_task) { + var hostName = _task.Tasks.host_name; + var host = { + name: hostName, + warnings: [] + }; + + if (!_task.Tasks.structured_out || !_task.Tasks.structured_out.last_agent_env_check) { + console.log("last_agent_env is missing for " + hostName + ". Skipping host check."); + return; + } + + var lastAgentEnvCheck = _task.Tasks.structured_out.last_agent_env_check; + + //parse all directories and files warnings for host + var stackFoldersAndFiles = lastAgentEnvCheck.stackFoldersAndFiles || []; + stackFoldersAndFiles.forEach(function (path) { + warning = warningCategories.fileFoldersWarnings[path.name]; + if (warning) { + warning.hosts.push(hostName); + warning.hostsLong.push(hostName); + warning.onSingleHost = false; + } else { + warningCategories.fileFoldersWarnings[path.name] = warning = { + name: path.name, + hosts: [hostName], + hostsLong: [hostName], + category: 'fileFolders', + onSingleHost: true + }; + } + host.warnings.push(warning); + }, this); + + //parse all package warnings for host + var _hostPackagesData = hostsPackagesData.findProperty('hostName', hostName); + + if (_hostPackagesData) { + _hostPackagesData.installedPackages.forEach(function (_package) { + warning = warningCategories.packagesWarnings[_package.name]; + if (warning) { + warning.hosts.push(hostName); + warning.hostsLong.push(hostName); + warning.version = _package.version; + warning.onSingleHost = false; + } else { + warningCategories.packagesWarnings[_package.name] = warning = { + name: _package.name, + version: _package.version, + hosts: [hostName], + hostsLong: [hostName], + category: 'packages', + onSingleHost: true + }; + } + host.warnings.push(warning); + }, this); + } + + //parse all process warnings for host + var hostHealth = lastAgentEnvCheck.hostHealth; + + var liveServices = null; + var javaProcs = null; + + if(hostHealth) { + if(hostHealth.activeJavaProcs) + javaProcs = hostHealth.activeJavaProcs; + if(hostHealth.liveServices) + liveServices = hostHealth.liveServices; + } + + if (javaProcs) { + javaProcs.forEach(function (process) { + warning = warningCategories.processesWarnings[process.pid]; + if (warning) { + warning.hosts.push(hostName); + warning.hostsLong.push(hostName); + warning.onSingleHost = false; + } else { + warningCategories.processesWarnings[process.pid] = warning = { + name: (process.command.substr(0, 35) + '...'), + hosts: [hostName], + hostsLong: [hostName], + category: 'processes', + user: process.user, + pid: process.pid, + command: '<table><tr><td style="word-break: break-all;">' + + ((process.command.length < 500) ? process.command : process.command.substr(0, 230) + '...' + + '<p style="text-align: center">................</p>' + + '...' + process.command.substr(-230)) + '</td></tr></table>', + onSingleHost: true + }; + } + host.warnings.push(warning); + }, this); + } + + //parse all service warnings for host + if (liveServices) { + liveServices.forEach(function (service) { + if (service.status === 'Unhealthy') { + warning = warningCategories.servicesWarnings[service.name]; + if (warning) { + warning.hosts.push(hostName); + warning.hostsLong.push(hostName); + warning.onSingleHost = false; + } else { + warningCategories.servicesWarnings[service.name] = warning = { + name: service.name, + hosts: [hostName], + hostsLong: [hostName], + category: 'services', + onSingleHost: true + }; + } + host.warnings.push(warning); + } + }, this); + } + //parse all user warnings for host + var existingUsers = lastAgentEnvCheck.existingUsers; + if (existingUsers) { + existingUsers.forEach(function (user) { + warning = warningCategories.usersWarnings[user.userName]; + if (warning) { + warning.hosts.push(hostName); + warning.hostsLong.push(hostName); + warning.onSingleHost = false; + } else { + warningCategories.usersWarnings[user.userName] = warning = { + name: user.userName, + hosts: [hostName], + hostsLong: [hostName], + category: 'users', + onSingleHost: true + }; + } + host.warnings.push(warning); + }, this); + } + + //parse misc warnings for host + var umask = lastAgentEnvCheck.umask; + if (umask && umask > 23) { + warning = warnings.filterProperty('category', 'misc').findProperty('name', umask); + if (warning) { + warning.hosts.push(hostName); + warning.hostsLong.push(hostName); + warning.onSingleHost = false; + } else { + warning = { + name: umask, + hosts: [hostName], + hostsLong: [hostName], + category: 'misc', + onSingleHost: true + }; + warnings.push(warning); + } + host.warnings.push(warning); + } + + var firewallRunning = lastAgentEnvCheck.firewallRunning; + if (firewallRunning !== null && firewallRunning) { + var name = lastAgentEnvCheck.firewallName + " Running"; + warning = warnings.filterProperty('category', 'firewall').findProperty('name', name); + if (warning) { + warning.hosts.push(hostName); + warning.hostsLong.push(hostName); + warning.onSingleHost = false; + } else { + warning = { + name: name, + hosts: [hostName], + hostsLong: [hostName], + category: 'firewall', + onSingleHost: true + }; + warnings.push(warning); + } + host.warnings.push(warning); + } + + if (lastAgentEnvCheck.alternatives) { + lastAgentEnvCheck.alternatives.forEach(function (alternative) { + warning = warningCategories.alternativeWarnings[alternative.name]; + if (warning) { + warning.hosts.push(hostName); + warning.hostsLong.push(hostName); + warning.onSingleHost = false; + } else { + warningCategories.alternativeWarnings[alternative.name] = warning = { + name: alternative.name, + target: alternative.target, + hosts: [hostName], + hostsLong: [hostName], + category: 'alternatives', + onSingleHost: true + }; + } + host.warnings.push(warning); + }, this); + } + + if (lastAgentEnvCheck.reverseLookup === false) { + var name = Em.I18n.t('installer.step3.hostWarningsPopup.reverseLookup.name'); + warning = warnings.filterProperty('category', 'reverseLookup').findProperty('name', name); + console.log("warning--"+warning); + if (warning) { + warning.hosts.push(hostName); + warning.hostsLong.push(hostName); + warning.onSingleHost = false; + } else { + warning = { + name: name, + hosts: [hostName], + hostsLong: [hostName], + category: 'reverseLookup', + onSingleHost: true + }; + warnings.push(warning); + } + host.warnings.push(warning); + } + hosts.push(host); + }, this); + + for (var categoryId in warningCategories) { + var category = warningCategories[categoryId]; + for (var warningId in category) { + warnings.push(category[warningId]); + } + } + + hosts.unshift({ + name: 'All Hosts', + warnings: warnings + }); + this.set('warnings', warnings); + this.set('warningsByHost', hosts); + }, + + /** + * Filter data for warnings parse + * is data from host in bootStrap + * @param {object} data + * @return {Object} + * @method filterBootHosts + */ + filterHostsData: function (data) { + var bootHostNames = {}; + this.get('bootHosts').forEach(function (bootHost) { + bootHostNames[bootHost.get('name')] = true; + }); + var filteredData = { + href: data.href, + tasks: [] + }; + data.tasks.forEach(function (_task) { + if (bootHostNames[_task.Tasks.host_name]) { + filteredData.tasks.push(_task); + } + }); + return filteredData; + }, + /** * parse warnings for host names resolution only * @param {object} data @@ -1143,7 +1434,7 @@ App.WizardStep3Controller = Em.Controller.extend(App.ReloadPopupMixin, { * @method getHostCheckTasksError */ getHostCheckTasksError: function() { - console.warn("failed to cheek hostName resolution"); + console.warn("failed to check hostName resolution"); this.set('stopChecking', true); }, @@ -1160,7 +1451,15 @@ App.WizardStep3Controller = Em.Controller.extend(App.ReloadPopupMixin, { thpWarnings = [], thpContext = [], thpHostsNames = []; // parse host checks warning - this.parseWarnings(jsonData); + var hostCheckResult = this.get("hostCheckResult"); + if(hostCheckResult){ + console.log("Parsing available host check result..."); + this.parseHostCheckWarnings(hostCheckResult); + this.set("hostCheckResult", null); + } else { + console.log("Parsing host info result..."); + this.parseWarnings(jsonData); + } this.set('isHostsWarningsLoaded', true); hosts.forEach(function (_host) { var host = (App.get('testMode')) ? jsonData.items[0] : jsonData.items.findProperty('Hosts.host_name', _host.name); http://git-wip-us.apache.org/repos/asf/ambari/blob/0d676b32/ambari-web/test/controllers/wizard/step3_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/controllers/wizard/step3_test.js b/ambari-web/test/controllers/wizard/step3_test.js index aad0509..74c62e6 100644 --- a/ambari-web/test/controllers/wizard/step3_test.js +++ b/ambari-web/test/controllers/wizard/step3_test.js @@ -1314,6 +1314,494 @@ describe('App.WizardStep3Controller', function () { }); }); + describe('#parseHostCheckWarnings', function () { + + beforeEach(function () { + sinon.stub(App, 'get', function (k) { + if ('testMode' === k) return false; + return Em.get(App, k); + }); + sinon.stub(c, 'filterHostsData', function (k) { + return k; + }); + }); + + afterEach(function () { + App.get.restore(); + c.filterHostsData.restore(); + }); + + it('no warnings if last_agent_env isn\'t specified', function () { + c.set('warnings', [ + {} + ]); + c.set('warningsByHost', [ + {}, + {} + ]); + c.parseHostCheckWarnings({tasks: [ + {Tasks: {host_name: 'c1'}} + ]}); + expect(c.get('warnings')).to.eql([]); + expect(c.get('warningsByHost.length')).to.equal(1); // default group + }); + + Em.A([ + { + m: 'parse stackFoldersAndFiles', + tests: Em.A([ + { + tasks: [ + {Tasks: {host_name: 'c1', + structured_out:{last_agent_env_check: {stackFoldersAndFiles: []}} + } + } + ], + m: 'empty stackFoldersAndFiles', + e: { + warnings: [], + warningsByHost: [0] + } + }, + { + tasks: [ + {Tasks: {host_name: 'c1', + structured_out: {last_agent_env_check: {stackFoldersAndFiles: [{name: 'n1'}]}} + } + } + ], + m: 'not empty stackFoldersAndFiles', + e: { + warnings: [ + { + name: 'n1', + hosts: ['c1'], + onSingleHost: true, + category: 'fileFolders' + } + ], + warningsByHost: [1] + } + }, + { + tasks: [ + {Tasks: {host_name: 'c1', structured_out:{last_agent_env_check: {stackFoldersAndFiles: [ + {name: 'n1'} + ]}}}}, + {Tasks: {host_name: 'c2', structured_out: {last_agent_env_check: {stackFoldersAndFiles: [ + {name: 'n1'} + ]}}}} + ], + m: 'not empty stackFoldersAndFiles on two hosts', + e: { + warnings: [ + { + name: 'n1', + hosts: ['c1', 'c2'], + onSingleHost: false, + category: 'fileFolders' + } + ], + warningsByHost: [1] + } + } + ]) + }, + { + m: 'parse hostHealth.liveServices', + tests: Em.A([ + { + tasks: [ + {Tasks: {host_name: 'c1', structured_out: {last_agent_env_check: {hostHealth: []}}}} + ], + m: 'empty hostHealth', + e: { + warnings: [], + warningsByHost: [0] + } + }, + { + tasks: [ + {Tasks: {host_name: 'c1', structured_out: {last_agent_env_check: {hostHealth: {liveServices: []}}}}} + ], + m: 'empty liveServices', + e: { + warnings: [], + warningsByHost: [0] + } + }, + { + tasks: [ + {Tasks: {host_name: 'c1', + structured_out: {last_agent_env_check: {hostHealth: {liveServices: [{status: 'Unhealthy', name: 'n1'}]}}} + } + } + ], + m: 'not empty hostHealth.liveServices', + e: { + warnings: [ + { + name: 'n1', + hosts: ['c1'], + onSingleHost: true, + category: 'services' + } + ], + warningsByHost: [1] + } + }, + { + tasks: [ + {Tasks: {host_name: 'c1', + structured_out:{last_agent_env_check: {hostHealth: {liveServices: [{status: 'Unhealthy', name: 'n1'}]}}} + } + }, + + {Tasks: {host_name: 'c2', + structured_out:{last_agent_env_check: {hostHealth: {liveServices: [{status: 'Unhealthy', name: 'n1'}]}}} + } + } + ], + m: 'not empty hostHealth.liveServices on two hosts', + e: { + warnings: [ + { + name: 'n1', + hosts: ['c1', 'c2'], + onSingleHost: false, + category: 'services' + } + ], + warningsByHost: [1, 1] + } + } + ]) + }, + { + m: 'parse existingUsers', + tests: Em.A([ + { + tasks: [ + {Tasks: {host_name: 'c1', + structured_out: {last_agent_env_check: {existingUsers: []}} + } + } + ], + m: 'empty existingUsers', + e: { + warnings: [], + warningsByHost: [0] + } + }, + { + tasks: [ + {Tasks: {host_name: 'c1', + structured_out: {last_agent_env_check: {existingUsers: [{userName: 'n1'}]}} + } + } + ], + m: 'not empty existingUsers', + e: { + warnings: [ + { + name: 'n1', + hosts: ['c1'], + onSingleHost: true, + category: 'users' + } + ], + warningsByHost: [1] + } + }, + { + tasks: [ + {Tasks: {host_name: 'c1', + structured_out:{last_agent_env_check: {existingUsers: [{userName: 'n1'}]}} + } + }, + {Tasks: {host_name: 'c2', + structured_out:{last_agent_env_check: {existingUsers: [{userName: 'n1'}]}} + } + } + ], + m: 'not empty existingUsers on two hosts', + e: { + warnings: [ + { + name: 'n1', + hosts: ['c1', 'c2'], + onSingleHost: false, + category: 'users' + } + ], + warningsByHost: [1, 1] + } + } + ]) + }, + { + m: 'parse alternatives', + tests: Em.A([ + { + tasks: [ + {Tasks: {host_name: 'c1', + structured_out:{last_agent_env_check: {alternatives: []}} + } + } + ], + m: 'empty alternatives', + e: { + warnings: [], + warningsByHost: [0] + } + }, + { + tasks: [ + {Tasks: {host_name: 'c1', + structured_out: {last_agent_env_check: {alternatives: [{name: 'n1'}]}} + } + } + ], + m: 'not empty alternatives', + e: { + warnings: [ + { + name: 'n1', + hosts: ['c1'], + onSingleHost: true, + category: 'alternatives' + } + ], + warningsByHost: [1] + } + }, + { + tasks: [ + {Tasks: {host_name: 'c1', + structured_out:{last_agent_env_check: {alternatives: [{name: 'n1'}]}} + } + }, + {Tasks: {host_name: 'c2', + structured_out:{last_agent_env_check: {alternatives: [{name: 'n1'}]}} + } + } + ], + m: 'not empty alternatives on two hosts', + e: { + warnings: [ + { + name: 'n1', + hosts: ['c1', 'c2'], + onSingleHost: false, + category: 'alternatives' + } + ], + warningsByHost: [1, 1] + } + } + ]) + }, + { + m: 'parse hostHealth.activeJavaProcs', + tests: Em.A([ + { + tasks: [ + {Tasks: {host_name: 'c1', + structured_out:{last_agent_env_check: {hostHealth: [], javaProcs: []}} + } + } + ], + m: 'empty hostHealth', + e: { + warnings: [], + warningsByHost: [0] + } + }, + { + tasks: [ + {Tasks: {host_name: 'c1', structured_out:{last_agent_env_check: {hostHealth: {activeJavaProcs: []}}}}} + ], + m: 'empty activeJavaProcs', + e: { + warnings: [], + warningsByHost: [0] + } + }, + { + tasks: [ + {Tasks: {host_name: 'c1', + structured_out:{last_agent_env_check: {hostHealth: {activeJavaProcs: [{pid: 'n1', command: ''}]}}} + } + } + ], + m: 'not empty hostHealth.activeJavaProcs', + e: { + warnings: [ + { + pid: 'n1', + hosts: ['c1'], + onSingleHost: true, + category: 'processes' + } + ], + warningsByHost: [1] + } + }, + { + tasks: [ + {Tasks: {host_name: 'c1', + structured_out:{last_agent_env_check: {hostHealth: {activeJavaProcs: [{pid: 'n1', command: ''}]}}} + } + }, + {Tasks: {host_name: 'c2', + structured_out:{last_agent_env_check: {hostHealth: {activeJavaProcs: [{pid: 'n1', command: ''}]}}} + } + } + ], + m: 'not empty hostHealth.activeJavaProcs on two hosts', + e: { + warnings: [ + { + pid: 'n1', + hosts: ['c1', 'c2'], + onSingleHost: false, + category: 'processes' + } + ], + warningsByHost: [1, 1] + } + } + ]) + } + ]).forEach(function (category) { + describe(category.m, function () { + category.tests.forEach(function (test) { + it(test.m, function () { + c.parseHostCheckWarnings({tasks: test.tasks}); + c.get('warnings').forEach(function (w, i) { + Em.keys(test.e.warnings[i]).forEach(function (k) { + expect(w[k]).to.eql(test.e.warnings[i][k]); + }); + }); + for (var i in test.e.warningsByHost) { + if (test.e.warningsByHost.hasOwnProperty(i)) { + expect(c.get('warningsByHost')[i].warnings.length).to.equal(test.e.warningsByHost[i]); + } + } + }); + }); + }); + }); + + it('should parse umask warnings', function () { + + var tasks = [ + {Tasks: {host_name: 'c1', structured_out:{last_agent_env_check: {umask: 24}}}}, + {Tasks: {host_name: 'c2', structured_out:{last_agent_env_check: {umask: 1}}}} + ]; + + c.parseHostCheckWarnings({tasks: tasks}); + var warnings = c.get('warnings'); + expect(warnings.length).to.equal(1); + expect(warnings[0].hosts).to.eql(['c1']); + expect(warnings[0].hostsLong).to.eql(['c1']); + expect(warnings[0].onSingleHost).to.equal(true); + + }); + + it('should parse umask warnings (2)', function () { + + var tasks = [ + {Tasks: {host_name: 'c1', structured_out:{last_agent_env_check: {umask: 24}}}}, + {Tasks: {host_name: 'c2', structured_out:{last_agent_env_check: {umask: 25}}}} + ]; + + c.parseHostCheckWarnings({tasks: tasks}); + var warnings = c.get('warnings'); + expect(warnings.length).to.equal(2); + expect(warnings.mapProperty('hosts')).to.eql([ + ['c1'], + ['c2'] + ]); + + }); + + it('should parse firewall warnings', function () { + + var tasks = [ + {Tasks: {host_name: 'c1', structured_out:{last_agent_env_check: {firewallRunning: true, firewallName: "iptables"}}}}, + {Tasks: {host_name: 'c2', structured_out:{last_agent_env_check: {firewallRunning: false, firewallName: "iptables"}}}} + ]; + + c.parseHostCheckWarnings({tasks: tasks}); + var warnings = c.get('warnings'); + expect(warnings.length).to.equal(1); + expect(warnings[0].hosts).to.eql(['c1']); + expect(warnings[0].hostsLong).to.eql(['c1']); + expect(warnings[0].onSingleHost).to.equal(true); + + }); + + it('should parse firewall warnings (2)', function () { + + var tasks = [ + {Tasks: {host_name: 'c1', structured_out:{last_agent_env_check: {firewallRunning: true, firewallName: "iptables"}}}}, + {Tasks: {host_name: 'c2', structured_out:{last_agent_env_check: {firewallRunning: true, firewallName: "iptables"}}}} + ]; + + c.parseHostCheckWarnings({tasks: tasks}); + var warnings = c.get('warnings'); + expect(warnings.length).to.equal(1); + expect(warnings[0].hosts).to.eql(['c1', 'c2']); + expect(warnings[0].hostsLong).to.eql(['c1', 'c2']); + expect(warnings[0].onSingleHost).to.equal(false); + + }); + + it('should parse reverseLookup warnings', function () { + + var tasks = [ + {Tasks: {host_name: 'c1', structured_out:{last_agent_env_check: {reverseLookup: true}}}} + ]; + + c.parseHostCheckWarnings({tasks: tasks}); + var warnings = c.get('warnings'); + expect(warnings.length).to.equal(0); + + }); + + it('should parse reverseLookup warnings (2)', function () { + + var tasks = [ + {Tasks: {host_name: 'c1', structured_out:{last_agent_env_check: {reverseLookup: false}}}} + ]; + + c.parseHostCheckWarnings({tasks: tasks}); + var warnings = c.get('warnings'); + expect(warnings.length).to.equal(1); + expect(warnings[0].hosts).to.eql(['c1']); + expect(warnings[0].hostsLong).to.eql(['c1']); + expect(warnings[0].onSingleHost).to.equal(true); + + }); + + it('should parse reverseLookup warnings (3)', function () { + + var tasks = [ + {Tasks: {host_name: 'c1', structured_out:{last_agent_env_check: {reverseLookup: false}}}}, + {Tasks: {host_name: 'c2', structured_out:{last_agent_env_check: {reverseLookup: false}}}} + ]; + + c.parseHostCheckWarnings({tasks: tasks}); + var warnings = c.get('warnings'); + expect(warnings.length).to.equal(1); + expect(warnings[0].hosts).to.eql(['c1', 'c2']); + expect(warnings[0].hostsLong).to.eql(['c1', 'c2']); + expect(warnings[0].onSingleHost).to.equal(false); + + }); + }); + describe('#parseWarnings', function () { beforeEach(function () {