summary_test.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455
  1. /**
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. var App = require('app');
  19. require('views/main/service/info/summary');
  20. var batchUtils = require('utils/batch_scheduled_requests');
  21. describe('App.MainServiceInfoSummaryView', function() {
  22. var view = App.MainServiceInfoSummaryView.create({
  23. monitorsLiveTextView: Em.View.create(),
  24. controller: Em.Object.create({
  25. content: Em.Object.create({
  26. id: 'HDFS',
  27. serviceName: 'HDFS',
  28. hostComponents: []
  29. }),
  30. getActiveWidgetLayout: Em.K
  31. }),
  32. alertsController: Em.Object.create(),
  33. service: Em.Object.create()
  34. });
  35. App.TestAliases.testAsComputedAlias(view, 'servicesHaveClients', 'App.services.hasClient', 'boolean');
  36. App.TestAliases.testAsComputedAlias(view, 'serviceName', 'service.serviceName', 'string');
  37. App.TestAliases.testAsComputedAlias(view, 'alertsCount', 'controller.content.alertsCount', 'number');
  38. App.TestAliases.testAsComputedAlias(view, 'hasCriticalAlerts', 'controller.content.hasCriticalAlerts', 'boolean');
  39. describe('#servers', function () {
  40. it('services shouldn\'t have servers except FLUME and ZOOKEEPER', function () {
  41. expect(view.get('servers')).to.be.empty;
  42. });
  43. it('if one server exists then first server should have isComma and isAnd property false', function () {
  44. view.set('controller.content', Em.Object.create({
  45. id: 'ZOOKEEPER',
  46. serviceName: 'ZOOKEEPER',
  47. hostComponents: [
  48. Em.Object.create({
  49. displayName: '',
  50. isMaster: true
  51. })
  52. ]
  53. }));
  54. expect(view.get('servers').objectAt(0).isComma).to.equal(false);
  55. expect(view.get('servers').objectAt(0).isAnd).to.equal(false);
  56. });
  57. it('if more than one servers exist then first server should have isComma - true and isAnd - false', function () {
  58. view.set('controller.content', Em.Object.create({
  59. id: 'ZOOKEEPER',
  60. serviceName: 'ZOOKEEPER',
  61. hostComponents: [
  62. Em.Object.create({
  63. displayName: '',
  64. isMaster: true
  65. }),
  66. Em.Object.create({
  67. displayName: '',
  68. isMaster: true
  69. })
  70. ]
  71. }));
  72. expect(view.get('servers').objectAt(0).isComma).to.equal(true);
  73. expect(view.get('servers').objectAt(0).isAnd).to.equal(false);
  74. expect(view.get('servers').objectAt(1).isComma).to.equal(false);
  75. expect(view.get('servers').objectAt(1).isAnd).to.equal(false);
  76. });
  77. it('if more than two servers exist then second server should have isComma - false and isAnd - true', function () {
  78. view.set('controller.content', Em.Object.create({
  79. id: 'ZOOKEEPER',
  80. serviceName: 'ZOOKEEPER',
  81. hostComponents: [
  82. Em.Object.create({
  83. displayName: '',
  84. isMaster: true
  85. }),
  86. Em.Object.create({
  87. displayName: '',
  88. isMaster: true
  89. }),
  90. Em.Object.create({
  91. displayName: '',
  92. isMaster: true
  93. })
  94. ]
  95. }));
  96. expect(view.get('servers').objectAt(0).isComma).to.equal(true);
  97. expect(view.get('servers').objectAt(0).isAnd).to.equal(false);
  98. expect(view.get('servers').objectAt(1).isComma).to.equal(false);
  99. expect(view.get('servers').objectAt(1).isAnd).to.equal(true);
  100. expect(view.get('servers').objectAt(2).isComma).to.equal(false);
  101. expect(view.get('servers').objectAt(2).isAnd).to.equal(false);
  102. });
  103. });
  104. describe('#hasAlertDefinitions', function () {
  105. beforeEach(function () {
  106. sinon.stub(App.AlertDefinition, 'find', function () {
  107. return [
  108. {
  109. serviceName: 'HDFS'
  110. },
  111. {
  112. serviceName: 'YARN'
  113. }
  114. ];
  115. });
  116. });
  117. afterEach(function () {
  118. App.AlertDefinition.find.restore();
  119. });
  120. it('should return true if at least one alert definition for this service exists', function () {
  121. view.set('controller.content', Em.Object.create({
  122. serviceName: 'HDFS'
  123. }));
  124. expect(view.get('hasAlertDefinitions')).to.be.true;
  125. it('should return false if there is no alert definition for this service', function () {
  126. view.set('controller.content', Em.Object.create({
  127. serviceName: 'ZOOKEEPER'
  128. }));
  129. expect(view.get('hasAlertDefinitions')).to.be.false;
  130. });
  131. })
  132. });
  133. describe('#didInsertElement', function () {
  134. var cases = [
  135. {
  136. serviceName: 'STORM',
  137. isStormMetricsSupported: false,
  138. isConstructGraphObjectsCalled: false,
  139. title: 'Storm, metrics not supported'
  140. },
  141. {
  142. serviceName: 'STORM',
  143. isStormMetricsSupported: true,
  144. isConstructGraphObjectsCalled: true,
  145. title: 'Storm, metrics supported'
  146. },
  147. {
  148. serviceName: 'HDFS',
  149. isConstructGraphObjectsCalled: true,
  150. title: 'not Storm'
  151. }
  152. ];
  153. beforeEach(function () {
  154. sinon.stub(view, 'constructGraphObjects', Em.K);
  155. this.mock = sinon.stub(App, 'get');
  156. });
  157. afterEach(function () {
  158. view.constructGraphObjects.restore();
  159. this.mock.restore();
  160. });
  161. cases.forEach(function (item) {
  162. it(item.title, function () {
  163. view.set('controller.content.serviceName', item.serviceName);
  164. this.mock.withArgs('isStormMetricsSupported').returns(item.isStormMetricsSupported);
  165. view.didInsertElement();
  166. expect(view.constructGraphObjects.calledOnce).to.equal(item.isConstructGraphObjectsCalled);
  167. });
  168. });
  169. });
  170. describe.skip('#setTimeRange', function () {
  171. var cases = [
  172. {
  173. currentTimeRangeIndex: 0,
  174. isServiceMetricLoaded: false,
  175. graphIds: [],
  176. title: 'no event passed'
  177. },
  178. {
  179. event: {},
  180. currentTimeRangeIndex: 0,
  181. isServiceMetricLoaded: false,
  182. graphIds: [],
  183. title: 'no event context passed'
  184. },
  185. {
  186. event: {
  187. context: {
  188. index: 1
  189. }
  190. },
  191. currentTimeRangeIndex: 1,
  192. isServiceMetricLoaded: false,
  193. graphIds: [],
  194. title: 'no service name set'
  195. },
  196. {
  197. event: {
  198. context: {
  199. index: 2
  200. }
  201. },
  202. serviceName: 'HDFS',
  203. currentTimeRangeIndex: 2,
  204. isServiceMetricLoaded: true,
  205. graphIds: [
  206. [
  207. 'service-metrics-hdfs-space-utilization', 'service-metrics-hdfs-file-operations',
  208. 'service-metrics-hdfs-block-status', 'service-metrics-hdfs-io', 'service-metrics-hdfs-rpc'
  209. ],
  210. [
  211. 'service-metrics-hdfs-gc', 'service-metrics-hdfs-jvm-heap', 'service-metrics-hdfs-jvm-threads'
  212. ]
  213. ]
  214. },
  215. {
  216. event: {
  217. context: {
  218. index: 3
  219. }
  220. },
  221. serviceName: 'YARN',
  222. currentTimeRangeIndex: 3,
  223. isServiceMetricLoaded: true,
  224. graphIds: [
  225. [
  226. 'service-metrics-yarn-queue-allocated', 'service-metrics-yarn-queue-memory-resource',
  227. 'service-metrics-yarn-queue-allocated-container', 'service-metrics-yarn-node-manager-statuses',
  228. 'service-metrics-yarn-apps-current-states'
  229. ],
  230. [
  231. 'service-metrics-yarn-apps-finished-states', 'service-metrics-yarn-rpc', 'service-metrics-yarn-gc',
  232. 'service-metrics-yarn-jvm-threads', 'service-metrics-yarn-jvm-heap'
  233. ]
  234. ]
  235. },
  236. {
  237. event: {
  238. context: {
  239. index: 4
  240. }
  241. },
  242. serviceName: 'HBASE',
  243. currentTimeRangeIndex: 4,
  244. isServiceMetricLoaded: true,
  245. graphIds: [
  246. [
  247. 'service-metrics-hbase-cluster-requests', 'service-metrics-hbase-regionserver-rw-requests',
  248. 'service-metrics-hbase-regionserver-regions', 'service-metrics-hbase-regionserver-queuesize',
  249. 'service-metrics-hbase-hlog-split-time'
  250. ],
  251. [
  252. 'service-metrics-hbase-hlog-split-size'
  253. ]
  254. ]
  255. },
  256. {
  257. event: {
  258. context: {
  259. index: 5
  260. }
  261. },
  262. serviceName: 'AMBARI_METRICS',
  263. currentTimeRangeIndex: 5,
  264. isServiceMetricLoaded: true,
  265. graphIds: [
  266. [
  267. 'service-metrics-ambari-metrics-master-average-load',
  268. 'service-metrics-ambari-metrics-region-server-store-files',
  269. 'service-metrics-ambari-metrics-region-server-regions',
  270. 'service-metrics-ambari-metrics-region-server-requests',
  271. 'service-metrics-ambari-metrics-region-server-block-cache-hit-percent'
  272. ],
  273. [
  274. 'service-metrics-ambari-metrics-region-server-compaction-queue-size'
  275. ]
  276. ]
  277. },
  278. {
  279. event: {
  280. context: {
  281. index: 6
  282. }
  283. },
  284. serviceName: 'FLUME',
  285. currentTimeRangeIndex: 6,
  286. isServiceMetricLoaded: true,
  287. graphIds: [
  288. [
  289. 'service-metrics-flume-channel-size-mma', 'service-metrics-flume-channel-size-sum',
  290. 'service-metrics-flume-incoming_mma', 'service-metrics-flume-incoming_sum',
  291. 'service-metrics-flume-outgoing_mma'
  292. ],
  293. [
  294. 'service-metrics-flume-outgoing_sum'
  295. ]
  296. ]
  297. },
  298. {
  299. event: {
  300. context: {
  301. index: 7
  302. }
  303. },
  304. serviceName: 'STORM',
  305. currentTimeRangeIndex: 7,
  306. isServiceMetricLoaded: true,
  307. graphIds: [
  308. [
  309. 'service-metrics-storm-supervisor-allocated', 'service-metrics-storm-executors',
  310. 'service-metrics-storm-topologies', 'service-metrics-storm-tasks'
  311. ]
  312. ]
  313. },
  314. {
  315. event: {
  316. context: {
  317. index: 8
  318. }
  319. },
  320. serviceName: 'KAFKA',
  321. chunkSize: 4,
  322. currentTimeRangeIndex: 8,
  323. isServiceMetricLoaded: true,
  324. graphIds: [
  325. [
  326. 'service-metrics-kafka-broker-topic-metrics', 'service-metrics-kafka-controller-metrics',
  327. 'service-metrics-kafka-controler-status-metrics', 'service-metrics-kafka-replica-manager-metrics'
  328. ],
  329. [
  330. 'service-metrics-kafka-log-metrics', 'service-metrics-kafka-replica-fetcher-metrics'
  331. ]
  332. ]
  333. }
  334. ];
  335. beforeEach(function () {
  336. sinon.stub(view, 'postUserPref', Em.K);
  337. view.setProperties({
  338. chunkSize: 5,
  339. currentTimeRangeIndex: 0,
  340. isServiceMetricLoaded: false,
  341. serviceMetricGraphs: []
  342. });
  343. });
  344. afterEach(function () {
  345. view.postUserPref.restore();
  346. });
  347. cases.forEach(function (item) {
  348. it(item.serviceName || item.title, function () {
  349. view.set('chunkSize', Em.isNone(item.chunkSize) ? 5 : item.chunkSize);
  350. view.set('service.serviceName', item.serviceName);
  351. view.setTimeRange(item.event);
  352. var graphIndices = [],
  353. graphIds = view.get('serviceMetricGraphs').map(function (graphs) {
  354. return graphs.map(function (graph) {
  355. var graphView = graph.create();
  356. graphIndices.push(graphView.get('currentTimeIndex'));
  357. return graphView.get('id');
  358. });
  359. });
  360. expect(view.get('currentTimeRangeIndex')).to.equal(item.currentTimeRangeIndex);
  361. expect(view.get('isServiceMetricLoaded')).to.equal(item.isServiceMetricLoaded);
  362. if (item.event && item.event.context && item.serviceName) {
  363. expect(graphIndices.uniq()).to.eql([item.currentTimeRangeIndex]);
  364. }
  365. expect(graphIds).to.eql(item.graphIds);
  366. });
  367. });
  368. });
  369. describe("#restartAllStaleConfigComponents", function () {
  370. it("trigger restartAllServiceHostComponents", function () {
  371. var view = App.MainServiceInfoSummaryView.create({
  372. controller: Em.Object.create({
  373. content: {
  374. serviceName: "HDFS"
  375. },
  376. getActiveWidgetLayout: Em.K
  377. }),
  378. service: Em.Object.create({
  379. displayName: 'HDFS'
  380. })
  381. });
  382. sinon.stub(batchUtils, "restartAllServiceHostComponents", Em.K);
  383. view.restartAllStaleConfigComponents().onPrimary();
  384. expect(batchUtils.restartAllServiceHostComponents.calledOnce).to.equal(true);
  385. batchUtils.restartAllServiceHostComponents.restore();
  386. });
  387. it("trigger check last check point warning before triggering restartAllServiceHostComponents", function () {
  388. var view = App.MainServiceInfoSummaryView.create({
  389. controller: Em.Object.create({
  390. content: {
  391. serviceName: "HDFS",
  392. hostComponents: [{
  393. componentName: 'NAMENODE',
  394. workStatus: 'STARTED'
  395. }],
  396. restartRequiredHostsAndComponents: {
  397. "host1": ['NameNode'],
  398. "host2": ['DataNode', 'ZooKeeper']
  399. }
  400. },
  401. getActiveWidgetLayout: Em.K
  402. }),
  403. service: Em.Object.create({
  404. displayName: 'HDFS'
  405. })
  406. });
  407. var mainServiceItemController = App.MainServiceItemController.create({});
  408. sinon.stub(mainServiceItemController, 'checkNnLastCheckpointTime', function() {
  409. return true;
  410. });
  411. sinon.stub(App.router, 'get', function(k) {
  412. if ('mainServiceItemController' === k) {
  413. return mainServiceItemController;
  414. }
  415. return Em.get(App.router, k);
  416. });
  417. view.restartAllStaleConfigComponents();
  418. expect(mainServiceItemController.checkNnLastCheckpointTime.calledOnce).to.equal(true);
  419. mainServiceItemController.checkNnLastCheckpointTime.restore();
  420. App.router.get.restore();
  421. });
  422. });
  423. });