background_operations_test.js 17 KB

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