alert_definitions_mapper_test.js 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489
  1. /**
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements. See the NOTICE file distributed with this
  4. * work for additional information regarding copyright ownership. The ASF
  5. * licenses this file to you under the Apache License, Version 2.0 (the
  6. * "License"); you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  13. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  14. * License for the specific language governing permissions and limitations under
  15. * the License.
  16. */
  17. var App = require('app');
  18. require('mappers/alert_definitions_mapper');
  19. var testHelpers = require('test/helpers');
  20. describe('App.alertDefinitionsMapper', function () {
  21. /*eslint-disable mocha-cleanup/asserts-limit */
  22. describe('#map', function () {
  23. var json = {
  24. items: [
  25. {
  26. "AlertDefinition" : {
  27. "component_name" : "RESOURCEMANAGER",
  28. "enabled" : true,
  29. "id" : 1,
  30. "ignore_host" : false,
  31. "interval" : 5,
  32. "label" : "ResourceManager RPC Latency",
  33. "name" : "yarn_resourcemanager_rpc_latency",
  34. "description" : "some description",
  35. "scope" : "ANY",
  36. "service_name" : "YARN",
  37. "source" : {
  38. "jmx" : {
  39. "property_list" : [
  40. "Hadoop:service=ResourceManager,name=RpcActivityForPort*/RpcQueueTimeAvgTime",
  41. "Hadoop:service=ResourceManager,name=RpcActivityForPort*/RpcProcessingTimeAvgTime"
  42. ],
  43. "value" : "{0}"
  44. },
  45. "reporting" : {
  46. "ok" : {
  47. "text" : "Average Queue Time:[{0}], Average Processing Time:[{1}]"
  48. },
  49. "warning" : {
  50. "text" : "Average Queue Time:[{0}], Average Processing Time:[{1}]",
  51. "value" : 3000.0
  52. },
  53. "critical" : {
  54. "text" : "Average Queue Time:[{0}], Average Processing Time:[{1}]",
  55. "value" : 5000.0
  56. }
  57. },
  58. "type" : "METRIC",
  59. "uri" : {
  60. "http" : "{{yarn-site/yarn.resourcemanager.webapp.address}}",
  61. "https" : "{{yarn-site/yarn.resourcemanager.webapp.https.address}}",
  62. "https_property" : "{{yarn-site/yarn.http.policy}}",
  63. "https_property_value" : "HTTPS_ONLY",
  64. "default_port" : 0.0
  65. }
  66. }
  67. }
  68. },
  69. {
  70. "AlertDefinition" : {
  71. "component_name" : "RESOURCEMANAGER",
  72. "enabled" : true,
  73. "id" : 2,
  74. "ignore_host" : false,
  75. "interval" : 1,
  76. "label" : "ResourceManager Web UI",
  77. "name" : "yarn_resourcemanager_webui",
  78. "description" : "",
  79. "scope" : "ANY",
  80. "service_name" : "YARN",
  81. "source" : {
  82. "reporting" : {
  83. "ok" : {
  84. "text" : "HTTP {0} response in {2:.4f} seconds"
  85. },
  86. "warning" : {
  87. "text" : "HTTP {0} response in {2:.4f} seconds"
  88. },
  89. "critical" : {
  90. "text" : "Connection failed to {1}"
  91. }
  92. },
  93. "type" : "WEB",
  94. "uri" : {
  95. "http" : "{{yarn-site/yarn.resourcemanager.webapp.address}}",
  96. "https" : "{{yarn-site/yarn.resourcemanager.webapp.https.address}}",
  97. "https_property" : "{{yarn-site/yarn.http.policy}}",
  98. "https_property_value" : "HTTPS_ONLY",
  99. "default_port" : 0.0
  100. }
  101. }
  102. }
  103. },
  104. {
  105. "AlertDefinition" : {
  106. "component_name" : null,
  107. "enabled" : true,
  108. "id" : 3,
  109. "ignore_host" : false,
  110. "interval" : 1,
  111. "label" : "Percent NodeManagers Available",
  112. "name" : "yarn_nodemanager_webui_percent",
  113. "description" : null,
  114. "scope" : "SERVICE",
  115. "service_name" : "YARN",
  116. "source" : {
  117. "alert_name" : "yarn_nodemanager_webui",
  118. "reporting" : {
  119. "ok" : {
  120. "text" : "affected: [{1}], total: [{0}]"
  121. },
  122. "warning" : {
  123. "text" : "affected: [{1}], total: [{0}]",
  124. "value" : 0.1
  125. },
  126. "critical" : {
  127. "text" : "affected: [{1}], total: [{0}]",
  128. "value" : 0.3
  129. }
  130. },
  131. "type" : "AGGREGATE"
  132. }
  133. }
  134. },
  135. {
  136. "AlertDefinition" : {
  137. "component_name" : "NODEMANAGER",
  138. "enabled" : true,
  139. "id" : 4,
  140. "ignore_host" : false,
  141. "interval" : 1,
  142. "label" : "NodeManager Health",
  143. "name" : "yarn_nodemanager_health",
  144. "description" : "some description",
  145. "scope" : "HOST",
  146. "service_name" : "YARN",
  147. "source" : {
  148. "parameters" : [
  149. {
  150. "name" : "connection.timeout",
  151. "display_name" : "Connection Timeout",
  152. "units" : "seconds",
  153. "value" : 5.0,
  154. "description" : "The maximum time before this alert is considered to be CRITICAL",
  155. "type" : "NUMERIC",
  156. "threshold" : "CRITICAL"
  157. }
  158. ],
  159. "path" : "HDP/2.0.6/services/YARN/package/files/alert_nodemanager_health.py",
  160. "type" : "SCRIPT"
  161. }
  162. }
  163. },
  164. {
  165. "AlertDefinition" : {
  166. "component_name" : "ZOOKEEPER_SERVER",
  167. "enabled" : true,
  168. "id" : 5,
  169. "ignore_host" : false,
  170. "interval" : 1,
  171. "label" : "ZooKeeper Server Process",
  172. "name" : "zookeeper_server_process",
  173. "description" : "some description",
  174. "scope" : "ANY",
  175. "service_name" : "ZOOKEEPER",
  176. "source" : {
  177. "default_port" : 2181.0,
  178. "reporting" : {
  179. "ok" : {
  180. "text" : "TCP OK - {0:.4f} response on port {1}"
  181. },
  182. "critical" : {
  183. "text" : "Connection failed: {0} to {1}:{2}"
  184. }
  185. },
  186. "type" : "PORT",
  187. "uri" : "{{zookeeper-env/clientPort}}"
  188. }
  189. }
  190. }
  191. ]
  192. };
  193. beforeEach(function () {
  194. App.alertDefinitionsMapper.setProperties({
  195. 'model': {},
  196. 'parameterModel': {},
  197. 'reportModel': {},
  198. 'metricsSourceModel': {},
  199. 'metricsUriModel': {}
  200. });
  201. sinon.stub(App.alertDefinitionsMapper, 'deleteRecord', Em.K);
  202. sinon.stub(App.store, 'commit', Em.K);
  203. sinon.stub(App.store, 'loadMany', function (type, content) {
  204. type.content = content;
  205. });
  206. sinon.stub(App.router, 'get', function() {return false;});
  207. App.cache.previousAlertGroupsMap = {};
  208. sinon.stub(App.alertDefinitionsMapper, 'setMetricsSourcePropertyLists', Em.K);
  209. sinon.stub(App.alertDefinitionsMapper, 'setAlertDefinitionsRawSourceData', Em.K);
  210. });
  211. afterEach(function () {
  212. App.store.commit.restore();
  213. App.store.loadMany.restore();
  214. App.alertDefinitionsMapper.setProperties({
  215. 'model': App.AlertDefinition,
  216. 'reportModel': App.AlertReportDefinition,
  217. 'metricsSourceModel': App.AlertMetricsSourceDefinition,
  218. 'metricsUriModel': App.AlertMetricsUriDefinition
  219. });
  220. App.alertDefinitionsMapper.deleteRecord.restore();
  221. App.router.get.restore();
  222. App.cache.previousAlertGroupsMap = {};
  223. App.alertDefinitionsMapper.setMetricsSourcePropertyLists.restore();
  224. App.alertDefinitionsMapper.setAlertDefinitionsRawSourceData.restore();
  225. });
  226. describe('should parse METRIC alertDefinitions', function () {
  227. var data = {items: [json.items[0]]},
  228. expected = [{
  229. id: 1,
  230. "name": "yarn_resourcemanager_rpc_latency",
  231. "label": "ResourceManager RPC Latency",
  232. "description" : "some description",
  233. "service_id": "YARN",
  234. "component_name": "RESOURCEMANAGER",
  235. "enabled": true,
  236. "scope": "ANY",
  237. "interval": 5,
  238. "type": "METRIC",
  239. "jmx_id": "1jmx",
  240. "uri_id": "1uri"
  241. }],
  242. expectedMetricsSource = [{
  243. "id":"1jmx",
  244. "value":"{0}",
  245. "property_list":[
  246. "Hadoop:service=ResourceManager,name=RpcActivityForPort*/RpcQueueTimeAvgTime",
  247. "Hadoop:service=ResourceManager,name=RpcActivityForPort*/RpcProcessingTimeAvgTime"
  248. ]
  249. }],
  250. expectedMetricsUri = [{
  251. "id":"1uri",
  252. "http":"{{yarn-site/yarn.resourcemanager.webapp.address}}",
  253. "https":"{{yarn-site/yarn.resourcemanager.webapp.https.address}}",
  254. "https_property":"{{yarn-site/yarn.http.policy}}",
  255. "https_property_value":"HTTPS_ONLY"
  256. }];
  257. beforeEach(function () {
  258. App.alertDefinitionsMapper.map(data);
  259. });
  260. it('parsing metrics model', function() {
  261. testHelpers.nestedExpect(expected, App.alertDefinitionsMapper.get('model.content'));
  262. });
  263. it('parse metrics source', function() {
  264. testHelpers.nestedExpect(expectedMetricsSource, App.alertDefinitionsMapper.get('metricsSourceModel.content'));
  265. });
  266. it('parse metrics uri', function() {
  267. testHelpers.nestedExpect(expectedMetricsUri, App.alertDefinitionsMapper.get('metricsUriModel.content'));
  268. });
  269. });
  270. describe('should parse WEB alertDefinitions', function () {
  271. var data = {items: [json.items[1]]},
  272. expected = [
  273. {
  274. "id": 2,
  275. "name": "yarn_resourcemanager_webui",
  276. "label": "ResourceManager Web UI",
  277. "description" : "",
  278. "service_id": "YARN",
  279. "component_name": "RESOURCEMANAGER",
  280. "enabled": true,
  281. "scope": "ANY",
  282. "interval": 1,
  283. "type": "WEB",
  284. "uri_id": "2uri"
  285. }
  286. ],
  287. expectedMetricsUri = [{
  288. "id":"2uri",
  289. "http":"{{yarn-site/yarn.resourcemanager.webapp.address}}",
  290. "https":"{{yarn-site/yarn.resourcemanager.webapp.https.address}}",
  291. "https_property":"{{yarn-site/yarn.http.policy}}",
  292. "https_property_value":"HTTPS_ONLY"
  293. }];
  294. beforeEach(function () {
  295. App.alertDefinitionsMapper.map(data);
  296. });
  297. it('parsing web model', function() {
  298. testHelpers.nestedExpect(expected, App.alertDefinitionsMapper.get('model.content'));
  299. });
  300. it('parse metrics uri', function() {
  301. testHelpers.nestedExpect(expectedMetricsUri, App.alertDefinitionsMapper.get('metricsUriModel.content'));
  302. });
  303. });
  304. it('should parse AGGREGATE alertDefinitions', function () {
  305. var data = {items: [json.items[2]]},
  306. expected = [
  307. {
  308. "id":3,
  309. "name":"yarn_nodemanager_webui_percent",
  310. "label":"Percent NodeManagers Available",
  311. "description" : "",
  312. "service_id":"YARN",
  313. "component_name":null,
  314. "enabled":true,
  315. "scope":"SERVICE",
  316. "interval":1,
  317. "type":"AGGREGATE",
  318. "alert_name":"yarn_nodemanager_webui"
  319. }
  320. ];
  321. App.alertDefinitionsMapper.map(data);
  322. testHelpers.nestedExpect(expected, App.alertDefinitionsMapper.get('model.content'));
  323. });
  324. describe('should parse SCRIPT alertDefinitions', function () {
  325. var data = {items: [json.items[3]]},
  326. expected = [
  327. {
  328. "id":4,
  329. "name":"yarn_nodemanager_health",
  330. "label":"NodeManager Health",
  331. "description" : "some description",
  332. "service_id":"YARN",
  333. "component_name":"NODEMANAGER",
  334. "enabled":true,
  335. "scope":"HOST",
  336. "interval":1,
  337. "type":"SCRIPT",
  338. "location":"HDP/2.0.6/services/YARN/package/files/alert_nodemanager_health.py"
  339. }
  340. ];
  341. var expectedParameters = [{
  342. "id": "4connection.timeout",
  343. "name": "connection.timeout",
  344. "display_name": "Connection Timeout",
  345. "units": "seconds",
  346. "value": 5,
  347. "description": "The maximum time before this alert is considered to be CRITICAL",
  348. "type": "NUMERIC",
  349. "threshold": "CRITICAL"
  350. }];
  351. beforeEach(function () {
  352. App.alertDefinitionsMapper.map(data);
  353. });
  354. it('should map definition', function () {
  355. testHelpers.nestedExpect(expected, App.alertDefinitionsMapper.get('model.content'));
  356. });
  357. it('should map parameters', function () {
  358. testHelpers.nestedExpect(expectedParameters, App.alertDefinitionsMapper.get('parameterModel.content'));
  359. });
  360. });
  361. it('should parse PORT alertDefinitions', function () {
  362. var data = {items: [json.items[4]]},
  363. expected = [
  364. {
  365. "id":5,
  366. "name":"zookeeper_server_process",
  367. "label":"ZooKeeper Server Process",
  368. "description" : "some description",
  369. "service_id":"ZOOKEEPER",
  370. "component_name":"ZOOKEEPER_SERVER",
  371. "enabled":true,
  372. "scope":"ANY",
  373. "interval":1,
  374. "type":"PORT",
  375. "default_port":2181,
  376. "port_uri":"{{zookeeper-env/clientPort}}"
  377. }
  378. ];
  379. App.alertDefinitionsMapper.map(data);
  380. testHelpers.nestedExpect(expected, App.alertDefinitionsMapper.get('model.content'));
  381. });
  382. /*eslint-disable mocha-cleanup/complexity-it */
  383. it('should set groups from App.cache.previousAlertGroupsMap', function () {
  384. App.cache.previousAlertGroupsMap = {
  385. 1: [5,1],
  386. 2: [4,3],
  387. 3: [3,2],
  388. 4: [2,5],
  389. 5: [1,4]
  390. };
  391. App.alertDefinitionsMapper.map(json);
  392. expect(App.alertDefinitionsMapper.get('model.content')[0].groups).to.eql([5, 1]);
  393. expect(App.alertDefinitionsMapper.get('model.content')[1].groups).to.eql([4, 3]);
  394. expect(App.alertDefinitionsMapper.get('model.content')[2].groups).to.eql([3, 2]);
  395. expect(App.alertDefinitionsMapper.get('model.content')[3].groups).to.eql([2, 5]);
  396. expect(App.alertDefinitionsMapper.get('model.content')[4].groups).to.eql([1, 4]);
  397. });
  398. /*eslint-enable mocha-cleanup/complexity-it */
  399. describe('should delete not existing definitions', function () {
  400. var definitions = [
  401. Em.Object.create({id: 100500, type: 'PORT'})
  402. ];
  403. beforeEach(function () {
  404. sinon.stub(App.AlertDefinition, 'find', function () {
  405. return definitions;
  406. });
  407. });
  408. afterEach(function() {
  409. App.AlertDefinition.find.restore();
  410. });
  411. it('should delete PORT alert definition with id 100500', function () {
  412. App.alertDefinitionsMapper.map(json);
  413. expect(App.alertDefinitionsMapper.deleteRecord.calledOnce).to.be.true;
  414. expect(App.alertDefinitionsMapper.deleteRecord.args[0][0].id).to.equal(100500);
  415. });
  416. });
  417. });
  418. /*eslint-enable mocha-cleanup/asserts-limit */
  419. });