summary_test.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527
  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. describe('if one server exists then first server should have isComma and isAnd property false', function () {
  44. beforeEach(function () {
  45. view.set('controller.content', Em.Object.create({
  46. id: 'ZOOKEEPER',
  47. serviceName: 'ZOOKEEPER',
  48. hostComponents: [
  49. Em.Object.create({
  50. displayName: '',
  51. isMaster: true
  52. })
  53. ]
  54. }));
  55. });
  56. it('isComma', function () {
  57. expect(view.get('servers').objectAt(0).isComma).to.equal(false);});
  58. it('isAnd', function () {
  59. expect(view.get('servers').objectAt(0).isAnd).to.equal(false);
  60. });
  61. });
  62. describe('if more than one servers exist then first server should have isComma - true and isAnd - false', function() {
  63. beforeEach(function () {
  64. view.set('controller.content', Em.Object.create({
  65. id: 'ZOOKEEPER',
  66. serviceName: 'ZOOKEEPER',
  67. hostComponents: [
  68. Em.Object.create({
  69. displayName: '',
  70. isMaster: true
  71. }),
  72. Em.Object.create({
  73. displayName: '',
  74. isMaster: true
  75. })
  76. ]
  77. }));
  78. });
  79. it('0 isComma', function () {
  80. expect(view.get('servers').objectAt(0).isComma).to.equal(true);
  81. });
  82. it('0 isAnd', function () {
  83. expect(view.get('servers').objectAt(0).isAnd).to.equal(false);
  84. });
  85. it('1 isComma', function () {
  86. expect(view.get('servers').objectAt(1).isComma).to.equal(false);
  87. });
  88. it('1 isAnd', function () {
  89. expect(view.get('servers').objectAt(1).isAnd).to.equal(false);
  90. });
  91. });
  92. describe('if more than two servers exist then second server should have isComma - false and isAnd - true', function () {
  93. beforeEach(function () {
  94. view.set('controller.content', Em.Object.create({
  95. id: 'ZOOKEEPER',
  96. serviceName: 'ZOOKEEPER',
  97. hostComponents: [
  98. Em.Object.create({
  99. displayName: '',
  100. isMaster: true
  101. }),
  102. Em.Object.create({
  103. displayName: '',
  104. isMaster: true
  105. }),
  106. Em.Object.create({
  107. displayName: '',
  108. isMaster: true
  109. })
  110. ]
  111. }));
  112. });
  113. it('0 isComma', function () {
  114. expect(view.get('servers').objectAt(0).isComma).to.equal(true);
  115. });
  116. it('0 isAnd', function () {
  117. expect(view.get('servers').objectAt(0).isAnd).to.equal(false);
  118. });
  119. it('1 isComma', function () {
  120. expect(view.get('servers').objectAt(1).isComma).to.equal(false);
  121. });
  122. it('1 isAnd', function () {
  123. expect(view.get('servers').objectAt(1).isAnd).to.equal(true);
  124. });
  125. it('2 isComma', function () {
  126. expect(view.get('servers').objectAt(2).isComma).to.equal(false);
  127. });
  128. it('2 isAnd', function () {
  129. expect(view.get('servers').objectAt(2).isAnd).to.equal(false);
  130. });
  131. });
  132. });
  133. describe('#hasAlertDefinitions', function () {
  134. beforeEach(function () {
  135. sinon.stub(App.AlertDefinition, 'find', function () {
  136. return [
  137. {
  138. serviceName: 'HDFS'
  139. },
  140. {
  141. serviceName: 'YARN'
  142. }
  143. ];
  144. });
  145. });
  146. afterEach(function () {
  147. App.AlertDefinition.find.restore();
  148. });
  149. it('should return true if at least one alert definition for this service exists', function () {
  150. view.set('controller.content', Em.Object.create({
  151. serviceName: 'HDFS'
  152. }));
  153. expect(view.get('hasAlertDefinitions')).to.be.true;
  154. it('should return false if there is no alert definition for this service', function () {
  155. view.set('controller.content', Em.Object.create({
  156. serviceName: 'ZOOKEEPER'
  157. }));
  158. expect(view.get('hasAlertDefinitions')).to.be.false;
  159. });
  160. })
  161. });
  162. describe('#didInsertElement', function () {
  163. var cases = [
  164. {
  165. serviceName: 'STORM',
  166. isStormMetricsSupported: false,
  167. isConstructGraphObjectsCalled: false,
  168. title: 'Storm, metrics not supported'
  169. },
  170. {
  171. serviceName: 'STORM',
  172. isStormMetricsSupported: true,
  173. isConstructGraphObjectsCalled: true,
  174. title: 'Storm, metrics supported'
  175. },
  176. {
  177. serviceName: 'HDFS',
  178. isConstructGraphObjectsCalled: true,
  179. title: 'not Storm'
  180. }
  181. ];
  182. beforeEach(function () {
  183. sinon.stub(view, 'constructGraphObjects', Em.K);
  184. this.mock = sinon.stub(App, 'get');
  185. });
  186. afterEach(function () {
  187. view.constructGraphObjects.restore();
  188. this.mock.restore();
  189. });
  190. cases.forEach(function (item) {
  191. it(item.title, function () {
  192. view.set('controller.content.serviceName', item.serviceName);
  193. this.mock.withArgs('isStormMetricsSupported').returns(item.isStormMetricsSupported);
  194. view.didInsertElement();
  195. expect(view.constructGraphObjects.calledOnce).to.equal(item.isConstructGraphObjectsCalled);
  196. });
  197. });
  198. });
  199. describe.skip('#setTimeRange', function () {
  200. var cases = [
  201. {
  202. currentTimeRangeIndex: 0,
  203. isServiceMetricLoaded: false,
  204. graphIds: [],
  205. title: 'no event passed'
  206. },
  207. {
  208. event: {},
  209. currentTimeRangeIndex: 0,
  210. isServiceMetricLoaded: false,
  211. graphIds: [],
  212. title: 'no event context passed'
  213. },
  214. {
  215. event: {
  216. context: {
  217. index: 1
  218. }
  219. },
  220. currentTimeRangeIndex: 1,
  221. isServiceMetricLoaded: false,
  222. graphIds: [],
  223. title: 'no service name set'
  224. },
  225. {
  226. event: {
  227. context: {
  228. index: 2
  229. }
  230. },
  231. serviceName: 'HDFS',
  232. currentTimeRangeIndex: 2,
  233. isServiceMetricLoaded: true,
  234. graphIds: [
  235. [
  236. 'service-metrics-hdfs-space-utilization', 'service-metrics-hdfs-file-operations',
  237. 'service-metrics-hdfs-block-status', 'service-metrics-hdfs-io', 'service-metrics-hdfs-rpc'
  238. ],
  239. [
  240. 'service-metrics-hdfs-gc', 'service-metrics-hdfs-jvm-heap', 'service-metrics-hdfs-jvm-threads'
  241. ]
  242. ]
  243. },
  244. {
  245. event: {
  246. context: {
  247. index: 3
  248. }
  249. },
  250. serviceName: 'YARN',
  251. currentTimeRangeIndex: 3,
  252. isServiceMetricLoaded: true,
  253. graphIds: [
  254. [
  255. 'service-metrics-yarn-queue-allocated', 'service-metrics-yarn-queue-memory-resource',
  256. 'service-metrics-yarn-queue-allocated-container', 'service-metrics-yarn-node-manager-statuses',
  257. 'service-metrics-yarn-apps-current-states'
  258. ],
  259. [
  260. 'service-metrics-yarn-apps-finished-states', 'service-metrics-yarn-rpc', 'service-metrics-yarn-gc',
  261. 'service-metrics-yarn-jvm-threads', 'service-metrics-yarn-jvm-heap'
  262. ]
  263. ]
  264. },
  265. {
  266. event: {
  267. context: {
  268. index: 4
  269. }
  270. },
  271. serviceName: 'HBASE',
  272. currentTimeRangeIndex: 4,
  273. isServiceMetricLoaded: true,
  274. graphIds: [
  275. [
  276. 'service-metrics-hbase-cluster-requests', 'service-metrics-hbase-regionserver-rw-requests',
  277. 'service-metrics-hbase-regionserver-regions', 'service-metrics-hbase-regionserver-queuesize',
  278. 'service-metrics-hbase-hlog-split-time'
  279. ],
  280. [
  281. 'service-metrics-hbase-hlog-split-size'
  282. ]
  283. ]
  284. },
  285. {
  286. event: {
  287. context: {
  288. index: 5
  289. }
  290. },
  291. serviceName: 'AMBARI_METRICS',
  292. currentTimeRangeIndex: 5,
  293. isServiceMetricLoaded: true,
  294. graphIds: [
  295. [
  296. 'service-metrics-ambari-metrics-master-average-load',
  297. 'service-metrics-ambari-metrics-region-server-store-files',
  298. 'service-metrics-ambari-metrics-region-server-regions',
  299. 'service-metrics-ambari-metrics-region-server-requests',
  300. 'service-metrics-ambari-metrics-region-server-block-cache-hit-percent'
  301. ],
  302. [
  303. 'service-metrics-ambari-metrics-region-server-compaction-queue-size'
  304. ]
  305. ]
  306. },
  307. {
  308. event: {
  309. context: {
  310. index: 6
  311. }
  312. },
  313. serviceName: 'FLUME',
  314. currentTimeRangeIndex: 6,
  315. isServiceMetricLoaded: true,
  316. graphIds: [
  317. [
  318. 'service-metrics-flume-channel-size-mma', 'service-metrics-flume-channel-size-sum',
  319. 'service-metrics-flume-incoming_mma', 'service-metrics-flume-incoming_sum',
  320. 'service-metrics-flume-outgoing_mma'
  321. ],
  322. [
  323. 'service-metrics-flume-outgoing_sum'
  324. ]
  325. ]
  326. },
  327. {
  328. event: {
  329. context: {
  330. index: 7
  331. }
  332. },
  333. serviceName: 'STORM',
  334. currentTimeRangeIndex: 7,
  335. isServiceMetricLoaded: true,
  336. graphIds: [
  337. [
  338. 'service-metrics-storm-supervisor-allocated', 'service-metrics-storm-executors',
  339. 'service-metrics-storm-topologies', 'service-metrics-storm-tasks'
  340. ]
  341. ]
  342. },
  343. {
  344. event: {
  345. context: {
  346. index: 8
  347. }
  348. },
  349. serviceName: 'KAFKA',
  350. chunkSize: 4,
  351. currentTimeRangeIndex: 8,
  352. isServiceMetricLoaded: true,
  353. graphIds: [
  354. [
  355. 'service-metrics-kafka-broker-topic-metrics', 'service-metrics-kafka-controller-metrics',
  356. 'service-metrics-kafka-controler-status-metrics', 'service-metrics-kafka-replica-manager-metrics'
  357. ],
  358. [
  359. 'service-metrics-kafka-log-metrics', 'service-metrics-kafka-replica-fetcher-metrics'
  360. ]
  361. ]
  362. }
  363. ];
  364. beforeEach(function () {
  365. sinon.stub(view, 'postUserPref', Em.K);
  366. view.setProperties({
  367. chunkSize: 5,
  368. currentTimeRangeIndex: 0,
  369. isServiceMetricLoaded: false,
  370. serviceMetricGraphs: []
  371. });
  372. });
  373. afterEach(function () {
  374. view.postUserPref.restore();
  375. });
  376. cases.forEach(function (item) {
  377. it(item.serviceName || item.title, function () {
  378. view.set('chunkSize', Em.isNone(item.chunkSize) ? 5 : item.chunkSize);
  379. view.set('service.serviceName', item.serviceName);
  380. view.setTimeRange(item.event);
  381. var graphIndices = [],
  382. graphIds = view.get('serviceMetricGraphs').map(function (graphs) {
  383. return graphs.map(function (graph) {
  384. var graphView = graph.create();
  385. graphIndices.push(graphView.get('currentTimeIndex'));
  386. return graphView.get('id');
  387. });
  388. });
  389. expect(view.get('currentTimeRangeIndex')).to.equal(item.currentTimeRangeIndex);
  390. expect(view.get('isServiceMetricLoaded')).to.equal(item.isServiceMetricLoaded);
  391. if (item.event && item.event.context && item.serviceName) {
  392. expect(graphIndices.uniq()).to.eql([item.currentTimeRangeIndex]);
  393. }
  394. expect(graphIds).to.eql(item.graphIds);
  395. });
  396. });
  397. });
  398. describe("#restartAllStaleConfigComponents", function () {
  399. describe('trigger restartAllServiceHostComponents', function () {
  400. var view;
  401. beforeEach(function () {
  402. view = App.MainServiceInfoSummaryView.create({
  403. controller: Em.Object.create({
  404. content: {
  405. serviceName: "HDFS"
  406. },
  407. getActiveWidgetLayout: Em.K
  408. }),
  409. service: Em.Object.create({
  410. displayName: 'HDFS'
  411. })
  412. });
  413. sinon.stub(batchUtils, "restartAllServiceHostComponents", Em.K);
  414. });
  415. afterEach(function () {
  416. batchUtils.restartAllServiceHostComponents.restore();
  417. });
  418. it('batch request is started', function () {
  419. view.restartAllStaleConfigComponents().onPrimary();
  420. expect(batchUtils.restartAllServiceHostComponents.calledOnce).to.equal(true);
  421. });
  422. });
  423. describe('trigger check last check point warning before triggering restartAllServiceHostComponents', function () {
  424. var view;
  425. var mainServiceItemController;
  426. beforeEach(function () {
  427. view = App.MainServiceInfoSummaryView.create({
  428. controller: Em.Object.create({
  429. content: {
  430. serviceName: "HDFS",
  431. hostComponents: [{
  432. componentName: 'NAMENODE',
  433. workStatus: 'STARTED'
  434. }],
  435. restartRequiredHostsAndComponents: {
  436. "host1": ['NameNode'],
  437. "host2": ['DataNode', 'ZooKeeper']
  438. }
  439. },
  440. getActiveWidgetLayout: Em.K
  441. }),
  442. service: Em.Object.create({
  443. displayName: 'HDFS'
  444. })
  445. });
  446. mainServiceItemController = App.MainServiceItemController.create({});
  447. sinon.stub(mainServiceItemController, 'checkNnLastCheckpointTime', function() {
  448. return true;
  449. });
  450. sinon.stub(App.router, 'get', function(k) {
  451. if ('mainServiceItemController' === k) {
  452. return mainServiceItemController;
  453. }
  454. return Em.get(App.router, k);
  455. });
  456. });
  457. afterEach(function () {
  458. mainServiceItemController.checkNnLastCheckpointTime.restore();
  459. App.router.get.restore();
  460. });
  461. it('NN Last CheckPoint is checked', function () {
  462. view.restartAllStaleConfigComponents();
  463. expect(mainServiceItemController.checkNnLastCheckpointTime.calledOnce).to.equal(true);
  464. });
  465. });
  466. });
  467. });