background_operations_test.js 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663
  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('config');
  20. require('utils/updater');
  21. require('utils/ajax/ajax');
  22. require('models/host_component');
  23. require('controllers/global/background_operations_controller');
  24. require('views/common/modal_popup');
  25. require('utils/host_progress_popup');
  26. describe('App.BackgroundOperationsController', function () {
  27. var controller = App.BackgroundOperationsController.create({
  28. isInitLoading: Em.K
  29. });
  30. describe('#getQueryParams', function () {
  31. /**
  32. * Predefined data
  33. *
  34. */
  35. App.set('clusterName', 'testName');
  36. App.bgOperationsUpdateInterval = 100;
  37. var tests = Em.A([
  38. {
  39. levelInfo: Em.Object.create({
  40. name: 'REQUESTS_LIST',
  41. requestId: null,
  42. taskId: null,
  43. sync: false
  44. }),
  45. e: {
  46. name: 'background_operations.get_most_recent',
  47. successCallback: 'callBackForMostRecent',
  48. data: {
  49. 'operationsCount': 10
  50. }
  51. },
  52. response: {items: []},
  53. m: '"Get Most Recent"'
  54. },
  55. {
  56. levelInfo: Em.Object.create({
  57. name: 'TASK_DETAILS',
  58. requestId: 1,
  59. taskId: 1
  60. }),
  61. e: {
  62. name: 'background_operations.get_by_task',
  63. successCallback: 'callBackFilteredByTask',
  64. data: {
  65. taskId: 1,
  66. requestId: 1
  67. }
  68. },
  69. response: {items: {Tasks: {request_id: 0}}},
  70. m: '"Filtered By task"'
  71. },
  72. {
  73. levelInfo: Em.Object.create({
  74. name: 'TASKS_LIST',
  75. requestId: 1,
  76. taskId: 1
  77. }),
  78. e: {
  79. name: 'background_operations.get_by_request',
  80. successCallback: 'callBackFilteredByRequest',
  81. data: {
  82. requestId: 1
  83. }
  84. },
  85. response: {items: {Requests: {id: 0}}},
  86. m: '"Filtered By Request (TASKS_LIST)"'
  87. },
  88. {
  89. levelInfo: Em.Object.create({
  90. name: 'HOSTS_LIST',
  91. requestId: 1,
  92. taskId: 1
  93. }),
  94. e: {
  95. name: 'background_operations.get_by_request',
  96. successCallback: 'callBackFilteredByRequest',
  97. data: {
  98. requestId: 1
  99. }
  100. },
  101. response: {items: {Requests: {id: 0}}},
  102. m: '"Filtered By Request (HOSTS_LIST)"'
  103. }
  104. ]);
  105. beforeEach(function () {
  106. App.testMode = false;
  107. });
  108. afterEach(function () {
  109. App.testMode = true;
  110. });
  111. tests.forEach(function (test) {
  112. it(test.m, function () {
  113. controller.set('levelInfo', test.levelInfo);
  114. var r = controller.getQueryParams();
  115. expect(r.name).to.equal(test.e.name);
  116. expect(r.successCallback).to.equal(test.e.successCallback);
  117. expect(r.data).to.eql(test.e.data);
  118. });
  119. });
  120. });
  121. describe('#startPolling()', function () {
  122. beforeEach(function () {
  123. sinon.spy(App.updater, 'run');
  124. sinon.spy(controller, 'requestMostRecent');
  125. });
  126. afterEach(function () {
  127. App.updater.run.restore();
  128. controller.requestMostRecent.restore();
  129. });
  130. it('isWorking = false', function () {
  131. controller.set('isWorking', false);
  132. expect(App.updater.run.calledOnce).to.equal(false);
  133. expect(controller.requestMostRecent.calledOnce).to.equal(false);
  134. });
  135. it('isWorking = true', function () {
  136. controller.set('isWorking', true);
  137. expect(App.updater.run.calledOnce).to.equal(true);
  138. expect(controller.requestMostRecent.calledOnce).to.equal(true);
  139. });
  140. });
  141. describe('#callBackForMostRecent()', function () {
  142. it('No requests exists', function () {
  143. var data = {
  144. items: []
  145. };
  146. controller.callBackForMostRecent(data);
  147. expect(controller.get("allOperationsCount")).to.equal(0);
  148. expect(controller.get("services.length")).to.equal(0);
  149. });
  150. it('One non-running request', function () {
  151. var data = {
  152. items: [
  153. {
  154. Requests: {
  155. id: 1,
  156. request_context: '',
  157. task_count: 0,
  158. aborted_task_count: 0,
  159. completed_task_count: 0,
  160. failed_task_count: 0,
  161. timed_out_task_count: 0,
  162. queued_task_count: 0
  163. }
  164. }
  165. ]
  166. };
  167. controller.callBackForMostRecent(data);
  168. expect(controller.get("allOperationsCount")).to.equal(0);
  169. expect(controller.get("services").mapProperty('id')).to.eql([1]);
  170. });
  171. it('One running request', function () {
  172. var data = {
  173. items: [
  174. {
  175. Requests: {
  176. id: 1,
  177. request_context: '',
  178. task_count: 1,
  179. aborted_task_count: 0,
  180. completed_task_count: 0,
  181. failed_task_count: 0,
  182. timed_out_task_count: 0,
  183. queued_task_count: 0
  184. }
  185. }
  186. ]
  187. };
  188. controller.callBackForMostRecent(data);
  189. expect(controller.get("allOperationsCount")).to.equal(1);
  190. expect(controller.get("services").mapProperty('id')).to.eql([1]);
  191. });
  192. it('Two requests in order', function () {
  193. var data = {
  194. items: [
  195. {
  196. Requests: {
  197. id: 1,
  198. request_context: ''
  199. }
  200. },
  201. {
  202. Requests: {
  203. id: 2,
  204. request_context: ''
  205. }
  206. }
  207. ]
  208. };
  209. controller.callBackForMostRecent(data);
  210. expect(controller.get("allOperationsCount")).to.equal(0);
  211. expect(controller.get("services").mapProperty('id')).to.eql([2, 1]);
  212. });
  213. });
  214. describe('#removeOldRequests()', function () {
  215. var testCases = [
  216. {
  217. title: 'No requests exist',
  218. content: {
  219. currentRequestIds: [],
  220. services: []
  221. },
  222. result: []
  223. },
  224. {
  225. title: 'One current request',
  226. content: {
  227. currentRequestIds: [1],
  228. services: [
  229. {id: 1}
  230. ]
  231. },
  232. result: [
  233. {id: 1}
  234. ]
  235. },
  236. {
  237. title: 'One old request',
  238. content: {
  239. currentRequestIds: [2],
  240. services: [
  241. {id: 1}
  242. ]
  243. },
  244. result: []
  245. },
  246. {
  247. title: 'One old request and one is current',
  248. content: {
  249. currentRequestIds: [2],
  250. services: [
  251. {id: 1},
  252. {id: 2}
  253. ]
  254. },
  255. result: [
  256. {id: 2}
  257. ]
  258. }
  259. ];
  260. testCases.forEach(function (test) {
  261. it(test.title, function () {
  262. controller.set('services', test.content.services);
  263. controller.removeOldRequests(test.content.currentRequestIds);
  264. expect(controller.get('services')).to.eql(test.result);
  265. });
  266. });
  267. });
  268. describe('#isRequestRunning()', function () {
  269. var testCases = [
  270. {
  271. title: 'Counters are missing',
  272. request: {
  273. Requests: {}
  274. },
  275. result: false
  276. },
  277. {
  278. title: 'Request has zero tasks',
  279. request: {
  280. Requests: {
  281. task_count: 0,
  282. aborted_task_count: 0,
  283. completed_task_count: 0,
  284. failed_task_count: 0,
  285. timed_out_task_count: 0,
  286. queued_task_count: 0
  287. }
  288. },
  289. result: false
  290. },
  291. {
  292. title: 'One task in running status',
  293. request: {
  294. Requests: {
  295. task_count: 1,
  296. aborted_task_count: 0,
  297. completed_task_count: 0,
  298. failed_task_count: 0,
  299. timed_out_task_count: 0,
  300. queued_task_count: 0
  301. }
  302. },
  303. result: true
  304. },
  305. {
  306. title: 'One task in queued status',
  307. request: {
  308. Requests: {
  309. task_count: 1,
  310. aborted_task_count: 0,
  311. completed_task_count: 0,
  312. failed_task_count: 0,
  313. timed_out_task_count: 0,
  314. queued_task_count: 1
  315. }
  316. },
  317. result: true
  318. },
  319. {
  320. title: 'One task in aborted status',
  321. request: {
  322. Requests: {
  323. task_count: 1,
  324. aborted_task_count: 1,
  325. completed_task_count: 0,
  326. failed_task_count: 0,
  327. timed_out_task_count: 0,
  328. queued_task_count: 0
  329. }
  330. },
  331. result: false
  332. },
  333. {
  334. title: 'One task in completed status',
  335. request: {
  336. Requests: {
  337. task_count: 1,
  338. aborted_task_count: 0,
  339. completed_task_count: 1,
  340. failed_task_count: 0,
  341. timed_out_task_count: 0,
  342. queued_task_count: 0
  343. }
  344. },
  345. result: false
  346. },
  347. {
  348. title: 'One task in failed status',
  349. request: {
  350. Requests: {
  351. task_count: 1,
  352. aborted_task_count: 0,
  353. completed_task_count: 0,
  354. failed_task_count: 1,
  355. timed_out_task_count: 0,
  356. queued_task_count: 0
  357. }
  358. },
  359. result: false
  360. },
  361. {
  362. title: 'One task in timed out status',
  363. request: {
  364. Requests: {
  365. task_count: 1,
  366. aborted_task_count: 0,
  367. completed_task_count: 0,
  368. failed_task_count: 0,
  369. timed_out_task_count: 1,
  370. queued_task_count: 0
  371. }
  372. },
  373. result: false
  374. },
  375. {
  376. title: 'One task in timed out status and the second one in running',
  377. request: {
  378. Requests: {
  379. task_count: 2,
  380. aborted_task_count: 0,
  381. completed_task_count: 0,
  382. failed_task_count: 0,
  383. timed_out_task_count: 1,
  384. queued_task_count: 0
  385. }
  386. },
  387. result: true
  388. },
  389. {
  390. title: 'One task in each status',
  391. request: {
  392. Requests: {
  393. task_count: 5,
  394. aborted_task_count: 1,
  395. completed_task_count: 1,
  396. failed_task_count: 1,
  397. timed_out_task_count: 1,
  398. queued_task_count: 1
  399. }
  400. },
  401. result: true
  402. },
  403. {
  404. title: 'One task in each status except queued',
  405. request: {
  406. Requests: {
  407. task_count: 5,
  408. aborted_task_count: 1,
  409. completed_task_count: 1,
  410. failed_task_count: 1,
  411. timed_out_task_count: 1,
  412. queued_task_count: 0
  413. }
  414. },
  415. result: true
  416. },
  417. {
  418. title: 'No tasks in running status',
  419. request: {
  420. Requests: {
  421. task_count: 4,
  422. aborted_task_count: 1,
  423. completed_task_count: 1,
  424. failed_task_count: 1,
  425. timed_out_task_count: 1,
  426. queued_task_count: 0
  427. }
  428. },
  429. result: false
  430. }
  431. ];
  432. testCases.forEach(function (test) {
  433. it(test.title, function () {
  434. expect(controller.isRequestRunning(test.request)).to.eql(test.result);
  435. });
  436. });
  437. });
  438. describe('#isOneHost()', function () {
  439. var testCases = [
  440. {
  441. title: 'inputs is null',
  442. inputs: null,
  443. result: false
  444. },
  445. {
  446. title: 'inputs is "null"',
  447. inputs: 'null',
  448. result: false
  449. },
  450. {
  451. title: 'inputs is empty object',
  452. inputs: '{}',
  453. result: false
  454. },
  455. {
  456. title: 'included_hosts is empty',
  457. inputs: '{"included_hosts": ""}',
  458. result: false
  459. },
  460. {
  461. title: 'included_hosts contain one host',
  462. inputs: '{"included_hosts": "host1"}',
  463. result: true
  464. },
  465. {
  466. title: 'included_hosts contain two hosts',
  467. inputs: '{"included_hosts": "host1,host2"}',
  468. result: false
  469. }
  470. ];
  471. testCases.forEach(function (test) {
  472. it(test.title, function () {
  473. expect(controller.isOneHost(test.inputs)).to.eql(test.result);
  474. });
  475. });
  476. });
  477. describe('#assignScheduleId()', function () {
  478. var testCases = [
  479. {
  480. title: 'isOneHost is false',
  481. content: {
  482. request: {
  483. Requests: {
  484. request_schedule: {
  485. schedule_id: 1
  486. },
  487. inputs: null
  488. }
  489. },
  490. requestParams: ''
  491. },
  492. result: 1
  493. },
  494. {
  495. title: 'isOneHost is true and requestContext is empty',
  496. content: {
  497. request: {
  498. Requests: {
  499. request_schedule: {
  500. schedule_id: 1
  501. },
  502. inputs: '{"included_hosts": "host1"}'
  503. }
  504. },
  505. requestParams: {
  506. requestContext: ''
  507. }
  508. },
  509. result: 1
  510. },
  511. {
  512. title: 'isOneHost is true and requestContext contains "Recommission"',
  513. content: {
  514. request: {
  515. Requests: {
  516. request_schedule: {
  517. schedule_id: 1
  518. },
  519. inputs: '{"included_hosts": "host1"}'
  520. }
  521. },
  522. requestParams: {
  523. requestContext: 'Recommission'
  524. }
  525. },
  526. result: null
  527. }
  528. ];
  529. testCases.forEach(function (test) {
  530. it(test.title, function () {
  531. controller.assignScheduleId(test.content.request, test.content.requestParams);
  532. expect(test.content.request.Requests.request_schedule.schedule_id).to.equal(test.result);
  533. });
  534. });
  535. });
  536. describe('#callBackFilteredByRequest()', function () {
  537. it('request haven\'t tasks and isRunning false', function () {
  538. var data = {
  539. Requests: {id: 1},
  540. tasks: []
  541. };
  542. var request = Em.Object.create({
  543. id: 1,
  544. previousTaskStatusMap: {},
  545. isRunning: false,
  546. progress: 0,
  547. status:''
  548. });
  549. controller.set('services', [request]);
  550. controller.callBackFilteredByRequest(data);
  551. expect(request.get('previousTaskStatusMap')).to.eql({});
  552. expect(request.get('hostsMap')).to.eql({});
  553. expect(request.get('isRunning')).to.equal(false);
  554. });
  555. it('request haven\'t tasks and isRunning true', function () {
  556. var data = {
  557. Requests: {id: 1},
  558. tasks: []
  559. };
  560. var request = Em.Object.create({
  561. id: 1,
  562. previousTaskStatusMap: {},
  563. isRunning: true,
  564. progress: 0,
  565. status:''
  566. });
  567. controller.set('services', [request]);
  568. controller.callBackFilteredByRequest(data);
  569. expect(request.get('previousTaskStatusMap')).to.eql({});
  570. expect(request.get('hostsMap')).to.eql({});
  571. expect(request.get('isRunning')).to.equal(true);
  572. });
  573. it('request has one completed task', function () {
  574. var data = {
  575. Requests: {id: 1},
  576. tasks: [
  577. {
  578. Tasks: {
  579. id: 1,
  580. host_name: 'host1',
  581. status: 'COMPLETED'
  582. }
  583. }
  584. ]
  585. };
  586. var request = Em.Object.create({
  587. id: 1,
  588. previousTaskStatusMap: {},
  589. isRunning: true,
  590. progress: 100,
  591. status:''
  592. });
  593. controller.set('services', [request]);
  594. controller.callBackFilteredByRequest(data);
  595. expect(request.get('previousTaskStatusMap')).to.eql({"1": "COMPLETED"});
  596. expect(request.get('hostsMap')['host1'].logTasks.length).to.equal(1);
  597. expect(request.get('isRunning')).to.equal(false);
  598. });
  599. it('request has one completed task and one running task', function () {
  600. var data = {
  601. Requests: {id: 1},
  602. tasks: [
  603. {
  604. Tasks: {
  605. id: 1,
  606. host_name: 'host1',
  607. status: 'COMPLETED'
  608. }
  609. },
  610. {
  611. Tasks: {
  612. id: 2,
  613. host_name: 'host1',
  614. status: 'IN_PROGRESS'
  615. }
  616. }
  617. ]
  618. };
  619. var request = Em.Object.create({
  620. id: 1,
  621. previousTaskStatusMap: {},
  622. isRunning: true,
  623. progress: 100,
  624. status:''
  625. });
  626. controller.set('services', [request]);
  627. controller.callBackFilteredByRequest(data);
  628. expect(request.get('previousTaskStatusMap')).to.eql({"1": "COMPLETED", "2": "IN_PROGRESS"});
  629. expect(request.get('hostsMap')['host1'].logTasks.length).to.equal(2);
  630. expect(request.get('isRunning')).to.equal(true);
  631. });
  632. });
  633. });