step4_controller_test.js 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180
  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. App = require('app');
  19. require('controllers/main/service/reassign/step4_controller');
  20. describe('App.ReassignMasterWizardStep4Controller', function () {
  21. var controller = App.ReassignMasterWizardStep4Controller.create({
  22. content: Em.Object.create({
  23. reassign: Em.Object.create(),
  24. reassignHosts: Em.Object.create()
  25. })
  26. });
  27. beforeEach(function () {
  28. sinon.stub(App.ajax, 'send', Em.K);
  29. });
  30. afterEach(function () {
  31. App.ajax.send.restore();
  32. });
  33. describe('#setAdditionalConfigs()', function () {
  34. it('Component is absent', function () {
  35. controller.set('additionalConfigsMap', []);
  36. var configs = {};
  37. expect(controller.setAdditionalConfigs(configs, 'COMP1', '')).to.be.false;
  38. expect(configs).to.eql({});
  39. });
  40. it('configs for Hadoop 2 is present', function () {
  41. controller.set('additionalConfigsMap', [
  42. {
  43. componentName: 'COMP1',
  44. configs: {
  45. 'test-site': {
  46. 'property1': '<replace-value>:1111'
  47. }
  48. },
  49. configs_Hadoop2: {
  50. 'test-site': {
  51. 'property2': '<replace-value>:2222'
  52. }
  53. }
  54. }
  55. ]);
  56. var configs = {
  57. 'test-site': {}
  58. };
  59. expect(controller.setAdditionalConfigs(configs, 'COMP1', 'host1')).to.be.true;
  60. expect(configs).to.eql({
  61. 'test-site': {
  62. 'property2': 'host1:2222'
  63. }
  64. });
  65. });
  66. });
  67. describe('#getHostComponentsNames()', function () {
  68. it('No host-components', function () {
  69. controller.set('hostComponents', []);
  70. expect(controller.getHostComponentsNames()).to.be.empty;
  71. });
  72. it('one host-components', function () {
  73. controller.set('hostComponents', ['COMP1']);
  74. expect(controller.getHostComponentsNames()).to.equal('Comp1');
  75. });
  76. it('ZKFC host-components', function () {
  77. controller.set('hostComponents', ['COMP1', 'ZKFC']);
  78. expect(controller.getHostComponentsNames()).to.equal('Comp1+ZKFC');
  79. });
  80. });
  81. describe('#testDBConnection', function() {
  82. beforeEach(function() {
  83. controller.set('requiredProperties', Em.A([]));
  84. controller.set('content.serviceProperties', Em.Object.create({'javax.jdo.option.ConnectionDriverName': 'mysql'}));
  85. controller.set('content.reassign.component_name', 'HIVE_SERVER');
  86. sinon.stub(controller, 'getConnectionProperty', Em.K);
  87. sinon.stub(App.router, 'get', Em.K);
  88. });
  89. afterEach(function() {
  90. controller.getConnectionProperty.restore();
  91. App.router.get.restore();
  92. });
  93. it('tests database connection', function() {
  94. sinon.stub(controller, 'prepareDBCheckAction', Em.K);
  95. controller.testDBConnection();
  96. expect(controller.prepareDBCheckAction.calledOnce).to.be.true;
  97. controller.prepareDBCheckAction.restore();
  98. });
  99. it('tests prepareDBCheckAction', function() {
  100. controller.prepareDBCheckAction();
  101. expect(App.ajax.send.calledOnce).to.be.true;
  102. });
  103. });
  104. describe('#removeUnneededTasks()', function () {
  105. var isHaEnabled = false;
  106. var commands;
  107. var commandsForDB;
  108. beforeEach(function () {
  109. sinon.stub(App, 'get', function () {
  110. return isHaEnabled;
  111. });
  112. commands = [
  113. { id: 1, command: 'stopRequiredServices' },
  114. { id: 2, command: 'cleanMySqlServer' },
  115. { id: 3, command: 'createHostComponents' },
  116. { id: 4, command: 'putHostComponentsInMaintenanceMode' },
  117. { id: 5, command: 'reconfigure' },
  118. { id: 6, command: 'installHostComponents' },
  119. { id: 7, command: 'startZooKeeperServers' },
  120. { id: 8, command: 'startNameNode' },
  121. { id: 9, command: 'deleteHostComponents' },
  122. { id: 10, command: 'configureMySqlServer' },
  123. { id: 11, command: 'startMySqlServer' },
  124. { id: 12, command: 'startNewMySqlServer' },
  125. { id: 13, command: 'startRequiredServices' }
  126. ];
  127. commandsForDB = [
  128. { id: 1, command: 'createHostComponents' },
  129. { id: 2, command: 'installHostComponents' },
  130. { id: 3, command: 'configureMySqlServer' },
  131. { id: 4, command: 'restartMySqlServer' },
  132. { id: 5, command: 'testDBConnection' },
  133. { id: 6, command: 'stopRequiredServices' },
  134. { id: 7, command: 'cleanMySqlServer' },
  135. { id: 8, command: 'putHostComponentsInMaintenanceMode' },
  136. { id: 9, command: 'reconfigure' },
  137. { id: 10, command: 'deleteHostComponents' },
  138. { id: 11, command: 'configureMySqlServer' },
  139. { id: 12, command: 'startRequiredServices' }
  140. ];
  141. });
  142. afterEach(function () {
  143. App.get.restore();
  144. });
  145. it('hasManualSteps is false', function () {
  146. controller.set('tasks', commands);
  147. controller.set('content.hasManualSteps', false);
  148. controller.removeUnneededTasks();
  149. expect(controller.get('tasks').mapProperty('id')).to.eql([1,3,4,5,6,9,12,13]);
  150. });
  151. it('reassign component is not NameNode and HA disabled', function () {
  152. controller.set('tasks', commands);
  153. controller.set('content.hasManualSteps', true);
  154. controller.set('content.reassign.component_name', 'COMP1');
  155. isHaEnabled = false;
  156. controller.removeUnneededTasks();
  157. expect(controller.get('tasks').mapProperty('id')).to.eql([1, 3, 4, 5, 6]);
  158. });
  159. it('reassign component is not NameNode and HA enabled', function () {
  160. controller.set('tasks', commands);
  161. controller.set('content.hasManualSteps', true);
  162. controller.set('content.reassign.component_name', 'COMP1');
  163. isHaEnabled = true;
  164. controller.removeUnneededTasks();
  165. expect(controller.get('tasks').mapProperty('id')).to.eql([1, 3, 4, 5, 6]);
  166. });
  167. it('reassign component is NameNode and HA disabled', function () {
  168. controller.set('tasks', commands);
  169. controller.set('content.hasManualSteps', true);
  170. controller.set('content.reassign.component_name', 'NAMENODE');
  171. isHaEnabled = false;
  172. controller.removeUnneededTasks();
  173. expect(controller.get('tasks').mapProperty('id')).to.eql([1, 3, 4, 5, 6]);
  174. });
  175. it('reassign component is NameNode and HA enabled', function () {
  176. controller.set('tasks', commands);
  177. controller.set('content.hasManualSteps', true);
  178. controller.set('content.reassign.component_name', 'NAMENODE');
  179. isHaEnabled = true;
  180. controller.removeUnneededTasks();
  181. expect(controller.get('tasks').mapProperty('id')).to.eql([1, 3, 4, 5, 6, 7, 8]);
  182. });
  183. it('reassign component is HiveServer and db type is mysql', function () {
  184. controller.set('tasks', commandsForDB);
  185. controller.set('content.hasManualSteps', false);
  186. controller.set('content.databaseType', 'mysql');
  187. controller.set('content.reassign.component_name', 'HIVE_SERVER');
  188. isHaEnabled = false;
  189. controller.removeUnneededTasks();
  190. expect(controller.get('tasks').mapProperty('id')).to.eql([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]);
  191. });
  192. it('reassign component is HiveServer and db type is not mysql', function () {
  193. controller.set('tasks', commandsForDB);
  194. controller.set('content.hasManualSteps', false);
  195. controller.set('content.databaseType', 'derby');
  196. controller.set('content.reassign.component_name', 'HIVE_SERVER');
  197. isHaEnabled = false;
  198. controller.removeUnneededTasks();
  199. expect(controller.get('tasks').mapProperty('id')).to.eql([1, 2, 6, 8, 9, 10, 12]);
  200. });
  201. it('reassign component is Oozie Server and db type is derby', function () {
  202. controller.set('tasks', commandsForDB);
  203. controller.set('content.hasManualSteps', true);
  204. controller.set('content.databaseType', 'derby');
  205. controller.set('content.reassign.component_name', 'OOZIE_SERVER');
  206. isHaEnabled = false;
  207. controller.removeUnneededTasks();
  208. expect(controller.get('tasks').mapProperty('id')).to.eql([1,2,6,8,9]);
  209. });
  210. it('reassign component is Oozie Server and db type is mysql', function () {
  211. controller.set('content.hasManualSteps', false);
  212. controller.set('content.databaseType', 'mysql');
  213. controller.set('content.reassign.component_name', 'OOZIE_SERVER');
  214. isHaEnabled = false;
  215. controller.set('tasks', commandsForDB);
  216. controller.removeUnneededTasks();
  217. expect(controller.get('tasks').mapProperty('id')).to.eql([1,2,3,4,5,6,7,8,9,10,11,12]);
  218. });
  219. });
  220. describe('#initializeTasks()', function () {
  221. beforeEach(function () {
  222. controller.set('tasks', []);
  223. sinon.stub(controller, 'getHostComponentsNames', Em.K);
  224. sinon.stub(controller, 'removeUnneededTasks', Em.K);
  225. });
  226. afterEach(function () {
  227. controller.removeUnneededTasks.restore();
  228. controller.getHostComponentsNames.restore();
  229. });
  230. it('No commands', function () {
  231. controller.set('commands', []);
  232. controller.set('commandsForDB', []);
  233. controller.initializeTasks();
  234. expect(controller.get('tasks')).to.be.empty;
  235. });
  236. it('One command', function () {
  237. controller.set('commands', ['COMMAND1']);
  238. controller.set('commandsForDB', ['COMMAND1']);
  239. controller.initializeTasks();
  240. expect(controller.get('tasks')[0].get('id')).to.equal(0);
  241. expect(controller.get('tasks')[0].get('command')).to.equal('COMMAND1');
  242. });
  243. });
  244. describe('#hideRollbackButton()', function () {
  245. it('No showRollback command', function () {
  246. controller.set('tasks', [Em.Object.create({
  247. showRollback: false
  248. })]);
  249. controller.hideRollbackButton();
  250. expect(controller.get('tasks')[0].get('showRollback')).to.be.false;
  251. });
  252. it('showRollback command is present', function () {
  253. controller.set('tasks', [Em.Object.create({
  254. showRollback: true
  255. })]);
  256. controller.hideRollbackButton();
  257. expect(controller.get('tasks')[0].get('showRollback')).to.be.false;
  258. });
  259. });
  260. describe('#onComponentsTasksSuccess()', function () {
  261. beforeEach(function () {
  262. sinon.stub(controller, 'onTaskCompleted', Em.K);
  263. });
  264. afterEach(function () {
  265. controller.onTaskCompleted.restore();
  266. });
  267. it('No host-components', function () {
  268. controller.set('multiTaskCounter', 0);
  269. controller.set('hostComponents', []);
  270. controller.onComponentsTasksSuccess();
  271. expect(controller.get('multiTaskCounter')).to.equal(1);
  272. expect(controller.onTaskCompleted.calledOnce).to.be.true;
  273. });
  274. it('One host-component', function () {
  275. controller.set('multiTaskCounter', 0);
  276. controller.set('hostComponents', [
  277. {}
  278. ]);
  279. controller.onComponentsTasksSuccess();
  280. expect(controller.get('multiTaskCounter')).to.equal(1);
  281. expect(controller.onTaskCompleted.calledOnce).to.be.true;
  282. });
  283. it('two host-components', function () {
  284. controller.set('multiTaskCounter', 0);
  285. controller.set('hostComponents', [
  286. {},
  287. {}
  288. ]);
  289. controller.onComponentsTasksSuccess();
  290. expect(controller.get('multiTaskCounter')).to.equal(1);
  291. expect(controller.onTaskCompleted.called).to.be.false;
  292. });
  293. });
  294. describe('#stopServices()', function () {
  295. it('', function () {
  296. controller.stopServices();
  297. expect(App.ajax.send.calledOnce).to.be.true;
  298. });
  299. });
  300. describe('#createHostComponents()', function () {
  301. beforeEach(function () {
  302. sinon.stub(controller, 'createComponent', Em.K);
  303. });
  304. afterEach(function () {
  305. controller.createComponent.restore();
  306. });
  307. it('No host-components', function () {
  308. controller.set('hostComponents', []);
  309. controller.createHostComponents();
  310. expect(controller.get('multiTaskCounter')).to.equal(0);
  311. expect(controller.createComponent.called).to.be.false;
  312. });
  313. it('One host-component', function () {
  314. controller.set('hostComponents', ['COMP1']);
  315. controller.set('content.reassignHosts.target', 'host1');
  316. controller.set('content.reassign.service_id', 'SERVICE1');
  317. controller.createHostComponents();
  318. expect(controller.get('multiTaskCounter')).to.equal(0);
  319. expect(controller.createComponent.calledWith('COMP1', 'host1', 'SERVICE1')).to.be.true;
  320. });
  321. });
  322. describe('#onCreateComponent()', function () {
  323. it('', function () {
  324. sinon.stub(controller, 'onComponentsTasksSuccess', Em.K);
  325. controller.onCreateComponent();
  326. expect(controller.onComponentsTasksSuccess.calledOnce).to.be.true;
  327. controller.onComponentsTasksSuccess.restore();
  328. });
  329. });
  330. describe('#putHostComponentsInMaintenanceMode()', function () {
  331. beforeEach(function(){
  332. sinon.stub(controller, 'onComponentsTasksSuccess', Em.K);
  333. controller.set('content.reassignHosts.source', 'source');
  334. });
  335. afterEach(function(){
  336. controller.onComponentsTasksSuccess.restore();
  337. });
  338. it('No host-components', function () {
  339. controller.set('hostComponents', []);
  340. controller.putHostComponentsInMaintenanceMode();
  341. expect(App.ajax.send.called).to.be.false;
  342. expect(controller.get('multiTaskCounter')).to.equal(0);
  343. });
  344. it('One host-components', function () {
  345. controller.set('hostComponents', [{}]);
  346. controller.putHostComponentsInMaintenanceMode();
  347. expect(App.ajax.send.calledOnce).to.be.true;
  348. expect(controller.get('multiTaskCounter')).to.equal(0);
  349. });
  350. });
  351. describe('#installHostComponents()', function () {
  352. beforeEach(function () {
  353. sinon.stub(controller, 'updateComponent', Em.K);
  354. });
  355. afterEach(function () {
  356. controller.updateComponent.restore();
  357. });
  358. it('No host-components', function () {
  359. controller.set('hostComponents', []);
  360. controller.installHostComponents();
  361. expect(controller.get('multiTaskCounter')).to.equal(0);
  362. expect(controller.updateComponent.called).to.be.false;
  363. });
  364. it('One host-component', function () {
  365. controller.set('hostComponents', ['COMP1']);
  366. controller.set('content.reassignHosts.target', 'host1');
  367. controller.set('content.reassign.service_id', 'SERVICE1');
  368. controller.installHostComponents();
  369. expect(controller.get('multiTaskCounter')).to.equal(0);
  370. expect(controller.updateComponent.calledWith('COMP1', 'host1', 'SERVICE1', 'Install', 1)).to.be.true;
  371. });
  372. });
  373. describe('#reconfigure()', function () {
  374. it('', function () {
  375. sinon.stub(controller, 'loadConfigsTags', Em.K);
  376. controller.reconfigure();
  377. expect(controller.loadConfigsTags.calledOnce).to.be.true;
  378. controller.loadConfigsTags.restore();
  379. });
  380. });
  381. describe('#loadConfigsTags()', function () {
  382. it('', function () {
  383. controller.loadConfigsTags();
  384. expect(App.ajax.send.calledOnce).to.be.true;
  385. });
  386. });
  387. describe('#getConfigUrlParams()', function () {
  388. var testCases = [
  389. {
  390. componentName: 'NAMENODE',
  391. result: [
  392. "(type=hdfs-site&tag=1)",
  393. "(type=core-site&tag=2)"
  394. ]
  395. },
  396. {
  397. componentName: 'SECONDARY_NAMENODE',
  398. result: [
  399. "(type=hdfs-site&tag=1)",
  400. "(type=core-site&tag=2)"
  401. ]
  402. },
  403. {
  404. componentName: 'JOBTRACKER',
  405. result: [
  406. "(type=mapred-site&tag=4)"
  407. ]
  408. },
  409. {
  410. componentName: 'RESOURCEMANAGER',
  411. result: [
  412. "(type=yarn-site&tag=5)"
  413. ]
  414. },
  415. {
  416. componentName: 'APP_TIMELINE_SERVER',
  417. result: [
  418. "(type=yarn-site&tag=5)",
  419. "(type=yarn-env&tag=8)",
  420. ]
  421. },
  422. {
  423. componentName: 'OOZIE_SERVER',
  424. result: [
  425. "(type=oozie-site&tag=6)",
  426. "(type=core-site&tag=2)"
  427. ]
  428. },
  429. {
  430. componentName: 'WEBHCAT_SERVER',
  431. result: [
  432. "(type=webhcat-site&tag=7)"
  433. ]
  434. }
  435. ];
  436. var data = {
  437. Clusters: {
  438. desired_configs: {
  439. 'hdfs-site': {tag: 1},
  440. 'core-site': {tag: 2},
  441. 'hbase-site': {tag: 3},
  442. 'mapred-site': {tag: 4},
  443. 'yarn-site': {tag: 5},
  444. 'oozie-site': {tag: 6},
  445. 'webhcat-site': {tag: 7},
  446. 'yarn-env': {tag: 8}
  447. }
  448. }
  449. };
  450. var services = [];
  451. beforeEach(function () {
  452. sinon.stub(App.Service, 'find', function () {
  453. return services;
  454. });
  455. });
  456. afterEach(function () {
  457. App.Service.find.restore();
  458. });
  459. testCases.forEach(function (test) {
  460. it('get config of ' + test.componentName, function () {
  461. expect(controller.getConfigUrlParams(test.componentName, data)).to.eql(test.result);
  462. });
  463. });
  464. it('get config of NAMENODE when HBASE installed', function () {
  465. services = [
  466. {
  467. serviceName: 'HBASE'
  468. }
  469. ];
  470. expect(controller.getConfigUrlParams('NAMENODE', data)).to.eql([
  471. "(type=hdfs-site&tag=1)",
  472. "(type=core-site&tag=2)",
  473. "(type=hbase-site&tag=3)"
  474. ]);
  475. });
  476. });
  477. describe('#onLoadConfigsTags()', function () {
  478. it('', function () {
  479. sinon.stub(controller, 'getConfigUrlParams', function () {
  480. return [];
  481. });
  482. controller.set('content.reassign.component_name', 'COMP1');
  483. controller.onLoadConfigsTags({});
  484. expect(App.ajax.send.calledOnce).to.be.true;
  485. expect(controller.getConfigUrlParams.calledWith('COMP1', {})).to.be.true;
  486. controller.getConfigUrlParams.restore();
  487. });
  488. });
  489. describe('#onLoadConfigs()', function () {
  490. beforeEach(function () {
  491. sinon.stub(controller, 'setAdditionalConfigs', Em.K);
  492. sinon.stub(controller, 'setSecureConfigs', Em.K);
  493. sinon.stub(controller, 'setSpecificNamenodeConfigs', Em.K);
  494. sinon.stub(controller, 'setSpecificResourceMangerConfigs', Em.K);
  495. sinon.stub(controller, 'getComponentDir', Em.K);
  496. sinon.stub(controller, 'saveClusterStatus', Em.K);
  497. sinon.stub(controller, 'saveConfigsToServer', Em.K);
  498. sinon.stub(controller, 'saveServiceProperties', Em.K);
  499. controller.set('content.reassignHosts.target', 'host1');
  500. });
  501. afterEach(function () {
  502. controller.setAdditionalConfigs.restore();
  503. controller.setSecureConfigs.restore();
  504. controller.setSpecificNamenodeConfigs.restore();
  505. controller.setSpecificResourceMangerConfigs.restore();
  506. controller.getComponentDir.restore();
  507. controller.saveClusterStatus.restore();
  508. controller.saveConfigsToServer.restore();
  509. controller.saveServiceProperties.restore();
  510. });
  511. it('component is not NAMENODE', function () {
  512. controller.set('content.reassign.component_name', 'COMP1');
  513. controller.onLoadConfigs({items: []});
  514. expect(controller.setAdditionalConfigs.calledWith({}, 'COMP1', 'host1')).to.be.true;
  515. expect(controller.setSecureConfigs.calledWith([], {}, 'COMP1')).to.be.true;
  516. expect(controller.setSpecificNamenodeConfigs.called).to.be.false;
  517. expect(controller.getComponentDir.calledWith({}, 'COMP1')).to.be.true;
  518. expect(controller.saveClusterStatus.calledWith([])).to.be.true;
  519. expect(controller.saveConfigsToServer.calledWith({})).to.be.true;
  520. expect(controller.saveServiceProperties.calledWith({})).to.be.true;
  521. });
  522. it('component is NAMENODE, has configs', function () {
  523. controller.set('content.reassign.component_name', 'NAMENODE');
  524. controller.onLoadConfigs({items: [
  525. {
  526. type: 'hdfs-site',
  527. properties: {}
  528. }
  529. ]});
  530. expect(controller.setAdditionalConfigs.calledWith({'hdfs-site': {}}, 'NAMENODE', 'host1')).to.be.true;
  531. expect(controller.setSecureConfigs.calledWith([], {'hdfs-site': {}}, 'NAMENODE')).to.be.true;
  532. expect(controller.setSpecificNamenodeConfigs.calledWith({'hdfs-site': {}}, 'host1')).to.be.true;
  533. expect(controller.getComponentDir.calledWith({'hdfs-site': {}}, 'NAMENODE')).to.be.true;
  534. expect(controller.saveClusterStatus.calledWith([])).to.be.true;
  535. expect(controller.saveConfigsToServer.calledWith({'hdfs-site': {}})).to.be.true;
  536. expect(controller.saveServiceProperties.calledWith({'hdfs-site': {}})).to.be.true;
  537. });
  538. it('component is RESOURCEMANAGER, has configs', function () {
  539. controller.set('content.reassign.component_name', 'RESOURCEMANAGER');
  540. controller.onLoadConfigs({items: [
  541. {
  542. type: 'hdfs-site',
  543. properties: {}
  544. }
  545. ]});
  546. expect(controller.setAdditionalConfigs.calledWith({'hdfs-site': {}}, 'RESOURCEMANAGER', 'host1')).to.be.true;
  547. expect(controller.setSecureConfigs.calledWith([], {'hdfs-site': {}}, 'RESOURCEMANAGER')).to.be.true;
  548. expect(controller.setSpecificResourceMangerConfigs.calledWith({'hdfs-site': {}}, 'host1')).to.be.true;
  549. expect(controller.getComponentDir.calledWith({'hdfs-site': {}}, 'RESOURCEMANAGER')).to.be.true;
  550. expect(controller.saveClusterStatus.calledWith([])).to.be.true;
  551. expect(controller.saveConfigsToServer.calledWith({'hdfs-site': {}})).to.be.true;
  552. expect(controller.saveServiceProperties.calledWith({'hdfs-site': {}})).to.be.true;
  553. });
  554. });
  555. describe('#loadStep()', function () {
  556. var isHaEnabled = true;
  557. beforeEach(function () {
  558. controller.set('content.reassign.service_id', 'service1');
  559. sinon.stub(controller, 'onTaskStatusChange', Em.K);
  560. sinon.stub(controller, 'initializeTasks', Em.K);
  561. sinon.stub(App, 'get', function () {
  562. return isHaEnabled;
  563. });
  564. });
  565. afterEach(function () {
  566. controller.onTaskStatusChange.restore();
  567. controller.initializeTasks.restore();
  568. App.get.restore();
  569. });
  570. it('reassign component is NameNode and HA enabled', function () {
  571. isHaEnabled = true;
  572. controller.set('content.reassign.component_name', 'NAMENODE');
  573. controller.loadStep();
  574. expect(controller.get('hostComponents')).to.eql(['NAMENODE', 'ZKFC']);
  575. expect(controller.get('serviceName')).to.eql(['service1']);
  576. });
  577. it('reassign component is NameNode and HA disabled', function () {
  578. isHaEnabled = false;
  579. controller.set('content.reassign.component_name', 'NAMENODE');
  580. controller.loadStep();
  581. expect(controller.get('hostComponents')).to.eql(['NAMENODE']);
  582. expect(controller.get('serviceName')).to.eql(['service1']);
  583. });
  584. it('reassign component is JOBTRACKER and HA enabled', function () {
  585. isHaEnabled = true;
  586. controller.set('content.reassign.component_name', 'JOBTRACKER');
  587. controller.loadStep();
  588. expect(controller.get('hostComponents')).to.eql(['JOBTRACKER']);
  589. expect(controller.get('serviceName')).to.eql(['service1']);
  590. });
  591. it('reassign component is RESOURCEMANAGER and HA enabled', function () {
  592. isHaEnabled = true;
  593. controller.set('content.reassign.component_name', 'RESOURCEMANAGER');
  594. controller.loadStep();
  595. expect(controller.get('hostComponents')).to.eql(['RESOURCEMANAGER']);
  596. expect(controller.get('serviceName')).to.eql(['service1']);
  597. });
  598. });
  599. describe('#saveConfigsToServer()', function () {
  600. beforeEach(function () {
  601. sinon.stub(controller, 'getServiceConfigData', Em.K);
  602. });
  603. afterEach(function () {
  604. controller.getServiceConfigData.restore();
  605. });
  606. it('', function () {
  607. controller.saveConfigsToServer([1]);
  608. expect(controller.getServiceConfigData.calledWith([1])).to.be.true;
  609. expect(App.ajax.send.calledOnce).to.be.true;
  610. });
  611. });
  612. describe('#setSpecificNamenodeConfigs()', function () {
  613. var isHaEnabled = false;
  614. var service = Em.Object.create();
  615. beforeEach(function () {
  616. sinon.stub(App, 'get', function () {
  617. return isHaEnabled;
  618. });
  619. sinon.stub(App.Service, 'find', function () {
  620. return service;
  621. });
  622. controller.set('content.reassignHosts.source', 'host1');
  623. });
  624. afterEach(function () {
  625. App.get.restore();
  626. App.Service.find.restore();
  627. });
  628. it('HA isn\'t enabled and no HBASE or ACCUMULO service', function () {
  629. isHaEnabled = false;
  630. var configs = {};
  631. controller.setSpecificNamenodeConfigs(configs, 'host1');
  632. expect(configs).to.eql({});
  633. });
  634. it('HA isn\'t enabled and HBASE and ACCUMULO service', function () {
  635. isHaEnabled = false;
  636. service = Em.Object.create({
  637. isLoaded: true
  638. });
  639. var configs = {
  640. 'hbase-site': {
  641. 'hbase.rootdir': 'hdfs://localhost:8020/apps/hbase/data'
  642. },
  643. 'accumulo-site': {
  644. 'instance.volumes': 'hdfs://localhost:8020/apps/accumulo/data'
  645. }
  646. };
  647. controller.setSpecificNamenodeConfigs(configs, 'host1');
  648. expect(configs['hbase-site']['hbase.rootdir']).to.equal('hdfs://host1:8020/apps/hbase/data');
  649. expect(configs['accumulo-site']['instance.volumes']).to.equal('hdfs://host1:8020/apps/accumulo/data');
  650. });
  651. it('HA enabled and namenode 1', function () {
  652. isHaEnabled = true;
  653. var configs = {
  654. 'hdfs-site': {
  655. 'dfs.nameservices': 's',
  656. 'dfs.namenode.http-address.s.nn1': 'host1:50070',
  657. 'dfs.namenode.https-address.s.nn1': '',
  658. 'dfs.namenode.rpc-address.s.nn1': ''
  659. }
  660. };
  661. controller.setSpecificNamenodeConfigs(configs, 'host2');
  662. expect(configs['hdfs-site']).to.eql({
  663. "dfs.nameservices": "s",
  664. "dfs.namenode.http-address.s.nn1": "host2:50070",
  665. "dfs.namenode.https-address.s.nn1": "host2:50470",
  666. "dfs.namenode.rpc-address.s.nn1": "host2:8020"
  667. });
  668. });
  669. it('HA enabled and namenode 2', function () {
  670. isHaEnabled = true;
  671. var configs = {
  672. 'hdfs-site': {
  673. 'dfs.nameservices': 's',
  674. 'dfs.namenode.http-address.s.nn2': 'host2:50070',
  675. 'dfs.namenode.https-address.s.nn2': '',
  676. 'dfs.namenode.rpc-address.s.nn2': ''
  677. }
  678. };
  679. controller.setSpecificNamenodeConfigs(configs, 'host1');
  680. expect(configs['hdfs-site']).to.eql({
  681. "dfs.nameservices": "s",
  682. "dfs.namenode.http-address.s.nn2": "host1:50070",
  683. "dfs.namenode.https-address.s.nn2": "host1:50470",
  684. "dfs.namenode.rpc-address.s.nn2": "host1:8020"
  685. });
  686. });
  687. });
  688. describe('#setSpecificResourceMangerConfigs()', function () {
  689. var isRMHaEnabled = false;
  690. var service = Em.Object.create();
  691. beforeEach(function () {
  692. sinon.stub(App, 'get', function () {
  693. return isRMHaEnabled;
  694. });
  695. controller.set('content.reassignHosts.source', 'host1');
  696. });
  697. afterEach(function () {
  698. App.get.restore();
  699. });
  700. it('HA isn\'t enabled', function () {
  701. isRMHaEnabled = false;
  702. var configs = {};
  703. controller.setSpecificResourceMangerConfigs(configs, 'host1');
  704. expect(configs).to.eql({});
  705. });
  706. it('HA enabled and resource manager 1', function () {
  707. isRMHaEnabled = true;
  708. var configs = {
  709. 'yarn-site': {
  710. 'yarn.resourcemanager.hostname.rm1': 'host1'
  711. }
  712. };
  713. controller.setSpecificResourceMangerConfigs(configs, 'host2');
  714. expect(configs['yarn-site']).to.eql({
  715. 'yarn.resourcemanager.hostname.rm1': 'host2'
  716. });
  717. });
  718. it('HA enabled and resource manager 2', function () {
  719. isRMHaEnabled = true;
  720. var configs = {
  721. 'yarn-site': {
  722. 'yarn.resourcemanager.hostname.rm2': 'host2'
  723. }
  724. };
  725. controller.setSpecificResourceMangerConfigs(configs, 'host1');
  726. expect(configs['yarn-site']).to.eql({
  727. 'yarn.resourcemanager.hostname.rm2': 'host1'
  728. });
  729. });
  730. });
  731. describe('#setSecureConfigs()', function () {
  732. it('undefined component and security disabled', function () {
  733. var secureConfigs = [];
  734. controller.set('content.securityEnabled', false);
  735. controller.set('secureConfigsMap', []);
  736. expect(controller.setSecureConfigs(secureConfigs, {}, 'COMP1')).to.be.false;
  737. expect(secureConfigs).to.eql([]);
  738. });
  739. it('undefined component and security enabled', function () {
  740. var secureConfigs = [];
  741. controller.set('content.securityEnabled', true);
  742. controller.set('secureConfigsMap', []);
  743. expect(controller.setSecureConfigs(secureConfigs, {}, 'COMP1')).to.be.false;
  744. expect(secureConfigs).to.eql([]);
  745. });
  746. it('component exist and security disabled', function () {
  747. var secureConfigs = [];
  748. controller.set('content.securityEnabled', false);
  749. controller.set('secureConfigsMap', [{
  750. componentName: 'COMP1'
  751. }]);
  752. expect(controller.setSecureConfigs(secureConfigs, {}, 'COMP1')).to.be.false;
  753. expect(secureConfigs).to.eql([]);
  754. });
  755. it('component exist and security enabled', function () {
  756. var secureConfigs = [];
  757. var configs = {'s1': {
  758. 'k1': 'kValue',
  759. 'p1': 'pValue'
  760. }};
  761. controller.set('content.securityEnabled', true);
  762. controller.set('secureConfigsMap', [{
  763. componentName: 'COMP1',
  764. configs: [{
  765. site: 's1',
  766. keytab: 'k1',
  767. principal: 'p1'
  768. }]
  769. }]);
  770. expect(controller.setSecureConfigs(secureConfigs, configs, 'COMP1')).to.be.true;
  771. expect(secureConfigs).to.eql([
  772. {
  773. "keytab": "kValue",
  774. "principal": "pValue"
  775. }
  776. ]);
  777. });
  778. });
  779. describe('#getComponentDir()', function () {
  780. var configs = {
  781. 'hdfs-site': {
  782. 'dfs.name.dir': 'case1',
  783. 'dfs.namenode.name.dir': 'case2',
  784. 'dfs.namenode.checkpoint.dir': 'case3'
  785. },
  786. 'core-site': {
  787. 'fs.checkpoint.dir': 'case4'
  788. }
  789. };
  790. it('unknown component name', function () {
  791. expect(controller.getComponentDir(configs, 'COMP1')).to.be.empty;
  792. });
  793. it('NAMENODE component', function () {
  794. expect(controller.getComponentDir(configs, 'NAMENODE')).to.equal('case2');
  795. });
  796. it('SECONDARY_NAMENODE component', function () {
  797. expect(controller.getComponentDir(configs, 'SECONDARY_NAMENODE')).to.equal('case3');
  798. });
  799. });
  800. describe('#saveClusterStatus()', function () {
  801. var mock = {
  802. saveComponentDir: Em.K,
  803. saveSecureConfigs: Em.K
  804. };
  805. beforeEach(function () {
  806. sinon.stub(App.clusterStatus, 'setClusterStatus', Em.K);
  807. sinon.stub(App.router, 'get', function() {
  808. return mock;
  809. });
  810. sinon.spy(mock, 'saveComponentDir');
  811. sinon.spy(mock, 'saveSecureConfigs');
  812. });
  813. afterEach(function () {
  814. App.clusterStatus.setClusterStatus.restore();
  815. App.router.get.restore();
  816. mock.saveSecureConfigs.restore();
  817. mock.saveComponentDir.restore();
  818. });
  819. it('componentDir undefined and secureConfigs is empty', function () {
  820. expect(controller.saveClusterStatus([], null)).to.be.false;
  821. });
  822. it('componentDir defined and secureConfigs is empty', function () {
  823. expect(controller.saveClusterStatus([], 'dir1')).to.be.true;
  824. expect(mock.saveComponentDir.calledWith('dir1')).to.be.true;
  825. expect(mock.saveSecureConfigs.calledWith([])).to.be.true;
  826. });
  827. it('componentDir undefined and secureConfigs has data', function () {
  828. expect(controller.saveClusterStatus([1], null)).to.be.true;
  829. expect(mock.saveComponentDir.calledWith(null)).to.be.true;
  830. expect(mock.saveSecureConfigs.calledWith([1])).to.be.true;
  831. });
  832. it('componentDir defined and secureConfigs has data', function () {
  833. expect(controller.saveClusterStatus([1], 'dir1')).to.be.true;
  834. expect(mock.saveComponentDir.calledWith('dir1')).to.be.true;
  835. expect(mock.saveSecureConfigs.calledWith([1])).to.be.true;
  836. });
  837. });
  838. describe('#onSaveConfigs()', function () {
  839. beforeEach(function () {
  840. sinon.stub(controller, 'onTaskCompleted', Em.K);
  841. });
  842. afterEach(function () {
  843. controller.onTaskCompleted.restore();
  844. });
  845. it('', function () {
  846. controller.onSaveConfigs();
  847. expect(controller.onTaskCompleted.calledOnce).to.be.true;
  848. });
  849. });
  850. describe('#startZooKeeperServers()', function () {
  851. beforeEach(function () {
  852. sinon.stub(controller, 'updateComponent', Em.K);
  853. });
  854. afterEach(function () {
  855. controller.updateComponent.restore();
  856. });
  857. it('', function () {
  858. controller.set('content.masterComponentHosts', [{
  859. component: 'ZOOKEEPER_SERVER',
  860. hostName: 'host1'
  861. }]);
  862. controller.startZooKeeperServers();
  863. expect(controller.updateComponent.calledWith('ZOOKEEPER_SERVER', ['host1'], 'ZOOKEEPER', 'Start')).to.be.true;
  864. });
  865. });
  866. describe('#startNameNode()', function () {
  867. beforeEach(function () {
  868. sinon.stub(controller, 'updateComponent', Em.K);
  869. });
  870. afterEach(function () {
  871. controller.updateComponent.restore();
  872. });
  873. it('reassign host does not match current', function () {
  874. controller.set('content.masterComponentHosts', [{
  875. component: 'NAMENODE',
  876. hostName: 'host1'
  877. }]);
  878. controller.set('content.reassignHosts.source', 'host2');
  879. controller.startNameNode();
  880. expect(controller.updateComponent.calledWith('NAMENODE', ['host1'], 'HDFS', 'Start')).to.be.true;
  881. });
  882. it('reassign host matches current', function () {
  883. controller.set('content.masterComponentHosts', [{
  884. component: 'NAMENODE',
  885. hostName: 'host1'
  886. }]);
  887. controller.set('content.reassignHosts.source', 'host1');
  888. controller.startNameNode();
  889. expect(controller.updateComponent.calledWith('NAMENODE', [], 'HDFS', 'Start')).to.be.true;
  890. });
  891. });
  892. describe('#startServices()', function () {
  893. before(function () {
  894. sinon.stub(App.router, 'get').returns({"skip.service.checks": "false"});
  895. });
  896. after(function () {
  897. App.router.get.restore();
  898. });
  899. it('', function () {
  900. controller.startServices();
  901. expect(App.ajax.send.calledOnce).to.be.true;
  902. });
  903. });
  904. describe('#deleteHostComponents()', function () {
  905. it('No host components', function () {
  906. controller.set('hostComponents', []);
  907. controller.set('content.reassignHosts.source', 'host1');
  908. controller.deleteHostComponents();
  909. expect(App.ajax.send.called).to.be.false;
  910. });
  911. it('delete two components', function () {
  912. controller.set('hostComponents', [1, 2]);
  913. controller.set('content.reassignHosts.source', 'host1');
  914. controller.deleteHostComponents();
  915. expect(App.ajax.send.getCall(0).args[0].data).to.eql({
  916. "hostName": "host1",
  917. "componentName": 1
  918. });
  919. expect(App.ajax.send.getCall(1).args[0].data).to.eql({
  920. "hostName": "host1",
  921. "componentName": 2
  922. });
  923. });
  924. });
  925. describe('#onDeleteHostComponentsError()', function () {
  926. beforeEach(function () {
  927. sinon.stub(controller, 'onComponentsTasksSuccess', Em.K);
  928. sinon.stub(controller, 'onTaskError', Em.K);
  929. });
  930. afterEach(function () {
  931. controller.onComponentsTasksSuccess.restore();
  932. controller.onTaskError.restore();
  933. });
  934. it('task success', function () {
  935. var error = {
  936. responseText: 'org.apache.ambari.server.controller.spi.NoSuchResourceException'
  937. }
  938. controller.onDeleteHostComponentsError(error);
  939. expect(controller.onComponentsTasksSuccess.calledOnce).to.be.true;
  940. });
  941. it('unknown error', function () {
  942. var error = {
  943. responseText: ''
  944. }
  945. controller.onDeleteHostComponentsError(error);
  946. expect(controller.onTaskError.calledOnce).to.be.true;
  947. });
  948. });
  949. describe('#done()', function () {
  950. beforeEach(function () {
  951. sinon.stub(controller, 'removeObserver', Em.K);
  952. sinon.stub(App.router, 'send', Em.K);
  953. });
  954. afterEach(function () {
  955. controller.removeObserver.restore();
  956. App.router.send.restore();
  957. });
  958. it('submit disabled', function () {
  959. controller.set('isSubmitDisabled', true);
  960. controller.done();
  961. expect(App.router.send.called).to.be.false;
  962. });
  963. it('submit enabled and does not have manual steps', function () {
  964. controller.set('isSubmitDisabled', false);
  965. controller.set('content.hasManualSteps', false);
  966. controller.done();
  967. expect(controller.removeObserver.calledWith('tasks.@each.status', controller, 'onTaskStatusChange')).to.be.true;
  968. expect(App.router.send.calledWith('complete')).to.be.true;
  969. });
  970. it('submit enabled and has manual steps', function () {
  971. controller.set('isSubmitDisabled', false);
  972. controller.set('content.hasManualSteps', true);
  973. controller.done();
  974. expect(controller.removeObserver.calledWith('tasks.@each.status', controller, 'onTaskStatusChange')).to.be.true;
  975. expect(App.router.send.calledWith('next')).to.be.true;
  976. });
  977. });
  978. describe('#getServiceConfigData()', function () {
  979. var services = [];
  980. var stackServices = [];
  981. beforeEach(function () {
  982. sinon.stub(App.Service, 'find', function () {
  983. return services;
  984. });
  985. sinon.stub(App.StackService, 'find', function () {
  986. return stackServices;
  987. });
  988. });
  989. afterEach(function () {
  990. App.Service.find.restore();
  991. App.StackService.find.restore();
  992. });
  993. it('No services', function () {
  994. services = [];
  995. controller.set('content.reassign.component_name', 'COMP1');
  996. expect(controller.getServiceConfigData([])).to.eql([]);
  997. });
  998. it('No services in stackServices', function () {
  999. services = [Em.Object.create({serviceName: 'S1'})];
  1000. stackServices = [];
  1001. controller.set('content.reassign.component_name', 'COMP1');
  1002. expect(controller.getServiceConfigData([])).to.eql([]);
  1003. });
  1004. it('Services in stackServicesm but configTypesRendered is empty', function () {
  1005. services = [Em.Object.create({serviceName: 'S1'})];
  1006. stackServices = [Em.Object.create({
  1007. serviceName: 'S1',
  1008. configTypesRendered: {}
  1009. })];
  1010. controller.set('content.reassign.component_name', 'COMP1');
  1011. expect(controller.getServiceConfigData([])[0]).to.equal("{\"Clusters\":{\"desired_config\":[]}}");
  1012. });
  1013. it('Services in stackServicesm and configTypesRendered has data, but configs is empty', function () {
  1014. services = [Em.Object.create({serviceName: 'S1'})];
  1015. stackServices = [
  1016. Em.Object.create({
  1017. serviceName: 'S1',
  1018. configTypesRendered: {'type1': {}}
  1019. })
  1020. ];
  1021. controller.set('content.reassign.component_name', 'COMP1');
  1022. expect(controller.getServiceConfigData([])[0]).to.equal("{\"Clusters\":{\"desired_config\":[]}}");
  1023. });
  1024. it('Services in stackServicesm and configTypesRendered has data, and configs present', function () {
  1025. services = [Em.Object.create({serviceName: 'S1'})];
  1026. stackServices = [
  1027. Em.Object.create({
  1028. serviceName: 'S1',
  1029. configTypesRendered: {'type1': {}}
  1030. })
  1031. ];
  1032. var configs = {
  1033. 'type1': {
  1034. 'prop1': 'value1'
  1035. }
  1036. };
  1037. controller.set('content.reassign.component_name', 'COMP1');
  1038. expect(JSON.parse(controller.getServiceConfigData(configs)[0]).Clusters.desired_config.length).to.equal(1);
  1039. });
  1040. });
  1041. describe('#testsMySqlServer()', function () {
  1042. beforeEach(function() {
  1043. sinon.stub(App.HostComponent, 'find', function() {
  1044. return Em.A([
  1045. Em.Object.create({
  1046. 'componentName': 'MYSQL_SERVER',
  1047. 'hostName': 'c6401.ambari.apache.org'
  1048. })
  1049. ]);
  1050. });
  1051. });
  1052. afterEach(function() {
  1053. App.HostComponent.find.restore();
  1054. });
  1055. it('Cleans MySql Server', function () {
  1056. controller.cleanMySqlServer();
  1057. expect(App.ajax.send.calledOnce).to.be.true;
  1058. });
  1059. it('Configures MySql Server', function () {
  1060. controller.configureMySqlServer();
  1061. expect(App.ajax.send.calledOnce).to.be.true;
  1062. });
  1063. });
  1064. });