step4_controller_test.js 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195
  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. 'accumulo-site': {tag: 9}
  448. }
  449. }
  450. };
  451. var services = [];
  452. beforeEach(function () {
  453. sinon.stub(App.Service, 'find', function () {
  454. return services;
  455. });
  456. });
  457. afterEach(function () {
  458. App.Service.find.restore();
  459. });
  460. testCases.forEach(function (test) {
  461. it('get config of ' + test.componentName, function () {
  462. expect(controller.getConfigUrlParams(test.componentName, data)).to.eql(test.result);
  463. });
  464. });
  465. it('get config of NAMENODE when HBASE installed', function () {
  466. services = [
  467. {
  468. serviceName: 'HBASE'
  469. }
  470. ];
  471. expect(controller.getConfigUrlParams('NAMENODE', data)).to.eql([
  472. "(type=hdfs-site&tag=1)",
  473. "(type=core-site&tag=2)",
  474. "(type=hbase-site&tag=3)"
  475. ]);
  476. });
  477. it('get config of NAMENODE when ACCUMULO installed', function () {
  478. services = [
  479. {
  480. serviceName: 'ACCUMULO'
  481. }
  482. ];
  483. expect(controller.getConfigUrlParams('NAMENODE', data)).to.eql([
  484. "(type=hdfs-site&tag=1)",
  485. "(type=core-site&tag=2)",
  486. "(type=accumulo-site&tag=9)"
  487. ]);
  488. });
  489. });
  490. describe('#onLoadConfigsTags()', function () {
  491. it('', function () {
  492. sinon.stub(controller, 'getConfigUrlParams', function () {
  493. return [];
  494. });
  495. controller.set('content.reassign.component_name', 'COMP1');
  496. controller.onLoadConfigsTags({});
  497. expect(App.ajax.send.calledOnce).to.be.true;
  498. expect(controller.getConfigUrlParams.calledWith('COMP1', {})).to.be.true;
  499. controller.getConfigUrlParams.restore();
  500. });
  501. });
  502. describe('#onLoadConfigs()', function () {
  503. beforeEach(function () {
  504. sinon.stub(controller, 'setAdditionalConfigs', Em.K);
  505. sinon.stub(controller, 'setSecureConfigs', Em.K);
  506. sinon.stub(controller, 'setSpecificNamenodeConfigs', Em.K);
  507. sinon.stub(controller, 'setSpecificResourceMangerConfigs', Em.K);
  508. sinon.stub(controller, 'getComponentDir', Em.K);
  509. sinon.stub(controller, 'saveClusterStatus', Em.K);
  510. sinon.stub(controller, 'saveConfigsToServer', Em.K);
  511. sinon.stub(controller, 'saveServiceProperties', Em.K);
  512. controller.set('content.reassignHosts.target', 'host1');
  513. });
  514. afterEach(function () {
  515. controller.setAdditionalConfigs.restore();
  516. controller.setSecureConfigs.restore();
  517. controller.setSpecificNamenodeConfigs.restore();
  518. controller.setSpecificResourceMangerConfigs.restore();
  519. controller.getComponentDir.restore();
  520. controller.saveClusterStatus.restore();
  521. controller.saveConfigsToServer.restore();
  522. controller.saveServiceProperties.restore();
  523. });
  524. it('component is not NAMENODE', function () {
  525. controller.set('content.reassign.component_name', 'COMP1');
  526. controller.onLoadConfigs({items: []});
  527. expect(controller.setAdditionalConfigs.calledWith({}, 'COMP1', 'host1')).to.be.true;
  528. expect(controller.setSecureConfigs.calledWith([], {}, 'COMP1')).to.be.true;
  529. expect(controller.setSpecificNamenodeConfigs.called).to.be.false;
  530. expect(controller.getComponentDir.calledWith({}, 'COMP1')).to.be.true;
  531. expect(controller.saveClusterStatus.calledWith([])).to.be.true;
  532. expect(controller.saveConfigsToServer.calledWith({})).to.be.true;
  533. expect(controller.saveServiceProperties.calledWith({})).to.be.true;
  534. });
  535. it('component is NAMENODE, has configs', function () {
  536. controller.set('content.reassign.component_name', 'NAMENODE');
  537. controller.onLoadConfigs({items: [
  538. {
  539. type: 'hdfs-site',
  540. properties: {}
  541. }
  542. ]});
  543. expect(controller.setAdditionalConfigs.calledWith({'hdfs-site': {}}, 'NAMENODE', 'host1')).to.be.true;
  544. expect(controller.setSecureConfigs.calledWith([], {'hdfs-site': {}}, 'NAMENODE')).to.be.true;
  545. expect(controller.setSpecificNamenodeConfigs.calledWith({'hdfs-site': {}}, 'host1')).to.be.true;
  546. expect(controller.getComponentDir.calledWith({'hdfs-site': {}}, 'NAMENODE')).to.be.true;
  547. expect(controller.saveClusterStatus.calledWith([])).to.be.true;
  548. expect(controller.saveConfigsToServer.calledWith({'hdfs-site': {}})).to.be.true;
  549. expect(controller.saveServiceProperties.calledWith({'hdfs-site': {}})).to.be.true;
  550. });
  551. it('component is RESOURCEMANAGER, has configs', function () {
  552. controller.set('content.reassign.component_name', 'RESOURCEMANAGER');
  553. controller.onLoadConfigs({items: [
  554. {
  555. type: 'hdfs-site',
  556. properties: {}
  557. }
  558. ]});
  559. expect(controller.setAdditionalConfigs.calledWith({'hdfs-site': {}}, 'RESOURCEMANAGER', 'host1')).to.be.true;
  560. expect(controller.setSecureConfigs.calledWith([], {'hdfs-site': {}}, 'RESOURCEMANAGER')).to.be.true;
  561. expect(controller.setSpecificResourceMangerConfigs.calledWith({'hdfs-site': {}}, 'host1')).to.be.true;
  562. expect(controller.getComponentDir.calledWith({'hdfs-site': {}}, 'RESOURCEMANAGER')).to.be.true;
  563. expect(controller.saveClusterStatus.calledWith([])).to.be.true;
  564. expect(controller.saveConfigsToServer.calledWith({'hdfs-site': {}})).to.be.true;
  565. expect(controller.saveServiceProperties.calledWith({'hdfs-site': {}})).to.be.true;
  566. });
  567. });
  568. describe('#loadStep()', function () {
  569. var isHaEnabled = true;
  570. beforeEach(function () {
  571. controller.set('content.reassign.service_id', 'service1');
  572. sinon.stub(controller, 'onTaskStatusChange', Em.K);
  573. sinon.stub(controller, 'initializeTasks', Em.K);
  574. sinon.stub(App, 'get', function () {
  575. return isHaEnabled;
  576. });
  577. });
  578. afterEach(function () {
  579. controller.onTaskStatusChange.restore();
  580. controller.initializeTasks.restore();
  581. App.get.restore();
  582. });
  583. it('reassign component is NameNode and HA enabled', function () {
  584. isHaEnabled = true;
  585. controller.set('content.reassign.component_name', 'NAMENODE');
  586. controller.loadStep();
  587. expect(controller.get('hostComponents')).to.eql(['NAMENODE', 'ZKFC']);
  588. expect(controller.get('serviceName')).to.eql(['service1']);
  589. });
  590. it('reassign component is NameNode and HA disabled', function () {
  591. isHaEnabled = false;
  592. controller.set('content.reassign.component_name', 'NAMENODE');
  593. controller.loadStep();
  594. expect(controller.get('hostComponents')).to.eql(['NAMENODE']);
  595. expect(controller.get('serviceName')).to.eql(['service1']);
  596. });
  597. it('reassign component is JOBTRACKER and HA enabled', function () {
  598. isHaEnabled = true;
  599. controller.set('content.reassign.component_name', 'JOBTRACKER');
  600. controller.loadStep();
  601. expect(controller.get('hostComponents')).to.eql(['JOBTRACKER']);
  602. expect(controller.get('serviceName')).to.eql(['service1']);
  603. });
  604. it('reassign component is RESOURCEMANAGER and HA enabled', function () {
  605. isHaEnabled = true;
  606. controller.set('content.reassign.component_name', 'RESOURCEMANAGER');
  607. controller.loadStep();
  608. expect(controller.get('hostComponents')).to.eql(['RESOURCEMANAGER']);
  609. expect(controller.get('serviceName')).to.eql(['service1']);
  610. });
  611. });
  612. describe('#saveConfigsToServer()', function () {
  613. beforeEach(function () {
  614. sinon.stub(controller, 'getServiceConfigData', Em.K);
  615. });
  616. afterEach(function () {
  617. controller.getServiceConfigData.restore();
  618. });
  619. it('', function () {
  620. controller.saveConfigsToServer([1]);
  621. expect(controller.getServiceConfigData.calledWith([1])).to.be.true;
  622. expect(App.ajax.send.calledOnce).to.be.true;
  623. });
  624. });
  625. describe('#setSpecificNamenodeConfigs()', function () {
  626. var isHaEnabled = false;
  627. var service = Em.Object.create();
  628. beforeEach(function () {
  629. sinon.stub(App, 'get', function () {
  630. return isHaEnabled;
  631. });
  632. sinon.stub(App.Service, 'find', function () {
  633. return service;
  634. });
  635. controller.set('content.reassignHosts.source', 'host1');
  636. });
  637. afterEach(function () {
  638. App.get.restore();
  639. App.Service.find.restore();
  640. });
  641. it('HA isn\'t enabled and no HBASE or ACCUMULO service', function () {
  642. isHaEnabled = false;
  643. var configs = {};
  644. controller.setSpecificNamenodeConfigs(configs, 'host1');
  645. expect(configs).to.eql({});
  646. });
  647. it('HA isn\'t enabled and HBASE and ACCUMULO service', function () {
  648. isHaEnabled = false;
  649. service = Em.Object.create({
  650. isLoaded: true
  651. });
  652. var configs = {
  653. 'hbase-site': {
  654. 'hbase.rootdir': 'hdfs://localhost:8020/apps/hbase/data'
  655. },
  656. 'accumulo-site': {
  657. 'instance.volumes': 'hdfs://localhost:8020/apps/accumulo/data'
  658. }
  659. };
  660. controller.setSpecificNamenodeConfigs(configs, 'host1');
  661. expect(configs['hbase-site']['hbase.rootdir']).to.equal('hdfs://host1:8020/apps/hbase/data');
  662. expect(configs['accumulo-site']['instance.volumes']).to.equal('hdfs://host1:8020/apps/accumulo/data');
  663. });
  664. it('HA enabled and namenode 1', function () {
  665. isHaEnabled = true;
  666. var configs = {
  667. 'hdfs-site': {
  668. 'dfs.nameservices': 's',
  669. 'dfs.namenode.http-address.s.nn1': 'host1:50070',
  670. 'dfs.namenode.https-address.s.nn1': '',
  671. 'dfs.namenode.rpc-address.s.nn1': ''
  672. }
  673. };
  674. controller.setSpecificNamenodeConfigs(configs, 'host2');
  675. expect(configs['hdfs-site']).to.eql({
  676. "dfs.nameservices": "s",
  677. "dfs.namenode.http-address.s.nn1": "host2:50070",
  678. "dfs.namenode.https-address.s.nn1": "host2:50470",
  679. "dfs.namenode.rpc-address.s.nn1": "host2:8020"
  680. });
  681. });
  682. it('HA enabled and namenode 2', function () {
  683. isHaEnabled = true;
  684. var configs = {
  685. 'hdfs-site': {
  686. 'dfs.nameservices': 's',
  687. 'dfs.namenode.http-address.s.nn2': 'host2:50070',
  688. 'dfs.namenode.https-address.s.nn2': '',
  689. 'dfs.namenode.rpc-address.s.nn2': ''
  690. }
  691. };
  692. controller.setSpecificNamenodeConfigs(configs, 'host1');
  693. expect(configs['hdfs-site']).to.eql({
  694. "dfs.nameservices": "s",
  695. "dfs.namenode.http-address.s.nn2": "host1:50070",
  696. "dfs.namenode.https-address.s.nn2": "host1:50470",
  697. "dfs.namenode.rpc-address.s.nn2": "host1:8020"
  698. });
  699. });
  700. });
  701. describe('#setSpecificResourceMangerConfigs()', function () {
  702. var isRMHaEnabled = false;
  703. var service = Em.Object.create();
  704. beforeEach(function () {
  705. sinon.stub(App, 'get', function () {
  706. return isRMHaEnabled;
  707. });
  708. controller.set('content.reassignHosts.source', 'host1');
  709. });
  710. afterEach(function () {
  711. App.get.restore();
  712. });
  713. it('HA isn\'t enabled', function () {
  714. isRMHaEnabled = false;
  715. var configs = {};
  716. controller.setSpecificResourceMangerConfigs(configs, 'host1');
  717. expect(configs).to.eql({});
  718. });
  719. it('HA enabled and resource manager 1', function () {
  720. isRMHaEnabled = true;
  721. var configs = {
  722. 'yarn-site': {
  723. 'yarn.resourcemanager.hostname.rm1': 'host1'
  724. }
  725. };
  726. controller.setSpecificResourceMangerConfigs(configs, 'host2');
  727. expect(configs['yarn-site']).to.eql({
  728. 'yarn.resourcemanager.hostname.rm1': 'host2'
  729. });
  730. });
  731. it('HA enabled and resource manager 2', function () {
  732. isRMHaEnabled = true;
  733. var configs = {
  734. 'yarn-site': {
  735. 'yarn.resourcemanager.hostname.rm2': 'host2'
  736. }
  737. };
  738. controller.setSpecificResourceMangerConfigs(configs, 'host1');
  739. expect(configs['yarn-site']).to.eql({
  740. 'yarn.resourcemanager.hostname.rm2': 'host1'
  741. });
  742. });
  743. });
  744. describe('#setSecureConfigs()', function () {
  745. it('undefined component and security disabled', function () {
  746. var secureConfigs = [];
  747. controller.set('content.securityEnabled', false);
  748. controller.set('secureConfigsMap', []);
  749. expect(controller.setSecureConfigs(secureConfigs, {}, 'COMP1')).to.be.false;
  750. expect(secureConfigs).to.eql([]);
  751. });
  752. it('undefined component and security enabled', function () {
  753. var secureConfigs = [];
  754. controller.set('content.securityEnabled', true);
  755. controller.set('secureConfigsMap', []);
  756. expect(controller.setSecureConfigs(secureConfigs, {}, 'COMP1')).to.be.false;
  757. expect(secureConfigs).to.eql([]);
  758. });
  759. it('component exist and security disabled', function () {
  760. var secureConfigs = [];
  761. controller.set('content.securityEnabled', false);
  762. controller.set('secureConfigsMap', [{
  763. componentName: 'COMP1'
  764. }]);
  765. expect(controller.setSecureConfigs(secureConfigs, {}, 'COMP1')).to.be.false;
  766. expect(secureConfigs).to.eql([]);
  767. });
  768. it('component exist and security enabled', function () {
  769. var secureConfigs = [];
  770. var configs = {'s1': {
  771. 'k1': 'kValue',
  772. 'p1': 'pValue'
  773. }};
  774. controller.set('content.securityEnabled', true);
  775. controller.set('secureConfigsMap', [{
  776. componentName: 'COMP1',
  777. configs: [{
  778. site: 's1',
  779. keytab: 'k1',
  780. principal: 'p1'
  781. }]
  782. }]);
  783. expect(controller.setSecureConfigs(secureConfigs, configs, 'COMP1')).to.be.true;
  784. expect(secureConfigs).to.eql([
  785. {
  786. "keytab": "kValue",
  787. "principal": "pValue"
  788. }
  789. ]);
  790. });
  791. });
  792. describe('#getComponentDir()', function () {
  793. var configs = {
  794. 'hdfs-site': {
  795. 'dfs.name.dir': 'case1',
  796. 'dfs.namenode.name.dir': 'case2',
  797. 'dfs.namenode.checkpoint.dir': 'case3'
  798. },
  799. 'core-site': {
  800. 'fs.checkpoint.dir': 'case4'
  801. }
  802. };
  803. it('unknown component name', function () {
  804. expect(controller.getComponentDir(configs, 'COMP1')).to.be.empty;
  805. });
  806. it('NAMENODE component', function () {
  807. expect(controller.getComponentDir(configs, 'NAMENODE')).to.equal('case2');
  808. });
  809. it('SECONDARY_NAMENODE component', function () {
  810. expect(controller.getComponentDir(configs, 'SECONDARY_NAMENODE')).to.equal('case3');
  811. });
  812. });
  813. describe('#saveClusterStatus()', function () {
  814. var mock = {
  815. saveComponentDir: Em.K,
  816. saveSecureConfigs: Em.K
  817. };
  818. beforeEach(function () {
  819. sinon.stub(App.clusterStatus, 'setClusterStatus', Em.K);
  820. sinon.stub(App.router, 'get', function() {
  821. return mock;
  822. });
  823. sinon.spy(mock, 'saveComponentDir');
  824. sinon.spy(mock, 'saveSecureConfigs');
  825. });
  826. afterEach(function () {
  827. App.clusterStatus.setClusterStatus.restore();
  828. App.router.get.restore();
  829. mock.saveSecureConfigs.restore();
  830. mock.saveComponentDir.restore();
  831. });
  832. it('componentDir undefined and secureConfigs is empty', function () {
  833. expect(controller.saveClusterStatus([], null)).to.be.false;
  834. });
  835. it('componentDir defined and secureConfigs is empty', function () {
  836. expect(controller.saveClusterStatus([], 'dir1')).to.be.true;
  837. expect(mock.saveComponentDir.calledWith('dir1')).to.be.true;
  838. expect(mock.saveSecureConfigs.calledWith([])).to.be.true;
  839. });
  840. it('componentDir undefined and secureConfigs has data', function () {
  841. expect(controller.saveClusterStatus([1], null)).to.be.true;
  842. expect(mock.saveComponentDir.calledWith(null)).to.be.true;
  843. expect(mock.saveSecureConfigs.calledWith([1])).to.be.true;
  844. });
  845. it('componentDir defined and secureConfigs has data', function () {
  846. expect(controller.saveClusterStatus([1], 'dir1')).to.be.true;
  847. expect(mock.saveComponentDir.calledWith('dir1')).to.be.true;
  848. expect(mock.saveSecureConfigs.calledWith([1])).to.be.true;
  849. });
  850. });
  851. describe('#onSaveConfigs()', function () {
  852. beforeEach(function () {
  853. sinon.stub(controller, 'onTaskCompleted', Em.K);
  854. });
  855. afterEach(function () {
  856. controller.onTaskCompleted.restore();
  857. });
  858. it('', function () {
  859. controller.onSaveConfigs();
  860. expect(controller.onTaskCompleted.calledOnce).to.be.true;
  861. });
  862. });
  863. describe('#startZooKeeperServers()', function () {
  864. beforeEach(function () {
  865. sinon.stub(controller, 'updateComponent', Em.K);
  866. });
  867. afterEach(function () {
  868. controller.updateComponent.restore();
  869. });
  870. it('', function () {
  871. controller.set('content.masterComponentHosts', [{
  872. component: 'ZOOKEEPER_SERVER',
  873. hostName: 'host1'
  874. }]);
  875. controller.startZooKeeperServers();
  876. expect(controller.updateComponent.calledWith('ZOOKEEPER_SERVER', ['host1'], 'ZOOKEEPER', 'Start')).to.be.true;
  877. });
  878. });
  879. describe('#startNameNode()', function () {
  880. beforeEach(function () {
  881. sinon.stub(controller, 'updateComponent', Em.K);
  882. });
  883. afterEach(function () {
  884. controller.updateComponent.restore();
  885. });
  886. it('reassign host does not match current', function () {
  887. controller.set('content.masterComponentHosts', [{
  888. component: 'NAMENODE',
  889. hostName: 'host1'
  890. }]);
  891. controller.set('content.reassignHosts.source', 'host2');
  892. controller.startNameNode();
  893. expect(controller.updateComponent.calledWith('NAMENODE', ['host1'], 'HDFS', 'Start')).to.be.true;
  894. });
  895. it('reassign host matches current', function () {
  896. controller.set('content.masterComponentHosts', [{
  897. component: 'NAMENODE',
  898. hostName: 'host1'
  899. }]);
  900. controller.set('content.reassignHosts.source', 'host1');
  901. controller.startNameNode();
  902. expect(controller.updateComponent.calledWith('NAMENODE', [], 'HDFS', 'Start')).to.be.true;
  903. });
  904. });
  905. describe('#startServices()', function () {
  906. before(function () {
  907. sinon.stub(App.router, 'get').returns({"skip.service.checks": "false"});
  908. });
  909. after(function () {
  910. App.router.get.restore();
  911. });
  912. it('', function () {
  913. controller.startServices();
  914. expect(App.ajax.send.calledOnce).to.be.true;
  915. });
  916. });
  917. describe('#deleteHostComponents()', function () {
  918. it('No host components', function () {
  919. controller.set('hostComponents', []);
  920. controller.set('content.reassignHosts.source', 'host1');
  921. controller.deleteHostComponents();
  922. expect(App.ajax.send.called).to.be.false;
  923. });
  924. it('delete two components', function () {
  925. controller.set('hostComponents', [1, 2]);
  926. controller.set('content.reassignHosts.source', 'host1');
  927. controller.deleteHostComponents();
  928. expect(App.ajax.send.getCall(0).args[0].data).to.eql({
  929. "hostName": "host1",
  930. "componentName": 1
  931. });
  932. expect(App.ajax.send.getCall(1).args[0].data).to.eql({
  933. "hostName": "host1",
  934. "componentName": 2
  935. });
  936. });
  937. });
  938. describe('#onDeleteHostComponentsError()', function () {
  939. beforeEach(function () {
  940. sinon.stub(controller, 'onComponentsTasksSuccess', Em.K);
  941. sinon.stub(controller, 'onTaskError', Em.K);
  942. });
  943. afterEach(function () {
  944. controller.onComponentsTasksSuccess.restore();
  945. controller.onTaskError.restore();
  946. });
  947. it('task success', function () {
  948. var error = {
  949. responseText: 'org.apache.ambari.server.controller.spi.NoSuchResourceException'
  950. }
  951. controller.onDeleteHostComponentsError(error);
  952. expect(controller.onComponentsTasksSuccess.calledOnce).to.be.true;
  953. });
  954. it('unknown error', function () {
  955. var error = {
  956. responseText: ''
  957. }
  958. controller.onDeleteHostComponentsError(error);
  959. expect(controller.onTaskError.calledOnce).to.be.true;
  960. });
  961. });
  962. describe('#done()', function () {
  963. beforeEach(function () {
  964. sinon.stub(controller, 'removeObserver', Em.K);
  965. sinon.stub(App.router, 'send', Em.K);
  966. });
  967. afterEach(function () {
  968. controller.removeObserver.restore();
  969. App.router.send.restore();
  970. });
  971. it('submit disabled', function () {
  972. controller.set('isSubmitDisabled', true);
  973. controller.done();
  974. expect(App.router.send.called).to.be.false;
  975. });
  976. it('submit enabled and does not have manual steps', function () {
  977. controller.set('isSubmitDisabled', false);
  978. controller.set('content.hasManualSteps', false);
  979. controller.done();
  980. expect(controller.removeObserver.calledWith('tasks.@each.status', controller, 'onTaskStatusChange')).to.be.true;
  981. expect(App.router.send.calledWith('complete')).to.be.true;
  982. });
  983. it('submit enabled and has manual steps', function () {
  984. controller.set('isSubmitDisabled', false);
  985. controller.set('content.hasManualSteps', true);
  986. controller.done();
  987. expect(controller.removeObserver.calledWith('tasks.@each.status', controller, 'onTaskStatusChange')).to.be.true;
  988. expect(App.router.send.calledWith('next')).to.be.true;
  989. });
  990. });
  991. describe('#getServiceConfigData()', function () {
  992. var services = [];
  993. var stackServices = [];
  994. beforeEach(function () {
  995. sinon.stub(App.Service, 'find', function () {
  996. return services;
  997. });
  998. sinon.stub(App.StackService, 'find', function () {
  999. return stackServices;
  1000. });
  1001. });
  1002. afterEach(function () {
  1003. App.Service.find.restore();
  1004. App.StackService.find.restore();
  1005. });
  1006. it('No services', function () {
  1007. services = [];
  1008. controller.set('content.reassign.component_name', 'COMP1');
  1009. expect(controller.getServiceConfigData([])).to.eql([]);
  1010. });
  1011. it('No services in stackServices', function () {
  1012. services = [Em.Object.create({serviceName: 'S1'})];
  1013. stackServices = [];
  1014. controller.set('content.reassign.component_name', 'COMP1');
  1015. expect(controller.getServiceConfigData([])).to.eql([]);
  1016. });
  1017. it('Services in stackServicesm but configTypesRendered is empty', function () {
  1018. services = [Em.Object.create({serviceName: 'S1'})];
  1019. stackServices = [Em.Object.create({
  1020. serviceName: 'S1',
  1021. configTypesRendered: {}
  1022. })];
  1023. controller.set('content.reassign.component_name', 'COMP1');
  1024. expect(controller.getServiceConfigData([])[0]).to.equal("{\"Clusters\":{\"desired_config\":[]}}");
  1025. });
  1026. it('Services in stackServicesm and configTypesRendered has data, but configs is empty', function () {
  1027. services = [Em.Object.create({serviceName: 'S1'})];
  1028. stackServices = [
  1029. Em.Object.create({
  1030. serviceName: 'S1',
  1031. configTypesRendered: {'type1': {}}
  1032. })
  1033. ];
  1034. controller.set('content.reassign.component_name', 'COMP1');
  1035. expect(controller.getServiceConfigData([])[0]).to.equal("{\"Clusters\":{\"desired_config\":[]}}");
  1036. });
  1037. it('Services in stackServicesm and configTypesRendered has data, and configs present', function () {
  1038. services = [Em.Object.create({serviceName: 'S1'})];
  1039. stackServices = [
  1040. Em.Object.create({
  1041. serviceName: 'S1',
  1042. configTypesRendered: {'type1': {}}
  1043. })
  1044. ];
  1045. var configs = {
  1046. 'type1': {
  1047. 'prop1': 'value1'
  1048. }
  1049. };
  1050. controller.set('content.reassign.component_name', 'COMP1');
  1051. expect(JSON.parse(controller.getServiceConfigData(configs)[0]).Clusters.desired_config.length).to.equal(1);
  1052. });
  1053. });
  1054. describe('#testsMySqlServer()', function () {
  1055. beforeEach(function() {
  1056. sinon.stub(App.HostComponent, 'find', function() {
  1057. return Em.A([
  1058. Em.Object.create({
  1059. 'componentName': 'MYSQL_SERVER',
  1060. 'hostName': 'c6401.ambari.apache.org'
  1061. })
  1062. ]);
  1063. });
  1064. });
  1065. afterEach(function() {
  1066. App.HostComponent.find.restore();
  1067. });
  1068. it('Cleans MySql Server', function () {
  1069. controller.cleanMySqlServer();
  1070. expect(App.ajax.send.calledOnce).to.be.true;
  1071. });
  1072. it('Configures MySql Server', function () {
  1073. controller.configureMySqlServer();
  1074. expect(App.ajax.send.calledOnce).to.be.true;
  1075. });
  1076. });
  1077. });