background_operations_test.js 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697
  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('#isUpgradeRequest', function() {
  142. it('defines if request is upgrade task (true)', function() {
  143. expect(controller.isUpgradeRequest({Requests: {request_context: "upgrading"}})).to.be.true;
  144. });
  145. it('defines if request is upgrade task (true - with uppercase)', function() {
  146. expect(controller.isUpgradeRequest({Requests: {request_context: "UPGRADING"}})).to.be.true;
  147. });
  148. it('defines if request is upgrade task (false)', function() {
  149. expect(controller.isUpgradeRequest({Requests: {request_context: "install"}})).to.be.false;
  150. });
  151. it('defines if request is upgrade task (false - invalid param)', function() {
  152. expect(controller.isUpgradeRequest({Requests: {}})).to.be.false;
  153. });
  154. });
  155. describe('#callBackForMostRecent()', function () {
  156. it('No requests exists', function () {
  157. var data = {
  158. items: []
  159. };
  160. controller.callBackForMostRecent(data);
  161. expect(controller.get("allOperationsCount")).to.equal(0);
  162. expect(controller.get("services.length")).to.equal(0);
  163. });
  164. it('One non-running request', function () {
  165. var data = {
  166. items: [
  167. {
  168. Requests: {
  169. id: 1,
  170. request_context: '',
  171. task_count: 0,
  172. aborted_task_count: 0,
  173. completed_task_count: 0,
  174. failed_task_count: 0,
  175. timed_out_task_count: 0,
  176. queued_task_count: 0
  177. }
  178. }
  179. ]
  180. };
  181. controller.callBackForMostRecent(data);
  182. expect(controller.get("allOperationsCount")).to.equal(0);
  183. expect(controller.get("services").mapProperty('id')).to.eql([1]);
  184. });
  185. it('One request that is excluded', function () {
  186. var data = {
  187. items: [
  188. {
  189. Requests: {
  190. id: 1,
  191. request_context: 'upgrading'
  192. }
  193. }
  194. ]
  195. };
  196. controller.callBackForMostRecent(data);
  197. expect(controller.get("allOperationsCount")).to.equal(0);
  198. expect(controller.get("services").mapProperty('id')).to.eql([]);
  199. });
  200. it('One running request', function () {
  201. var data = {
  202. items: [
  203. {
  204. Requests: {
  205. id: 1,
  206. request_context: '',
  207. task_count: 1,
  208. aborted_task_count: 0,
  209. completed_task_count: 0,
  210. failed_task_count: 0,
  211. timed_out_task_count: 0,
  212. queued_task_count: 0
  213. }
  214. }
  215. ]
  216. };
  217. controller.callBackForMostRecent(data);
  218. expect(controller.get("allOperationsCount")).to.equal(1);
  219. expect(controller.get("services").mapProperty('id')).to.eql([1]);
  220. });
  221. it('Two requests in order', function () {
  222. var data = {
  223. items: [
  224. {
  225. Requests: {
  226. id: 1,
  227. request_context: ''
  228. }
  229. },
  230. {
  231. Requests: {
  232. id: 2,
  233. request_context: ''
  234. }
  235. }
  236. ]
  237. };
  238. controller.callBackForMostRecent(data);
  239. expect(controller.get("allOperationsCount")).to.equal(0);
  240. expect(controller.get("services").mapProperty('id')).to.eql([2, 1]);
  241. });
  242. });
  243. describe('#removeOldRequests()', function () {
  244. var testCases = [
  245. {
  246. title: 'No requests exist',
  247. content: {
  248. currentRequestIds: [],
  249. services: []
  250. },
  251. result: []
  252. },
  253. {
  254. title: 'One current request',
  255. content: {
  256. currentRequestIds: [1],
  257. services: [
  258. {id: 1}
  259. ]
  260. },
  261. result: [
  262. {id: 1}
  263. ]
  264. },
  265. {
  266. title: 'One old request',
  267. content: {
  268. currentRequestIds: [2],
  269. services: [
  270. {id: 1}
  271. ]
  272. },
  273. result: []
  274. },
  275. {
  276. title: 'One old request and one is current',
  277. content: {
  278. currentRequestIds: [2],
  279. services: [
  280. {id: 1},
  281. {id: 2}
  282. ]
  283. },
  284. result: [
  285. {id: 2}
  286. ]
  287. }
  288. ];
  289. testCases.forEach(function (test) {
  290. it(test.title, function () {
  291. controller.set('services', test.content.services);
  292. controller.removeOldRequests(test.content.currentRequestIds);
  293. expect(controller.get('services')).to.eql(test.result);
  294. });
  295. });
  296. });
  297. describe('#isRequestRunning()', function () {
  298. var testCases = [
  299. {
  300. title: 'Counters are missing',
  301. request: {
  302. Requests: {}
  303. },
  304. result: false
  305. },
  306. {
  307. title: 'Request has zero tasks',
  308. request: {
  309. Requests: {
  310. task_count: 0,
  311. aborted_task_count: 0,
  312. completed_task_count: 0,
  313. failed_task_count: 0,
  314. timed_out_task_count: 0,
  315. queued_task_count: 0
  316. }
  317. },
  318. result: false
  319. },
  320. {
  321. title: 'One task in running status',
  322. request: {
  323. Requests: {
  324. task_count: 1,
  325. aborted_task_count: 0,
  326. completed_task_count: 0,
  327. failed_task_count: 0,
  328. timed_out_task_count: 0,
  329. queued_task_count: 0
  330. }
  331. },
  332. result: true
  333. },
  334. {
  335. title: 'One task in queued status',
  336. request: {
  337. Requests: {
  338. task_count: 1,
  339. aborted_task_count: 0,
  340. completed_task_count: 0,
  341. failed_task_count: 0,
  342. timed_out_task_count: 0,
  343. queued_task_count: 1
  344. }
  345. },
  346. result: true
  347. },
  348. {
  349. title: 'One task in aborted status',
  350. request: {
  351. Requests: {
  352. task_count: 1,
  353. aborted_task_count: 1,
  354. completed_task_count: 0,
  355. failed_task_count: 0,
  356. timed_out_task_count: 0,
  357. queued_task_count: 0
  358. }
  359. },
  360. result: false
  361. },
  362. {
  363. title: 'One task in completed status',
  364. request: {
  365. Requests: {
  366. task_count: 1,
  367. aborted_task_count: 0,
  368. completed_task_count: 1,
  369. failed_task_count: 0,
  370. timed_out_task_count: 0,
  371. queued_task_count: 0
  372. }
  373. },
  374. result: false
  375. },
  376. {
  377. title: 'One task in failed status',
  378. request: {
  379. Requests: {
  380. task_count: 1,
  381. aborted_task_count: 0,
  382. completed_task_count: 0,
  383. failed_task_count: 1,
  384. timed_out_task_count: 0,
  385. queued_task_count: 0
  386. }
  387. },
  388. result: false
  389. },
  390. {
  391. title: 'One task in timed out status',
  392. request: {
  393. Requests: {
  394. task_count: 1,
  395. aborted_task_count: 0,
  396. completed_task_count: 0,
  397. failed_task_count: 0,
  398. timed_out_task_count: 1,
  399. queued_task_count: 0
  400. }
  401. },
  402. result: false
  403. },
  404. {
  405. title: 'One task in timed out status and the second one in running',
  406. request: {
  407. Requests: {
  408. task_count: 2,
  409. aborted_task_count: 0,
  410. completed_task_count: 0,
  411. failed_task_count: 0,
  412. timed_out_task_count: 1,
  413. queued_task_count: 0
  414. }
  415. },
  416. result: true
  417. },
  418. {
  419. title: 'One task in each status',
  420. request: {
  421. Requests: {
  422. task_count: 5,
  423. aborted_task_count: 1,
  424. completed_task_count: 1,
  425. failed_task_count: 1,
  426. timed_out_task_count: 1,
  427. queued_task_count: 1
  428. }
  429. },
  430. result: true
  431. },
  432. {
  433. title: 'One task in each status except queued',
  434. request: {
  435. Requests: {
  436. task_count: 5,
  437. aborted_task_count: 1,
  438. completed_task_count: 1,
  439. failed_task_count: 1,
  440. timed_out_task_count: 1,
  441. queued_task_count: 0
  442. }
  443. },
  444. result: true
  445. },
  446. {
  447. title: 'No tasks in running status',
  448. request: {
  449. Requests: {
  450. task_count: 4,
  451. aborted_task_count: 1,
  452. completed_task_count: 1,
  453. failed_task_count: 1,
  454. timed_out_task_count: 1,
  455. queued_task_count: 0
  456. }
  457. },
  458. result: false
  459. }
  460. ];
  461. testCases.forEach(function (test) {
  462. it(test.title, function () {
  463. expect(controller.isRequestRunning(test.request)).to.eql(test.result);
  464. });
  465. });
  466. });
  467. describe('#isOneHost()', function () {
  468. var testCases = [
  469. {
  470. title: 'inputs is null',
  471. inputs: null,
  472. result: false
  473. },
  474. {
  475. title: 'inputs is "null"',
  476. inputs: 'null',
  477. result: false
  478. },
  479. {
  480. title: 'inputs is empty object',
  481. inputs: '{}',
  482. result: false
  483. },
  484. {
  485. title: 'included_hosts is empty',
  486. inputs: '{"included_hosts": ""}',
  487. result: false
  488. },
  489. {
  490. title: 'included_hosts contain one host',
  491. inputs: '{"included_hosts": "host1"}',
  492. result: true
  493. },
  494. {
  495. title: 'included_hosts contain two hosts',
  496. inputs: '{"included_hosts": "host1,host2"}',
  497. result: false
  498. }
  499. ];
  500. testCases.forEach(function (test) {
  501. it(test.title, function () {
  502. expect(controller.isOneHost(test.inputs)).to.eql(test.result);
  503. });
  504. });
  505. });
  506. describe('#assignScheduleId()', function () {
  507. var testCases = [
  508. {
  509. title: 'isOneHost is false',
  510. content: {
  511. request: {
  512. Requests: {
  513. request_schedule: {
  514. schedule_id: 1
  515. },
  516. inputs: null
  517. }
  518. },
  519. requestParams: ''
  520. },
  521. result: 1
  522. },
  523. {
  524. title: 'isOneHost is true and requestContext is empty',
  525. content: {
  526. request: {
  527. Requests: {
  528. request_schedule: {
  529. schedule_id: 1
  530. },
  531. inputs: '{"included_hosts": "host1"}'
  532. }
  533. },
  534. requestParams: {
  535. requestContext: ''
  536. }
  537. },
  538. result: 1
  539. },
  540. {
  541. title: 'isOneHost is true and requestContext contains "Recommission"',
  542. content: {
  543. request: {
  544. Requests: {
  545. request_schedule: {
  546. schedule_id: 1
  547. },
  548. inputs: '{"included_hosts": "host1"}'
  549. }
  550. },
  551. requestParams: {
  552. requestContext: 'Recommission'
  553. }
  554. },
  555. result: null
  556. }
  557. ];
  558. testCases.forEach(function (test) {
  559. it(test.title, function () {
  560. controller.assignScheduleId(test.content.request, test.content.requestParams);
  561. expect(test.content.request.Requests.request_schedule.schedule_id).to.equal(test.result);
  562. });
  563. });
  564. });
  565. describe('#callBackFilteredByRequest()', function () {
  566. it('request haven\'t tasks and isRunning false', function () {
  567. var data = {
  568. Requests: {id: 1},
  569. tasks: []
  570. };
  571. var request = Em.Object.create({
  572. id: 1,
  573. previousTaskStatusMap: {},
  574. isRunning: false,
  575. progress: 0,
  576. status:''
  577. });
  578. controller.set('services', [request]);
  579. controller.callBackFilteredByRequest(data);
  580. expect(request.get('previousTaskStatusMap')).to.eql({});
  581. expect(request.get('hostsMap')).to.eql({});
  582. expect(request.get('isRunning')).to.equal(false);
  583. });
  584. it('request haven\'t tasks and isRunning true', function () {
  585. var data = {
  586. Requests: {id: 1},
  587. tasks: []
  588. };
  589. var request = Em.Object.create({
  590. id: 1,
  591. previousTaskStatusMap: {},
  592. isRunning: true,
  593. progress: 0,
  594. status:''
  595. });
  596. controller.set('services', [request]);
  597. controller.callBackFilteredByRequest(data);
  598. expect(request.get('previousTaskStatusMap')).to.eql({});
  599. expect(request.get('hostsMap')).to.eql({});
  600. expect(request.get('isRunning')).to.equal(true);
  601. });
  602. it('request has one completed task', function () {
  603. var data = {
  604. Requests: {id: 1},
  605. tasks: [
  606. {
  607. Tasks: {
  608. id: 1,
  609. host_name: 'host1',
  610. status: 'COMPLETED'
  611. }
  612. }
  613. ]
  614. };
  615. var request = Em.Object.create({
  616. id: 1,
  617. previousTaskStatusMap: {},
  618. isRunning: true,
  619. progress: 100,
  620. status:''
  621. });
  622. controller.set('services', [request]);
  623. controller.callBackFilteredByRequest(data);
  624. expect(request.get('previousTaskStatusMap')).to.eql({"1": "COMPLETED"});
  625. expect(request.get('hostsMap')['host1'].logTasks.length).to.equal(1);
  626. expect(request.get('isRunning')).to.equal(false);
  627. });
  628. it('request has one completed task and one running task', function () {
  629. var data = {
  630. Requests: {id: 1},
  631. tasks: [
  632. {
  633. Tasks: {
  634. id: 1,
  635. host_name: 'host1',
  636. status: 'COMPLETED'
  637. }
  638. },
  639. {
  640. Tasks: {
  641. id: 2,
  642. host_name: 'host1',
  643. status: 'IN_PROGRESS'
  644. }
  645. }
  646. ]
  647. };
  648. var request = Em.Object.create({
  649. id: 1,
  650. previousTaskStatusMap: {},
  651. isRunning: true,
  652. progress: 100,
  653. status:''
  654. });
  655. controller.set('services', [request]);
  656. controller.callBackFilteredByRequest(data);
  657. expect(request.get('previousTaskStatusMap')).to.eql({"1": "COMPLETED", "2": "IN_PROGRESS"});
  658. expect(request.get('hostsMap')['host1'].logTasks.length).to.equal(2);
  659. expect(request.get('isRunning')).to.equal(true);
  660. });
  661. });
  662. });