stack_and_upgrade_controller_test.js 38 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214
  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('controllers/main/admin/stack_and_upgrade_controller');
  20. require('utils/string_utils');
  21. describe('App.MainAdminStackAndUpgradeController', function() {
  22. var controller = App.MainAdminStackAndUpgradeController.create({
  23. getDBProperty: Em.K,
  24. setDBProperty: Em.K
  25. });
  26. describe("#realRepoUrl", function() {
  27. before(function () {
  28. this.mock = sinon.stub(App, 'get');
  29. });
  30. after(function () {
  31. this.mock.restore();
  32. });
  33. it("", function() {
  34. this.mock.withArgs('apiPrefix').returns('apiPrefix');
  35. this.mock.withArgs('stackVersionURL').returns('stackVersionURL');
  36. controller.propertyDidChange('realRepoUrl');
  37. expect(controller.get('realRepoUrl')).to.equal('apiPrefixstackVersionURL/compatible_repository_versions?fields=*,operating_systems/*,operating_systems/repositories/*');
  38. });
  39. });
  40. describe("#realStackUrl", function() {
  41. before(function () {
  42. this.mock = sinon.stub(App, 'get');
  43. });
  44. after(function () {
  45. this.mock.restore();
  46. });
  47. it("", function() {
  48. this.mock.withArgs('apiPrefix').returns('apiPrefix');
  49. this.mock.withArgs('clusterName').returns('clusterName');
  50. controller.propertyDidChange('realStackUrl');
  51. expect(controller.get('realStackUrl')).to.equal('apiPrefix/clusters/clusterName/stack_versions?fields=*,repository_versions/*,repository_versions/operating_systems/repositories/*');
  52. });
  53. });
  54. describe("#realUpdateUrl", function() {
  55. before(function () {
  56. this.mock = sinon.stub(App, 'get');
  57. });
  58. after(function () {
  59. this.mock.restore();
  60. });
  61. it("", function() {
  62. this.mock.withArgs('apiPrefix').returns('apiPrefix');
  63. this.mock.withArgs('clusterName').returns('clusterName');
  64. controller.propertyDidChange('realUpdateUrl');
  65. expect(controller.get('realUpdateUrl')).to.equal('apiPrefix/clusters/clusterName/stack_versions?fields=ClusterStackVersions/*');
  66. });
  67. });
  68. describe("#load()", function() {
  69. before(function(){
  70. sinon.stub(controller, 'loadUpgradeData').returns({
  71. done: function(callback) {callback();}
  72. });
  73. sinon.stub(controller, 'loadStackVersionsToModel').returns({
  74. done: function(callback) {callback();}
  75. });
  76. sinon.stub(controller, 'loadRepoVersionsToModel').returns({
  77. done: function(callback) {callback();}
  78. });
  79. sinon.stub(App.StackVersion, 'find').returns([Em.Object.create({
  80. state: 'CURRENT',
  81. repositoryVersion: {
  82. repositoryVersion: '2.2',
  83. displayName: 'HDP-2.2'
  84. }
  85. })]);
  86. });
  87. after(function(){
  88. controller.loadUpgradeData.restore();
  89. controller.loadStackVersionsToModel.restore();
  90. controller.loadRepoVersionsToModel.restore();
  91. App.StackVersion.find.restore();
  92. });
  93. it("", function() {
  94. controller.load();
  95. expect(controller.loadUpgradeData.calledWith(true)).to.be.true;
  96. expect(controller.loadStackVersionsToModel.calledWith(true)).to.be.true;
  97. expect(controller.loadRepoVersionsToModel.calledOnce).to.be.true;
  98. expect(controller.get('currentVersion')).to.eql({
  99. "repository_version": "2.2",
  100. "repository_name": "HDP-2.2"
  101. });
  102. });
  103. });
  104. describe("#loadUpgradeData()", function() {
  105. beforeEach(function () {
  106. sinon.stub(App.ajax, 'send').returns({
  107. then: Em.K,
  108. complete: Em.K
  109. });
  110. });
  111. afterEach(function () {
  112. App.ajax.send.restore();
  113. });
  114. it("get entire data", function() {
  115. controller.set('upgradeId', 1);
  116. controller.loadUpgradeData();
  117. expect(App.ajax.send.getCall(0).args[0]).to.eql({
  118. name: 'admin.upgrade.data',
  119. sender: controller,
  120. data: {
  121. id: 1
  122. },
  123. success: 'loadUpgradeDataSuccessCallback'
  124. })
  125. });
  126. it("get only state", function() {
  127. controller.set('upgradeId', 1);
  128. controller.loadUpgradeData(true);
  129. expect(App.ajax.send.getCall(0).args[0]).to.eql({
  130. name: 'admin.upgrade.state',
  131. sender: controller,
  132. data: {
  133. id: 1
  134. },
  135. success: 'loadUpgradeDataSuccessCallback'
  136. })
  137. });
  138. it("upgrade id is null", function() {
  139. controller.set('upgradeId', null);
  140. controller.loadUpgradeData();
  141. expect(App.ajax.send.called).to.be.false;
  142. });
  143. });
  144. describe("#loadUpgradeDataSuccessCallback()", function() {
  145. var retryCases = [
  146. {
  147. isRetryPendingInitial: true,
  148. status: 'ABORTED',
  149. isRetryPending: true,
  150. requestInProgress: true,
  151. title: 'retry request not yet applied'
  152. },
  153. {
  154. isRetryPendingInitial: true,
  155. status: 'UPGRADING',
  156. isRetryPending: false,
  157. requestInProgress: false,
  158. title: 'retry request applied'
  159. },
  160. {
  161. isRetryPendingInitial: false,
  162. status: 'ABORTED',
  163. isRetryPending: false,
  164. requestInProgress: true,
  165. title: 'no retry request sent'
  166. },
  167. {
  168. isRetryPendingInitial: false,
  169. status: 'UPGRADING',
  170. isRetryPending: false,
  171. requestInProgress: true,
  172. title: 'upgrade wasn\'t aborted'
  173. }
  174. ];
  175. beforeEach(function () {
  176. sinon.stub(controller, 'updateUpgradeData', Em.K);
  177. sinon.stub(controller, 'setDBProperty', Em.K);
  178. });
  179. afterEach(function () {
  180. controller.updateUpgradeData.restore();
  181. controller.setDBProperty.restore();
  182. });
  183. it("correct data", function() {
  184. var data = {
  185. "Upgrade": {
  186. "request_status": "UPGRADED"
  187. },
  188. "upgrade_groups": [
  189. {
  190. "UpgradeGroup": {
  191. "id": 1
  192. },
  193. "upgrade_items": []
  194. }
  195. ]};
  196. controller.loadUpgradeDataSuccessCallback(data);
  197. expect(App.get('upgradeState')).to.equal('UPGRADED');
  198. expect(controller.updateUpgradeData.calledOnce).to.be.true;
  199. expect(controller.setDBProperty.calledWith('upgradeState', 'UPGRADED')).to.be.true;
  200. });
  201. it("data is null", function() {
  202. var data = null;
  203. controller.loadUpgradeDataSuccessCallback(data);
  204. expect(controller.updateUpgradeData.called).to.be.false;
  205. expect(controller.setDBProperty.called).to.be.false;
  206. });
  207. retryCases.forEach(function (item) {
  208. it(item.title, function () {
  209. var data = {
  210. "Upgrade": {
  211. "request_status": item.status
  212. }
  213. };
  214. controller.setProperties({
  215. isRetryPending: item.isRetryPendingInitial,
  216. requestInProgress: true
  217. });
  218. controller.loadUpgradeDataSuccessCallback(data);
  219. expect(controller.getProperties(['isRetryPending', 'requestInProgress'])).to.eql({
  220. isRetryPending: item.isRetryPending,
  221. requestInProgress: item.requestInProgress
  222. });
  223. });
  224. });
  225. });
  226. describe("#getUpgradeItem()", function() {
  227. beforeEach(function () {
  228. sinon.stub(App.ajax, 'send', Em.K);
  229. });
  230. afterEach(function () {
  231. App.ajax.send.restore();
  232. });
  233. it("", function() {
  234. var item = Em.Object.create({
  235. request_id: 1,
  236. group_id: 2,
  237. stage_id: 3
  238. });
  239. controller.getUpgradeItem(item);
  240. expect(App.ajax.send.getCall(0).args[0]).to.eql({
  241. name: 'admin.upgrade.upgrade_item',
  242. sender: controller,
  243. data: {
  244. upgradeId: 1,
  245. groupId: 2,
  246. stageId: 3
  247. },
  248. success: 'getUpgradeItemSuccessCallback'
  249. });
  250. });
  251. });
  252. describe("#openUpgradeDialog()", function () {
  253. before(function () {
  254. sinon.stub(App.router, 'transitionTo', Em.K);
  255. });
  256. after(function () {
  257. App.router.transitionTo.restore();
  258. });
  259. it("should open dialog", function () {
  260. controller.openUpgradeDialog();
  261. expect(App.router.transitionTo.calledWith('admin.stackUpgrade')).to.be.true;
  262. });
  263. });
  264. describe("#runPreUpgradeCheck()", function() {
  265. before(function () {
  266. sinon.stub(App.ajax, 'send', Em.K);
  267. });
  268. after(function () {
  269. App.ajax.send.restore();
  270. });
  271. it("make ajax call", function() {
  272. controller.runPreUpgradeCheck(Em.Object.create({
  273. repositoryVersion: '2.2',
  274. displayName: 'HDP-2.2'
  275. }));
  276. expect(App.ajax.send.getCall(0).args[0]).to.eql({
  277. name: "admin.rolling_upgrade.pre_upgrade_check",
  278. sender: controller,
  279. data: {
  280. value: '2.2',
  281. label: 'HDP-2.2'
  282. },
  283. success: "runPreUpgradeCheckSuccess",
  284. error: "runPreUpgradeCheckError"
  285. });
  286. });
  287. });
  288. describe("#runPreUpgradeCheckSuccess()", function () {
  289. var cases = [
  290. {
  291. check: {
  292. "check": "Work-preserving RM/NM restart is enabled in YARN configs",
  293. "status": "FAIL",
  294. "reason": "FAIL",
  295. "failed_on": [],
  296. "check_type": "SERVICE"
  297. },
  298. showClusterCheckPopupCalledCount: 1,
  299. upgradeCalledCount: 0,
  300. title: 'popup is displayed if fails are present'
  301. },
  302. {
  303. check: {
  304. "check": "Configuration Merge Check",
  305. "status": "WARNING",
  306. "reason": "Conflict",
  307. "failed_on": [],
  308. "failed_detail": [
  309. {
  310. type: 't0',
  311. property: 'p0',
  312. current: 'c0',
  313. new_stack_value: 'n0',
  314. result_value: 'n0'
  315. },
  316. {
  317. type: 't1',
  318. property: 'p1',
  319. current: 'c1',
  320. new_stack_value: null,
  321. result_value: 'c1'
  322. },
  323. {
  324. type: 't2',
  325. property: 'p2',
  326. current: 'c2',
  327. new_stack_value: null,
  328. result_value: null
  329. }
  330. ],
  331. "check_type": "CLUSTER",
  332. "id": "CONFIG_MERGE"
  333. },
  334. showClusterCheckPopupCalledCount: 1,
  335. upgradeCalledCount: 0,
  336. configs: [
  337. {
  338. type: 't0',
  339. name: 'p0',
  340. currentValue: 'c0',
  341. recommendedValue: 'n0',
  342. resultingValue: 'n0',
  343. isDeprecated: false,
  344. willBeRemoved: false
  345. },
  346. {
  347. type: 't1',
  348. name: 'p1',
  349. currentValue: 'c1',
  350. recommendedValue: Em.I18n.t('popup.clusterCheck.Upgrade.configsMerge.deprecated'),
  351. resultingValue: 'c1',
  352. isDeprecated: true,
  353. willBeRemoved: false
  354. },
  355. {
  356. type: 't2',
  357. name: 'p2',
  358. currentValue: 'c2',
  359. recommendedValue: Em.I18n.t('popup.clusterCheck.Upgrade.configsMerge.deprecated'),
  360. resultingValue: Em.I18n.t('popup.clusterCheck.Upgrade.configsMerge.willBeRemoved'),
  361. isDeprecated: true,
  362. willBeRemoved: true
  363. }
  364. ],
  365. title: 'popup is displayed if warnings are present; configs merge conflicts'
  366. },
  367. {
  368. check: {
  369. "check": "Work-preserving RM/NM restart is enabled in YARN configs",
  370. "status": "PASS",
  371. "reason": "OK",
  372. "failed_on": [],
  373. "check_type": "SERVICE"
  374. },
  375. showClusterCheckPopupCalledCount: 0,
  376. upgradeCalledCount: 1,
  377. title: 'upgrade is started if fails and warnings are absent'
  378. }
  379. ];
  380. beforeEach(function () {
  381. sinon.stub(App, 'showClusterCheckPopup', Em.K);
  382. sinon.stub(controller, 'upgrade', Em.K);
  383. });
  384. afterEach(function () {
  385. App.showClusterCheckPopup.restore();
  386. controller.upgrade.restore();
  387. });
  388. cases.forEach(function (item) {
  389. it(item.title, function () {
  390. controller.runPreUpgradeCheckSuccess(
  391. {
  392. items: [
  393. {
  394. UpgradeChecks: item.check
  395. }
  396. ]
  397. }, null, {
  398. label: 'name'
  399. }
  400. );
  401. expect(controller.upgrade.callCount).to.equal(item.upgradeCalledCount);
  402. expect(App.showClusterCheckPopup.callCount).to.equal(item.showClusterCheckPopupCalledCount);
  403. if (item.check.id == 'CONFIG_MERGE') {
  404. expect(App.showClusterCheckPopup.firstCall.args[7]).to.eql(item.configs);
  405. }
  406. });
  407. });
  408. });
  409. describe("#initDBProperties()", function() {
  410. before(function () {
  411. sinon.stub(controller, 'getDBProperties', function (prop) {
  412. var ret = {};
  413. prop.forEach(function (k) {
  414. ret[k] = k;
  415. });
  416. return ret;
  417. });
  418. });
  419. after(function () {
  420. controller.getDBProperties.restore();
  421. });
  422. it("set properties", function () {
  423. controller.set('wizardStorageProperties', ['prop1']);
  424. controller.initDBProperties();
  425. expect(controller.get('prop1')).to.equal('prop1');
  426. });
  427. });
  428. describe("#init()", function() {
  429. before(function () {
  430. sinon.stub(controller, 'initDBProperties', Em.K);
  431. });
  432. after(function () {
  433. controller.initDBProperties.restore();
  434. });
  435. it("call initDBProperties", function () {
  436. controller.init();
  437. expect(controller.initDBProperties.calledOnce).to.be.true;
  438. });
  439. });
  440. describe("#upgrade()", function() {
  441. before(function () {
  442. sinon.stub(App.ajax, 'send', Em.K);
  443. sinon.stub(controller, 'setDBProperty', Em.K);
  444. });
  445. after(function () {
  446. App.ajax.send.restore();
  447. controller.setDBProperty.restore();
  448. });
  449. it("make ajax call", function() {
  450. controller.set('currentVersion', {
  451. repository_version: '2.2'
  452. });
  453. controller.upgrade({
  454. value: '2.2',
  455. label: 'HDP-2.2'
  456. });
  457. expect(App.ajax.send.getCall(0).args[0].data).to.eql({"value": '2.2', "label": 'HDP-2.2'});
  458. expect(App.ajax.send.getCall(0).args[0].name).to.eql('admin.upgrade.start');
  459. expect(App.ajax.send.getCall(0).args[0].sender).to.eql(controller);
  460. expect(App.ajax.send.getCall(0).args[0].success).to.eql('upgradeSuccessCallback');
  461. expect(App.ajax.send.getCall(0).args[0].callback).to.be.called;
  462. expect(controller.setDBProperty.calledWith('currentVersion', {
  463. repository_version: '2.2'
  464. })).to.be.true;
  465. });
  466. });
  467. describe("#upgradeSuccessCallback()", function() {
  468. before(function () {
  469. sinon.stub(App.clusterStatus, 'setClusterStatus', Em.K);
  470. sinon.stub(controller, 'openUpgradeDialog', Em.K);
  471. sinon.stub(controller, 'setDBProperties', Em.K);
  472. sinon.stub(controller, 'load', Em.K);
  473. });
  474. after(function () {
  475. App.clusterStatus.setClusterStatus.restore();
  476. controller.openUpgradeDialog.restore();
  477. controller.setDBProperties.restore();
  478. controller.load.restore();
  479. });
  480. it("open upgrade dialog", function() {
  481. var data = {
  482. resources: [
  483. {
  484. Upgrade: {
  485. request_id: 1
  486. }
  487. }
  488. ]
  489. };
  490. controller.upgradeSuccessCallback(data, {}, {label: 'HDP-2.2.1', isDowngrade: true});
  491. expect(controller.load.calledOnce).to.be.true;
  492. expect(controller.get('upgradeVersion')).to.equal('HDP-2.2.1');
  493. expect(controller.get('upgradeData')).to.be.null;
  494. expect(controller.get('isDowngrade')).to.be.true;
  495. expect(App.clusterStatus.setClusterStatus.calledOnce).to.be.true;
  496. expect(controller.openUpgradeDialog.calledOnce).to.be.true;
  497. });
  498. });
  499. describe("#updateUpgradeData()", function() {
  500. beforeEach(function () {
  501. sinon.stub(controller, 'initUpgradeData', Em.K);
  502. });
  503. afterEach(function () {
  504. controller.initUpgradeData.restore();
  505. });
  506. it("data loaded first time", function() {
  507. controller.set('upgradeData', null);
  508. controller.updateUpgradeData({});
  509. expect(controller.initUpgradeData.calledWith({})).to.be.true;
  510. });
  511. it("update loaded data", function() {
  512. var oldData = Em.Object.create({
  513. upgradeGroups: [
  514. Em.Object.create({
  515. group_id: 1,
  516. upgradeItems: [
  517. Em.Object.create({
  518. stage_id: 1
  519. })
  520. ]
  521. }),
  522. Em.Object.create({
  523. group_id: 2,
  524. upgradeItems: [
  525. Em.Object.create({
  526. stage_id: 2
  527. }),
  528. Em.Object.create({
  529. stage_id: 3
  530. })
  531. ]
  532. })
  533. ]
  534. });
  535. var newData = {
  536. Upgrade: {
  537. request_id: 1
  538. },
  539. upgrade_groups: [
  540. {
  541. UpgradeGroup: {
  542. group_id: 1,
  543. status: 'COMPLETED',
  544. progress_percent: 100,
  545. completed_task_count: 3
  546. },
  547. upgrade_items: [
  548. {
  549. UpgradeItem: {
  550. stage_id: 1,
  551. status: 'COMPLETED',
  552. progress_percent: 100
  553. }
  554. }
  555. ]
  556. },
  557. {
  558. UpgradeGroup: {
  559. group_id: 2,
  560. status: 'ABORTED',
  561. progress_percent: 50,
  562. completed_task_count: 1
  563. },
  564. upgrade_items: [
  565. {
  566. UpgradeItem: {
  567. stage_id: 2,
  568. status: 'ABORTED',
  569. progress_percent: 99
  570. }
  571. },
  572. {
  573. UpgradeItem: {
  574. stage_id: 3,
  575. status: 'PENDING',
  576. progress_percent: 0
  577. }
  578. }
  579. ]
  580. }
  581. ]
  582. };
  583. controller.set('upgradeData', oldData);
  584. controller.updateUpgradeData(newData);
  585. expect(controller.get('upgradeData.upgradeGroups')[0].get('status')).to.equal('COMPLETED');
  586. expect(controller.get('upgradeData.upgradeGroups')[0].get('progress_percent')).to.equal(100);
  587. expect(controller.get('upgradeData.upgradeGroups')[0].get('completed_task_count')).to.equal(3);
  588. expect(controller.get('upgradeData.upgradeGroups')[0].get('upgradeItems')[0].get('status')).to.equal('COMPLETED');
  589. expect(controller.get('upgradeData.upgradeGroups')[0].get('upgradeItems')[0].get('progress_percent')).to.equal(100);
  590. expect(controller.get('upgradeData.upgradeGroups')[0].get('hasExpandableItems')).to.be.true;
  591. expect(controller.get('upgradeData.upgradeGroups')[1].get('status')).to.equal('ABORTED');
  592. expect(controller.get('upgradeData.upgradeGroups')[1].get('progress_percent')).to.equal(50);
  593. expect(controller.get('upgradeData.upgradeGroups')[1].get('completed_task_count')).to.equal(1);
  594. expect(controller.get('upgradeData.upgradeGroups')[1].get('upgradeItems')[0].get('status')).to.equal('ABORTED');
  595. expect(controller.get('upgradeData.upgradeGroups')[1].get('upgradeItems')[1].get('status')).to.equal('PENDING');
  596. expect(controller.get('upgradeData.upgradeGroups')[1].get('upgradeItems')[0].get('progress_percent')).to.equal(99);
  597. expect(controller.get('upgradeData.upgradeGroups')[1].get('upgradeItems')[1].get('progress_percent')).to.equal(0);
  598. expect(controller.get('upgradeData.upgradeGroups')[1].get('hasExpandableItems')).to.be.false;
  599. });
  600. });
  601. describe("#initUpgradeData()", function() {
  602. it("", function() {
  603. var newData = {
  604. Upgrade: {
  605. request_id: 1
  606. },
  607. upgrade_groups: [
  608. {
  609. UpgradeGroup: {
  610. group_id: 1
  611. },
  612. upgrade_items: [
  613. {
  614. UpgradeItem: {
  615. stage_id: 1,
  616. status: 'IN_PROGRESS'
  617. }
  618. },
  619. {
  620. UpgradeItem: {
  621. stage_id: 2
  622. }
  623. }
  624. ]
  625. },
  626. {
  627. UpgradeGroup: {
  628. group_id: 2
  629. },
  630. upgrade_items: []
  631. },
  632. {
  633. UpgradeGroup: {
  634. group_id: 3
  635. },
  636. upgrade_items: [
  637. {
  638. UpgradeItem: {
  639. stage_id: 3,
  640. status: 'ABORTED'
  641. }
  642. },
  643. {
  644. UpgradeItem: {
  645. stage_id: 4,
  646. status: 'PENDING'
  647. }
  648. }
  649. ]
  650. }
  651. ]
  652. };
  653. controller.initUpgradeData(newData);
  654. expect(controller.get('upgradeData.Upgrade.request_id')).to.equal(1);
  655. expect(controller.get('upgradeData.upgradeGroups')[0].get('group_id')).to.equal(3);
  656. expect(controller.get('upgradeData.upgradeGroups')[1].get('group_id')).to.equal(2);
  657. expect(controller.get('upgradeData.upgradeGroups')[2].get('group_id')).to.equal(1);
  658. expect(controller.get('upgradeData.upgradeGroups')[2].get('upgradeItems')[0].get('stage_id')).to.equal(2);
  659. expect(controller.get('upgradeData.upgradeGroups')[2].get('upgradeItems')[1].get('stage_id')).to.equal(1);
  660. expect(controller.get('upgradeData.upgradeGroups')[0].get('hasExpandableItems')).to.be.false;
  661. expect(controller.get('upgradeData.upgradeGroups')[1].get('hasExpandableItems')).to.be.false;
  662. expect(controller.get('upgradeData.upgradeGroups')[2].get('hasExpandableItems')).to.be.true;
  663. });
  664. });
  665. describe.skip("#finish()", function() {
  666. before(function () {
  667. sinon.stub(App.clusterStatus, 'setClusterStatus', Em.K);
  668. sinon.stub(controller, 'setDBProperty', Em.K);
  669. });
  670. after(function () {
  671. App.clusterStatus.setClusterStatus.restore();
  672. controller.setDBProperty.restore();
  673. });
  674. it("upgradeState is not COMPLETED", function() {
  675. App.set('upgradeState', 'UPGRADING');
  676. controller.finish();
  677. expect(App.clusterStatus.setClusterStatus.called).to.be.false;
  678. });
  679. it("upgradeState is COMPLETED", function() {
  680. App.set('upgradeState', 'COMPLETED');
  681. controller.finish();
  682. expect(controller.setDBProperty.calledWith('upgradeId', undefined)).to.be.true;
  683. expect(controller.setDBProperty.calledWith('upgradeVersion', undefined)).to.be.true;
  684. expect(controller.setDBProperty.calledWith('upgradeState', 'INIT')).to.be.true;
  685. expect(controller.setDBProperty.calledWith('currentVersion', undefined)).to.be.true;
  686. expect(App.get('upgradeState')).to.equal('INIT');
  687. expect(App.clusterStatus.setClusterStatus.calledOnce).to.be.true;
  688. });
  689. });
  690. describe("#confirmDowngrade()", function() {
  691. before(function () {
  692. sinon.spy(App, 'showConfirmationPopup');
  693. sinon.stub(controller, 'downgrade', Em.K);
  694. });
  695. after(function () {
  696. App.showConfirmationPopup.restore();
  697. controller.downgrade.restore();
  698. });
  699. it("show confirmation popup", function() {
  700. controller.set('currentVersion', Em.Object.create({
  701. repository_version: '2.2',
  702. repository_name: 'HDP-2.2'
  703. }));
  704. var popup = controller.confirmDowngrade();
  705. expect(App.showConfirmationPopup.calledOnce).to.be.true;
  706. popup.onPrimary();
  707. expect(controller.downgrade.calledWith(Em.Object.create({
  708. repository_version: '2.2',
  709. repository_name: 'HDP-2.2'
  710. }))).to.be.true;
  711. });
  712. });
  713. describe("#confirmUpgrade()", function() {
  714. before(function () {
  715. sinon.spy(App, 'showConfirmationPopup');
  716. sinon.stub(controller, 'runPreUpgradeCheck', Em.K);
  717. });
  718. after(function () {
  719. App.showConfirmationPopup.restore();
  720. controller.runPreUpgradeCheck.restore();
  721. });
  722. it("show confirmation popup", function() {
  723. var version = Em.Object.create({displayName: 'HDP-2.2'});
  724. var popup = controller.confirmUpgrade(version);
  725. expect(App.showConfirmationPopup.calledOnce).to.be.true;
  726. popup.onPrimary();
  727. expect(controller.runPreUpgradeCheck.calledWith(version)).to.be.true;
  728. });
  729. });
  730. describe("#downgrade()", function() {
  731. before(function () {
  732. sinon.stub(App.ajax, 'send', Em.K);
  733. sinon.stub(controller, 'abortUpgrade');
  734. sinon.stub(App.RepositoryVersion, 'find').returns([
  735. Em.Object.create({
  736. displayName: 'HDP-2.3',
  737. repositoryVersion: '2.3'
  738. })
  739. ]);
  740. });
  741. after(function () {
  742. App.ajax.send.restore();
  743. controller.abortUpgrade.restore();
  744. App.RepositoryVersion.find.restore();
  745. });
  746. it("make ajax call", function() {
  747. controller.set('upgradeVersion', 'HDP-2.3');
  748. controller.downgrade(Em.Object.create({
  749. repository_version: '2.2',
  750. repository_name: 'HDP-2.2'
  751. }), {context: 'context'});
  752. expect(controller.abortUpgrade.calledOnce).to.be.true;
  753. expect(App.ajax.send.getCall(0).args[0].data).to.eql({
  754. value: '2.2',
  755. label: 'HDP-2.2',
  756. from: '2.3',
  757. isDowngrade: true
  758. });
  759. expect(App.ajax.send.getCall(0).args[0].name).to.eql('admin.downgrade.start');
  760. expect(App.ajax.send.getCall(0).args[0].sender).to.eql(controller);
  761. expect(App.ajax.send.getCall(0).args[0].success).to.eql('upgradeSuccessCallback');
  762. expect(App.ajax.send.getCall(0).args[0].callback).to.be.called;
  763. });
  764. });
  765. describe("#installRepoVersionConfirmation()", function () {
  766. before(function () {
  767. sinon.stub(controller, 'installRepoVersion', Em.K);
  768. });
  769. after(function () {
  770. controller.installRepoVersion.restore();
  771. });
  772. it("show popup", function () {
  773. var repo = Em.Object.create({'displayName': 'HDP-2.2'});
  774. var popup = controller.installRepoVersionConfirmation(repo);
  775. popup.onPrimary();
  776. expect(controller.installRepoVersion.calledWith(repo)).to.be.true;
  777. });
  778. });
  779. describe("#installRepoVersion()", function () {
  780. before(function () {
  781. sinon.stub(App.ajax, 'send', Em.K);
  782. });
  783. after(function () {
  784. App.ajax.send.restore();
  785. });
  786. it("make ajax call", function () {
  787. var repo = Em.Object.create({
  788. stackVersionType: 'HDP',
  789. stackVersionNumber: '2.2',
  790. repositoryVersion: '2.2.1',
  791. repoId: 1
  792. });
  793. controller.installRepoVersion(repo);
  794. expect(App.ajax.send.calledOnce).to.be.true;
  795. });
  796. });
  797. describe("#installRepoVersionSuccess()", function() {
  798. var mock = Em.Object.create({
  799. id: 1,
  800. defaultStatus: 'INIT',
  801. stackVersion: {}
  802. });
  803. before(function () {
  804. sinon.spy(mock, 'set');
  805. sinon.stub(App.db, 'set', Em.K);
  806. sinon.stub(App.clusterStatus, 'setClusterStatus', Em.K);
  807. sinon.stub(App.RepositoryVersion, 'find').returns(mock);
  808. });
  809. after(function () {
  810. App.db.set.restore();
  811. App.clusterStatus.setClusterStatus.restore();
  812. App.RepositoryVersion.find.restore();
  813. });
  814. it("", function() {
  815. controller.installRepoVersionSuccess({Requests: {id: 1}}, {}, {id: 1});
  816. expect(App.db.set.calledWith('repoVersionInstall', 'id', [1])).to.be.true;
  817. expect(App.clusterStatus.setClusterStatus.calledOnce).to.be.true;
  818. expect(App.RepositoryVersion.find.calledWith(1)).to.be.true;
  819. expect(App.RepositoryVersion.find(1).get('defaultStatus')).to.equal('INSTALLING');
  820. expect(App.RepositoryVersion.find(1).get('stackVersion.state')).to.equal('INSTALLING');
  821. });
  822. });
  823. describe("#setUpgradeItemStatus()", function () {
  824. before(function () {
  825. sinon.stub(App.ajax, 'send', function () {
  826. return {
  827. done: function (callback) {
  828. callback();
  829. }
  830. }
  831. });
  832. });
  833. after(function () {
  834. App.ajax.send.restore();
  835. });
  836. it("", function () {
  837. var item = Em.Object.create({
  838. request_id: 1,
  839. stage_id: 1,
  840. group_id: 1
  841. });
  842. controller.setUpgradeItemStatus(item, 'PENDING');
  843. expect(App.ajax.send.getCall(0).args[0].data).to.eql({upgradeId: 1, itemId: 1, groupId: 1, status: 'PENDING'});
  844. expect(App.ajax.send.getCall(0).args[0].name).to.eql('admin.upgrade.upgradeItem.setState');
  845. expect(App.ajax.send.getCall(0).args[0].sender).to.eql(controller);
  846. expect(App.ajax.send.getCall(0).args[0].callback).to.be.called;
  847. expect(item.get('status')).to.equal('PENDING');
  848. });
  849. });
  850. describe("#prepareRepoForSaving()", function () {
  851. it("prepare date for saving", function () {
  852. var repo = Em.Object.create({
  853. operatingSystems: [
  854. Em.Object.create({
  855. osType: "redhat6",
  856. isDisabled: Ember.computed.not('isSelected'),
  857. repositories: [Em.Object.create({
  858. "baseUrl": "111121",
  859. "repoId": "HDP-2.2",
  860. "repoName": "HDP",
  861. hasError: false
  862. }),
  863. Em.Object.create({
  864. "baseUrl": "1",
  865. "repoId": "HDP-UTILS-1.1.0.20",
  866. "repoName": "HDP-UTILS",
  867. hasError: false
  868. })]
  869. })
  870. ]
  871. });
  872. var result = {
  873. "operating_systems": [
  874. {
  875. "OperatingSystems": {
  876. "os_type": "redhat6"
  877. },
  878. "repositories": [
  879. {
  880. "Repositories": {
  881. "base_url": "111121",
  882. "repo_id": "HDP-2.2",
  883. "repo_name": "HDP"
  884. }
  885. },
  886. {
  887. "Repositories": {
  888. "base_url": "1",
  889. "repo_id": "HDP-UTILS-1.1.0.20",
  890. "repo_name": "HDP-UTILS"
  891. }
  892. }
  893. ]
  894. }
  895. ]};
  896. expect(controller.prepareRepoForSaving(repo)).to.eql(result);
  897. });
  898. });
  899. describe("#getStackVersionNumber()", function(){
  900. it("get stack version number", function(){
  901. var repo = Em.Object.create({
  902. "stackVersionType": 'HDP',
  903. "stackVersion": '2.3',
  904. "repositoryVersion": '2.2.1'
  905. });
  906. var stackVersion = controller.getStackVersionNumber(repo);
  907. expect(stackVersion).to.equal('2.3');
  908. });
  909. it("get default stack version number", function(){
  910. App.set('currentStackVersion', '1.2.3');
  911. var repo = Em.Object.create({
  912. "stackVersionType": 'HDP',
  913. "repositoryVersion": '2.2.1'
  914. });
  915. var stackVersion = controller.getStackVersionNumber(repo);
  916. expect(stackVersion).to.equal('1.2.3');
  917. });
  918. });
  919. describe("#saveRepoOS()", function() {
  920. before(function(){
  921. this.mock = sinon.stub(controller, 'validateRepoVersions');
  922. sinon.stub(controller, 'prepareRepoForSaving', Em.K);
  923. sinon.stub(App.ajax, 'send').returns({success: Em.K});
  924. });
  925. after(function(){
  926. this.mock.restore();
  927. controller.prepareRepoForSaving.restore();
  928. App.ajax.send.restore();
  929. });
  930. it("validation errors present", function() {
  931. this.mock.returns({
  932. done: function(callback) {callback([1]);}
  933. });
  934. controller.saveRepoOS(Em.Object.create({repoVersionId: 1}), true);
  935. expect(controller.validateRepoVersions.calledWith(Em.Object.create({repoVersionId: 1}), true)).to.be.true;
  936. expect(controller.prepareRepoForSaving.called).to.be.false;
  937. expect(App.ajax.send.called).to.be.false;
  938. });
  939. it("no validation errors", function() {
  940. this.mock.returns({
  941. done: function(callback) {callback([]);}
  942. });
  943. controller.saveRepoOS(Em.Object.create({repoVersionId: 1}), true);
  944. expect(controller.validateRepoVersions.calledWith(Em.Object.create({repoVersionId: 1}), true)).to.be.true;
  945. expect(controller.prepareRepoForSaving.calledWith(Em.Object.create({repoVersionId: 1}))).to.be.true;
  946. expect(App.ajax.send.calledOnce).to.be.true;
  947. });
  948. });
  949. describe("#validateRepoVersions()", function () {
  950. before(function () {
  951. sinon.stub(App.ajax, 'send').returns({success: Em.K, error: Em.K});
  952. });
  953. after(function () {
  954. App.ajax.send.restore();
  955. });
  956. it("skip validation", function () {
  957. controller.validateRepoVersions(Em.Object.create({repoVersionId: 1}), true);
  958. expect(App.ajax.send.called).to.be.false;
  959. });
  960. it("do validation", function () {
  961. var repo = Em.Object.create({
  962. repoVersionId: 1,
  963. operatingSystems: [
  964. Em.Object.create({
  965. isSelected: true,
  966. repositories: [
  967. Em.Object.create()
  968. ]
  969. })
  970. ]
  971. });
  972. controller.validateRepoVersions(repo, false);
  973. expect(App.ajax.send.calledOnce).to.be.true;
  974. });
  975. });
  976. describe("#showProgressPopup()", function () {
  977. var mock = {
  978. initPopup: Em.K
  979. };
  980. before(function () {
  981. sinon.stub(App.router, 'get').withArgs('highAvailabilityProgressPopupController').returns(mock);
  982. sinon.spy(mock, 'initPopup');
  983. });
  984. after(function () {
  985. App.router.get.restore();
  986. mock.initPopup.restore();
  987. });
  988. it("", function () {
  989. controller.showProgressPopup(Em.Object.create());
  990. expect(mock.initPopup.calledOnce).to.be.true;
  991. });
  992. });
  993. describe("#getUrl()", function() {
  994. beforeEach(function(){
  995. controller.reopen({
  996. realStackUrl: 'realStackUrl',
  997. realRepoUrl: 'realRepoUrl',
  998. realUpdateUrl: 'realUpdateUrl'
  999. });
  1000. });
  1001. it("full load is true, stack is null", function() {
  1002. expect(controller.getUrl(null, true)).to.equal('realRepoUrl');
  1003. });
  1004. it("full load is true, stack is valid", function() {
  1005. expect(controller.getUrl({}, true)).to.equal('realStackUrl');
  1006. });
  1007. it("full load is false, stack is valid", function() {
  1008. expect(controller.getUrl({}, false)).to.equal('realUpdateUrl');
  1009. });
  1010. });
  1011. describe("#loadStackVersionsToModel()", function () {
  1012. before(function () {
  1013. sinon.stub(App.HttpClient, 'get');
  1014. });
  1015. after(function () {
  1016. App.HttpClient.get.restore();
  1017. });
  1018. it("", function () {
  1019. controller.loadStackVersionsToModel();
  1020. expect(App.HttpClient.get.calledOnce).to.be.true;
  1021. });
  1022. });
  1023. describe("#loadRepoVersionsToModel()", function () {
  1024. before(function () {
  1025. sinon.stub(App.HttpClient, 'get');
  1026. });
  1027. after(function () {
  1028. App.HttpClient.get.restore();
  1029. });
  1030. it("", function () {
  1031. controller.loadRepoVersionsToModel();
  1032. expect(App.HttpClient.get.calledOnce).to.be.true;
  1033. });
  1034. });
  1035. describe('#currentVersionObserver()', function () {
  1036. var cases = [
  1037. {
  1038. stackVersionType: 'HDP',
  1039. repoVersion: '2.2.1.1.0-1',
  1040. isStormMetricsSupported: false,
  1041. title: 'HDP < 2.2.2'
  1042. },
  1043. {
  1044. stackVersionType: 'HDP',
  1045. repoVersion: '2.2.2.1.0-1',
  1046. isStormMetricsSupported: true,
  1047. title: 'HDP 2.2.2'
  1048. },
  1049. {
  1050. stackVersionType: 'HDP',
  1051. repoVersion: '2.2.3.1.0-1',
  1052. isStormMetricsSupported: true,
  1053. title: 'HDP > 2.2.2'
  1054. },
  1055. {
  1056. stackVersionType: 'BIGTOP',
  1057. repoVersion: '0.8.1.1.0-1',
  1058. isStormMetricsSupported: true,
  1059. title: 'not HDP'
  1060. }
  1061. ];
  1062. afterEach(function () {
  1063. App.RepositoryVersion.find.restore();
  1064. });
  1065. cases.forEach(function (item) {
  1066. it(item.title, function () {
  1067. sinon.stub(App.RepositoryVersion, 'find').returns([
  1068. Em.Object.create({
  1069. status: 'CURRENT',
  1070. stackVersionType: item.stackVersionType
  1071. })
  1072. ]);
  1073. controller.set('currentVersion', {
  1074. repository_version: item.repoVersion
  1075. });
  1076. expect(App.get('isStormMetricsSupported')).to.equal(item.isStormMetricsSupported);
  1077. });
  1078. });
  1079. });
  1080. describe('#updateFinalize', function () {
  1081. beforeEach(function() {
  1082. sinon.stub($, 'ajax', Em.K);
  1083. controller.set('isFinalizeItem', true);
  1084. });
  1085. afterEach(function () {
  1086. $.ajax.restore();
  1087. });
  1088. it('should do ajax-request', function () {
  1089. sinon.stub(App, 'get').withArgs('upgradeState').returns('HOLDING');
  1090. controller.updateFinalize();
  1091. App.get.restore();
  1092. expect($.ajax.calledOnce).to.be.true;
  1093. });
  1094. it('shouldn\'t do ajax-request', function () {
  1095. sinon.stub(App, 'get').withArgs('upgradeState').returns('HOLDING_TIMEDOUT');
  1096. controller.updateFinalize();
  1097. App.get.restore();
  1098. expect(controller.get('isFinalizeItem')).to.be.false;
  1099. expect($.ajax.calledOnce).to.be.false;
  1100. });
  1101. });
  1102. describe('#updateFinalizeSuccessCallback', function () {
  1103. it('data exists and Finalize should be true', function() {
  1104. var data = {
  1105. upgrade_groups: [
  1106. {
  1107. upgrade_items: [
  1108. {
  1109. UpgradeItem: {
  1110. context: controller.get('finalizeContext'),
  1111. status: "HOLDING"
  1112. }
  1113. }
  1114. ]
  1115. }
  1116. ]
  1117. };
  1118. controller.set('isFinalizeItem', false);
  1119. controller.updateFinalizeSuccessCallback(data);
  1120. expect(controller.get('isFinalizeItem')).to.be.true;
  1121. });
  1122. it('data exists and Finalize should be false', function() {
  1123. var data = {
  1124. upgrade_groups: [
  1125. {
  1126. upgrade_items: [
  1127. {
  1128. UpgradeItem: {
  1129. context: '!@#$%^&',
  1130. status: "HOLDING"
  1131. }
  1132. }
  1133. ]
  1134. }
  1135. ]
  1136. };
  1137. controller.set('isFinalizeItem', true);
  1138. controller.updateFinalizeSuccessCallback(data);
  1139. expect(controller.get('isFinalizeItem')).to.be.false;
  1140. });
  1141. it('data doesn\'t exist', function() {
  1142. var data = null;
  1143. controller.set('isFinalizeItem', true);
  1144. controller.updateFinalizeSuccessCallback(data);
  1145. expect(controller.get('isFinalizeItem')).to.be.false;
  1146. });
  1147. });
  1148. describe('#updateFinalizeErrorCallback', function () {
  1149. it('should set isFinalizeItem to false', function () {
  1150. controller.set('isFinalizeItem', true);
  1151. controller.updateFinalizeErrorCallback();
  1152. expect(controller.get('isFinalizeItem')).to.be.false;
  1153. });
  1154. });
  1155. });