step4_controller_test.js 54 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605
  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. it('reassign component is Metrics Collector', function () {
  220. controller.set('content.hasManualSteps', false);
  221. controller.set('content.databaseType', 'mysql');
  222. controller.set('content.reassign.component_name', 'METRICS_COLLECTOR');
  223. isHaEnabled = false;
  224. controller.set('tasks', commandsForDB);
  225. controller.removeUnneededTasks();
  226. expect(controller.get('tasks').mapProperty('id')).to.eql([1,2,5,6,8,10,12]);
  227. });
  228. it('reassign component is Mysql Server', function () {
  229. controller.set('content.hasManualSteps', false);
  230. controller.set('content.databaseType', 'mysql');
  231. controller.set('content.reassign.component_name', 'MYSQL_SERVER');
  232. isHaEnabled = false;
  233. controller.set('tasks', commandsForDB);
  234. controller.removeUnneededTasks();
  235. expect(controller.get('tasks').mapProperty('id')).to.eql([1,2,3,4,5,6,8,9,10,11,12]);
  236. });
  237. });
  238. describe("#stopRequiredServices()", function() {
  239. before(function () {
  240. sinon.stub(controller, 'stopServices', Em.K);
  241. });
  242. after(function () {
  243. controller.stopServices.restore();
  244. });
  245. it("", function() {
  246. controller.set('content.reassign.component_name', 'JOBTRACKER');
  247. controller.stopRequiredServices();
  248. expect(controller.stopServices.calledWith(['HDFS', 'ZOOKEEPER', 'HBASE', 'FLUME', 'SQOOP', 'STORM'])).to.be.true;
  249. });
  250. });
  251. describe('#initializeTasks()', function () {
  252. beforeEach(function () {
  253. controller.set('tasks', []);
  254. sinon.stub(controller, 'getHostComponentsNames', Em.K);
  255. sinon.stub(controller, 'removeUnneededTasks', Em.K);
  256. this.mock = sinon.stub(controller, 'isComponentWithDB');
  257. });
  258. afterEach(function () {
  259. controller.removeUnneededTasks.restore();
  260. controller.getHostComponentsNames.restore();
  261. this.mock.restore();
  262. });
  263. it('No commands', function () {
  264. controller.set('commands', []);
  265. controller.set('commandsForDB', []);
  266. this.mock.returns(false);
  267. controller.initializeTasks();
  268. expect(controller.get('tasks')).to.be.empty;
  269. });
  270. it('No commands', function () {
  271. controller.set('commands', []);
  272. controller.set('commandsForDB', []);
  273. this.mock.returns(true);
  274. controller.initializeTasks();
  275. expect(controller.get('tasks')).to.be.empty;
  276. });
  277. it('One command', function () {
  278. controller.set('commands', ['COMMAND1']);
  279. controller.set('commandsForDB', ['COMMAND1']);
  280. controller.initializeTasks();
  281. expect(controller.get('tasks')[0].get('id')).to.equal(0);
  282. expect(controller.get('tasks')[0].get('command')).to.equal('COMMAND1');
  283. });
  284. });
  285. describe('#hideRollbackButton()', function () {
  286. it('No showRollback command', function () {
  287. controller.set('tasks', [Em.Object.create({
  288. showRollback: false
  289. })]);
  290. controller.hideRollbackButton();
  291. expect(controller.get('tasks')[0].get('showRollback')).to.be.false;
  292. });
  293. it('showRollback command is present', function () {
  294. controller.set('tasks', [Em.Object.create({
  295. showRollback: true
  296. })]);
  297. controller.hideRollbackButton();
  298. expect(controller.get('tasks')[0].get('showRollback')).to.be.false;
  299. });
  300. });
  301. describe('#onComponentsTasksSuccess()', function () {
  302. beforeEach(function () {
  303. sinon.stub(controller, 'onTaskCompleted', Em.K);
  304. });
  305. afterEach(function () {
  306. controller.onTaskCompleted.restore();
  307. });
  308. it('No host-components', function () {
  309. controller.set('multiTaskCounter', 0);
  310. controller.set('hostComponents', []);
  311. controller.onComponentsTasksSuccess();
  312. expect(controller.get('multiTaskCounter')).to.equal(1);
  313. expect(controller.onTaskCompleted.calledOnce).to.be.true;
  314. });
  315. it('One host-component', function () {
  316. controller.set('multiTaskCounter', 0);
  317. controller.set('hostComponents', [
  318. {}
  319. ]);
  320. controller.onComponentsTasksSuccess();
  321. expect(controller.get('multiTaskCounter')).to.equal(1);
  322. expect(controller.onTaskCompleted.calledOnce).to.be.true;
  323. });
  324. it('two host-components', function () {
  325. controller.set('multiTaskCounter', 0);
  326. controller.set('hostComponents', [
  327. {},
  328. {}
  329. ]);
  330. controller.onComponentsTasksSuccess();
  331. expect(controller.get('multiTaskCounter')).to.equal(1);
  332. expect(controller.onTaskCompleted.called).to.be.false;
  333. });
  334. });
  335. describe('#stopServices()', function () {
  336. it('', function () {
  337. controller.stopServices();
  338. expect(App.ajax.send.calledOnce).to.be.true;
  339. });
  340. });
  341. describe('#createHostComponents()', function () {
  342. beforeEach(function () {
  343. sinon.stub(controller, 'createComponent', Em.K);
  344. });
  345. afterEach(function () {
  346. controller.createComponent.restore();
  347. });
  348. it('No host-components', function () {
  349. controller.set('hostComponents', []);
  350. controller.createHostComponents();
  351. expect(controller.get('multiTaskCounter')).to.equal(0);
  352. expect(controller.createComponent.called).to.be.false;
  353. });
  354. it('One host-component', function () {
  355. controller.set('hostComponents', ['COMP1']);
  356. controller.set('content.reassignHosts.target', 'host1');
  357. controller.set('content.reassign.service_id', 'SERVICE1');
  358. controller.createHostComponents();
  359. expect(controller.get('multiTaskCounter')).to.equal(0);
  360. expect(controller.createComponent.calledWith('COMP1', 'host1', 'SERVICE1')).to.be.true;
  361. });
  362. });
  363. describe('#onCreateComponent()', function () {
  364. it('', function () {
  365. sinon.stub(controller, 'onComponentsTasksSuccess', Em.K);
  366. controller.onCreateComponent();
  367. expect(controller.onComponentsTasksSuccess.calledOnce).to.be.true;
  368. controller.onComponentsTasksSuccess.restore();
  369. });
  370. });
  371. describe('#putHostComponentsInMaintenanceMode()', function () {
  372. beforeEach(function(){
  373. sinon.stub(controller, 'onComponentsTasksSuccess', Em.K);
  374. controller.set('content.reassignHosts.source', 'source');
  375. });
  376. afterEach(function(){
  377. controller.onComponentsTasksSuccess.restore();
  378. });
  379. it('No host-components', function () {
  380. controller.set('hostComponents', []);
  381. controller.putHostComponentsInMaintenanceMode();
  382. expect(App.ajax.send.called).to.be.false;
  383. expect(controller.get('multiTaskCounter')).to.equal(0);
  384. });
  385. it('One host-components', function () {
  386. controller.set('hostComponents', [{}]);
  387. controller.putHostComponentsInMaintenanceMode();
  388. expect(App.ajax.send.calledOnce).to.be.true;
  389. expect(controller.get('multiTaskCounter')).to.equal(0);
  390. });
  391. });
  392. describe('#installHostComponents()', function () {
  393. beforeEach(function () {
  394. sinon.stub(controller, 'updateComponent', Em.K);
  395. });
  396. afterEach(function () {
  397. controller.updateComponent.restore();
  398. });
  399. it('No host-components', function () {
  400. controller.set('hostComponents', []);
  401. controller.installHostComponents();
  402. expect(controller.get('multiTaskCounter')).to.equal(0);
  403. expect(controller.updateComponent.called).to.be.false;
  404. });
  405. it('One host-component', function () {
  406. controller.set('hostComponents', ['COMP1']);
  407. controller.set('content.reassignHosts.target', 'host1');
  408. controller.set('content.reassign.service_id', 'SERVICE1');
  409. controller.installHostComponents();
  410. expect(controller.get('multiTaskCounter')).to.equal(0);
  411. expect(controller.updateComponent.calledWith('COMP1', 'host1', 'SERVICE1', 'Install', 1)).to.be.true;
  412. });
  413. });
  414. describe('#reconfigure()', function () {
  415. it('', function () {
  416. sinon.stub(controller, 'loadConfigsTags', Em.K);
  417. controller.reconfigure();
  418. expect(controller.loadConfigsTags.calledOnce).to.be.true;
  419. controller.loadConfigsTags.restore();
  420. });
  421. });
  422. describe('#loadConfigsTags()', function () {
  423. it('', function () {
  424. controller.loadConfigsTags();
  425. expect(App.ajax.send.calledOnce).to.be.true;
  426. });
  427. });
  428. describe('#getConfigUrlParams()', function () {
  429. var testCases = [
  430. {
  431. componentName: 'NAMENODE',
  432. result: [
  433. "(type=hdfs-site&tag=1)",
  434. "(type=core-site&tag=2)"
  435. ]
  436. },
  437. {
  438. componentName: 'SECONDARY_NAMENODE',
  439. result: [
  440. "(type=hdfs-site&tag=1)",
  441. "(type=core-site&tag=2)"
  442. ]
  443. },
  444. {
  445. componentName: 'JOBTRACKER',
  446. result: [
  447. "(type=mapred-site&tag=4)"
  448. ]
  449. },
  450. {
  451. componentName: 'RESOURCEMANAGER',
  452. result: [
  453. "(type=yarn-site&tag=5)"
  454. ]
  455. },
  456. {
  457. componentName: 'APP_TIMELINE_SERVER',
  458. result: [
  459. "(type=yarn-site&tag=5)",
  460. "(type=yarn-env&tag=8)"
  461. ]
  462. },
  463. {
  464. componentName: 'OOZIE_SERVER',
  465. result: [
  466. "(type=oozie-site&tag=6)",
  467. "(type=core-site&tag=2)"
  468. ]
  469. },
  470. {
  471. componentName: 'WEBHCAT_SERVER',
  472. result: [
  473. "(type=webhcat-site&tag=7)"
  474. ]
  475. },
  476. {
  477. componentName: 'HIVE_SERVER',
  478. result: [
  479. '(type=hive-site&tag=10)',
  480. '(type=webhcat-site&tag=7)',
  481. '(type=hive-env&tag=11)',
  482. '(type=core-site&tag=2)'
  483. ]
  484. },
  485. {
  486. componentName: 'HIVE_METASTORE',
  487. result: [
  488. '(type=hive-site&tag=10)',
  489. '(type=webhcat-site&tag=7)',
  490. '(type=hive-env&tag=11)',
  491. '(type=core-site&tag=2)'
  492. ]
  493. },
  494. {
  495. componentName: 'MYSQL_SERVER',
  496. result: [
  497. '(type=hive-site&tag=10)'
  498. ]
  499. }
  500. ];
  501. var data = {
  502. Clusters: {
  503. desired_configs: {
  504. 'hdfs-site': {tag: 1},
  505. 'core-site': {tag: 2},
  506. 'hbase-site': {tag: 3},
  507. 'mapred-site': {tag: 4},
  508. 'yarn-site': {tag: 5},
  509. 'oozie-site': {tag: 6},
  510. 'webhcat-site': {tag: 7},
  511. 'yarn-env': {tag: 8},
  512. 'accumulo-site': {tag: 9},
  513. 'hive-site': {tag: 10},
  514. 'hive-env': {tag: 11}
  515. }
  516. }
  517. };
  518. var services = [];
  519. beforeEach(function () {
  520. sinon.stub(App.Service, 'find', function () {
  521. return services;
  522. });
  523. });
  524. afterEach(function () {
  525. App.Service.find.restore();
  526. });
  527. testCases.forEach(function (test) {
  528. it('get config of ' + test.componentName, function () {
  529. expect(controller.getConfigUrlParams(test.componentName, data)).to.eql(test.result);
  530. });
  531. });
  532. it('get config of NAMENODE when HBASE installed', function () {
  533. services = [
  534. {
  535. serviceName: 'HBASE'
  536. }
  537. ];
  538. expect(controller.getConfigUrlParams('NAMENODE', data)).to.eql([
  539. "(type=hdfs-site&tag=1)",
  540. "(type=core-site&tag=2)",
  541. "(type=hbase-site&tag=3)"
  542. ]);
  543. });
  544. it('get config of NAMENODE when ACCUMULO installed', function () {
  545. services = [
  546. {
  547. serviceName: 'ACCUMULO'
  548. }
  549. ];
  550. expect(controller.getConfigUrlParams('NAMENODE', data)).to.eql([
  551. "(type=hdfs-site&tag=1)",
  552. "(type=core-site&tag=2)",
  553. "(type=accumulo-site&tag=9)"
  554. ]);
  555. });
  556. });
  557. describe('#onLoadConfigsTags()', function () {
  558. it('', function () {
  559. sinon.stub(controller, 'getConfigUrlParams', function () {
  560. return [];
  561. });
  562. controller.set('content.reassign.component_name', 'COMP1');
  563. controller.onLoadConfigsTags({});
  564. expect(App.ajax.send.calledOnce).to.be.true;
  565. expect(controller.getConfigUrlParams.calledWith('COMP1', {})).to.be.true;
  566. controller.getConfigUrlParams.restore();
  567. });
  568. });
  569. describe('#onLoadConfigs()', function () {
  570. beforeEach(function () {
  571. sinon.stub(controller, 'setAdditionalConfigs', Em.K);
  572. sinon.stub(controller, 'setSecureConfigs', Em.K);
  573. sinon.stub(controller, 'setSpecificNamenodeConfigs', Em.K);
  574. sinon.stub(controller, 'setSpecificResourceMangerConfigs', Em.K);
  575. sinon.stub(controller, 'setSpecificHiveConfigs', Em.K);
  576. sinon.stub(controller, 'getWebAddressPort', Em.K);
  577. sinon.stub(controller, 'getComponentDir', Em.K);
  578. sinon.stub(controller, 'saveClusterStatus', Em.K);
  579. sinon.stub(controller, 'saveConfigsToServer', Em.K);
  580. sinon.stub(controller, 'saveServiceProperties', Em.K);
  581. controller.set('content.reassignHosts.target', 'host1');
  582. });
  583. afterEach(function () {
  584. controller.setAdditionalConfigs.restore();
  585. controller.setSecureConfigs.restore();
  586. controller.setSpecificNamenodeConfigs.restore();
  587. controller.setSpecificResourceMangerConfigs.restore();
  588. controller.setSpecificHiveConfigs.restore();
  589. controller.getWebAddressPort.restore();
  590. controller.getComponentDir.restore();
  591. controller.saveClusterStatus.restore();
  592. controller.saveConfigsToServer.restore();
  593. controller.saveServiceProperties.restore();
  594. });
  595. it('component is not NAMENODE', function () {
  596. controller.set('content.reassign.component_name', 'COMP1');
  597. controller.onLoadConfigs({items: []});
  598. expect(controller.setAdditionalConfigs.calledWith({}, 'COMP1', 'host1')).to.be.true;
  599. expect(controller.setSecureConfigs.calledWith([], {}, 'COMP1')).to.be.true;
  600. expect(controller.setSpecificNamenodeConfigs.called).to.be.false;
  601. expect(controller.getComponentDir.calledWith({}, 'COMP1')).to.be.true;
  602. expect(controller.saveClusterStatus.calledWith([])).to.be.true;
  603. expect(controller.saveConfigsToServer.calledWith({})).to.be.true;
  604. expect(controller.saveServiceProperties.calledWith({})).to.be.true;
  605. });
  606. it('component is NAMENODE, has configs', function () {
  607. controller.set('content.reassign.component_name', 'NAMENODE');
  608. controller.onLoadConfigs({items: [
  609. {
  610. type: 'hdfs-site',
  611. properties: {}
  612. }
  613. ]});
  614. expect(controller.setAdditionalConfigs.calledWith({'hdfs-site': {}}, 'NAMENODE', 'host1')).to.be.true;
  615. expect(controller.setSecureConfigs.calledWith([], {'hdfs-site': {}}, 'NAMENODE')).to.be.true;
  616. expect(controller.setSpecificNamenodeConfigs.calledWith({'hdfs-site': {}}, 'host1')).to.be.true;
  617. expect(controller.getComponentDir.calledWith({'hdfs-site': {}}, 'NAMENODE')).to.be.true;
  618. expect(controller.saveClusterStatus.calledWith([])).to.be.true;
  619. expect(controller.saveConfigsToServer.calledWith({'hdfs-site': {}})).to.be.true;
  620. expect(controller.saveServiceProperties.calledWith({'hdfs-site': {}})).to.be.true;
  621. });
  622. it('component is RESOURCEMANAGER, has configs', function () {
  623. controller.set('content.reassign.component_name', 'RESOURCEMANAGER');
  624. controller.onLoadConfigs({items: [
  625. {
  626. type: 'hdfs-site',
  627. properties: {}
  628. }
  629. ]});
  630. expect(controller.setAdditionalConfigs.calledWith({'hdfs-site': {}}, 'RESOURCEMANAGER', 'host1')).to.be.true;
  631. expect(controller.setSecureConfigs.calledWith([], {'hdfs-site': {}}, 'RESOURCEMANAGER')).to.be.true;
  632. expect(controller.setSpecificResourceMangerConfigs.calledWith({'hdfs-site': {}}, 'host1')).to.be.true;
  633. expect(controller.getComponentDir.calledWith({'hdfs-site': {}}, 'RESOURCEMANAGER')).to.be.true;
  634. expect(controller.saveClusterStatus.calledWith([])).to.be.true;
  635. expect(controller.saveConfigsToServer.calledWith({'hdfs-site': {}})).to.be.true;
  636. expect(controller.saveServiceProperties.calledWith({'hdfs-site': {}})).to.be.true;
  637. });
  638. it('component is HIVE_METASTORE, has configs', function () {
  639. controller.set('content.reassign.component_name', 'HIVE_METASTORE');
  640. controller.onLoadConfigs({items: [
  641. {
  642. type: 'hive-site',
  643. properties: {}
  644. }
  645. ]});
  646. expect(controller.setAdditionalConfigs.calledWith({'hive-site': {}}, 'HIVE_METASTORE', 'host1')).to.be.true;
  647. expect(controller.setSecureConfigs.calledWith([], {'hive-site': {}}, 'HIVE_METASTORE')).to.be.true;
  648. expect(controller.setSpecificHiveConfigs.calledWith({'hive-site': {}}, 'host1')).to.be.true;
  649. expect(controller.getComponentDir.calledWith({'hive-site': {}}, 'HIVE_METASTORE')).to.be.true;
  650. expect(controller.saveClusterStatus.calledWith([])).to.be.true;
  651. expect(controller.saveConfigsToServer.calledWith({'hive-site': {}})).to.be.true;
  652. expect(controller.saveServiceProperties.calledWith({'hive-site': {}})).to.be.true;
  653. });
  654. });
  655. describe('#loadStep()', function () {
  656. var isHaEnabled = true;
  657. beforeEach(function () {
  658. controller.set('content.reassign.service_id', 'service1');
  659. sinon.stub(controller, 'onTaskStatusChange', Em.K);
  660. sinon.stub(controller, 'initializeTasks', Em.K);
  661. sinon.stub(App, 'get', function () {
  662. return isHaEnabled;
  663. });
  664. });
  665. afterEach(function () {
  666. controller.onTaskStatusChange.restore();
  667. controller.initializeTasks.restore();
  668. App.get.restore();
  669. });
  670. it('reassign component is NameNode and HA enabled', function () {
  671. isHaEnabled = true;
  672. controller.set('content.reassign.component_name', 'NAMENODE');
  673. controller.loadStep();
  674. expect(controller.get('hostComponents')).to.eql(['NAMENODE', 'ZKFC']);
  675. expect(controller.get('serviceName')).to.eql(['service1']);
  676. });
  677. it('reassign component is NameNode and HA disabled', function () {
  678. isHaEnabled = false;
  679. controller.set('content.reassign.component_name', 'NAMENODE');
  680. controller.loadStep();
  681. expect(controller.get('hostComponents')).to.eql(['NAMENODE']);
  682. expect(controller.get('serviceName')).to.eql(['service1']);
  683. });
  684. it('reassign component is JOBTRACKER and HA enabled', function () {
  685. isHaEnabled = true;
  686. controller.set('content.reassign.component_name', 'JOBTRACKER');
  687. controller.loadStep();
  688. expect(controller.get('hostComponents')).to.eql(['JOBTRACKER']);
  689. expect(controller.get('serviceName')).to.eql(['service1']);
  690. });
  691. it('reassign component is RESOURCEMANAGER and HA enabled', function () {
  692. isHaEnabled = true;
  693. controller.set('content.reassign.component_name', 'RESOURCEMANAGER');
  694. controller.loadStep();
  695. expect(controller.get('hostComponents')).to.eql(['RESOURCEMANAGER']);
  696. expect(controller.get('serviceName')).to.eql(['service1']);
  697. });
  698. });
  699. describe('#saveConfigsToServer()', function () {
  700. beforeEach(function () {
  701. sinon.stub(controller, 'getServiceConfigData', Em.K);
  702. });
  703. afterEach(function () {
  704. controller.getServiceConfigData.restore();
  705. });
  706. it('', function () {
  707. controller.saveConfigsToServer([1]);
  708. expect(controller.getServiceConfigData.calledWith([1])).to.be.true;
  709. expect(App.ajax.send.calledOnce).to.be.true;
  710. });
  711. });
  712. describe('#setSpecificNamenodeConfigs()', function () {
  713. var isHaEnabled = false;
  714. var service = Em.Object.create();
  715. beforeEach(function () {
  716. sinon.stub(App, 'get', function () {
  717. return isHaEnabled;
  718. });
  719. sinon.stub(App.Service, 'find', function () {
  720. return service;
  721. });
  722. controller.set('content.reassignHosts.source', 'host1');
  723. });
  724. afterEach(function () {
  725. App.get.restore();
  726. App.Service.find.restore();
  727. });
  728. it('HA isn\'t enabled and no HBASE or ACCUMULO service', function () {
  729. isHaEnabled = false;
  730. var configs = {};
  731. controller.setSpecificNamenodeConfigs(configs, 'host1');
  732. expect(configs).to.eql({});
  733. });
  734. it('HA isn\'t enabled and HBASE and ACCUMULO service', function () {
  735. isHaEnabled = false;
  736. service = Em.Object.create({
  737. isLoaded: true
  738. });
  739. var configs = {
  740. 'hbase-site': {
  741. 'hbase.rootdir': 'hdfs://localhost:8020/apps/hbase/data'
  742. },
  743. 'accumulo-site': {
  744. 'instance.volumes': 'hdfs://localhost:8020/apps/accumulo/data'
  745. }
  746. };
  747. controller.setSpecificNamenodeConfigs(configs, 'host1');
  748. expect(configs['hbase-site']['hbase.rootdir']).to.equal('hdfs://host1:8020/apps/hbase/data');
  749. expect(configs['accumulo-site']['instance.volumes']).to.equal('hdfs://host1:8020/apps/accumulo/data');
  750. });
  751. it('HA enabled and namenode 1', function () {
  752. isHaEnabled = true;
  753. var configs = {
  754. 'hdfs-site': {
  755. 'dfs.nameservices': 's',
  756. 'dfs.namenode.http-address.s.nn1': 'host1:50070',
  757. 'dfs.namenode.https-address.s.nn1': '',
  758. 'dfs.namenode.rpc-address.s.nn1': ''
  759. }
  760. };
  761. controller.setSpecificNamenodeConfigs(configs, 'host2');
  762. expect(configs['hdfs-site']).to.eql({
  763. "dfs.nameservices": "s",
  764. "dfs.namenode.http-address.s.nn1": "host2:50070",
  765. "dfs.namenode.https-address.s.nn1": "host2:50470",
  766. "dfs.namenode.rpc-address.s.nn1": "host2:8020"
  767. });
  768. });
  769. it('HA enabled and namenode 2', function () {
  770. isHaEnabled = true;
  771. var configs = {
  772. 'hdfs-site': {
  773. 'dfs.nameservices': 's',
  774. 'dfs.namenode.http-address.s.nn2': 'host2:50070',
  775. 'dfs.namenode.https-address.s.nn2': '',
  776. 'dfs.namenode.rpc-address.s.nn2': ''
  777. }
  778. };
  779. controller.setSpecificNamenodeConfigs(configs, 'host1');
  780. expect(configs['hdfs-site']).to.eql({
  781. "dfs.nameservices": "s",
  782. "dfs.namenode.http-address.s.nn2": "host1:50070",
  783. "dfs.namenode.https-address.s.nn2": "host1:50470",
  784. "dfs.namenode.rpc-address.s.nn2": "host1:8020"
  785. });
  786. });
  787. });
  788. describe('#setSpecificResourceMangerConfigs()', function () {
  789. var isRMHaEnabled = false;
  790. var service = Em.Object.create();
  791. beforeEach(function () {
  792. sinon.stub(App, 'get', function () {
  793. return isRMHaEnabled;
  794. });
  795. controller.set('content.reassignHosts.source', 'host1');
  796. });
  797. afterEach(function () {
  798. App.get.restore();
  799. });
  800. it('HA isn\'t enabled', function () {
  801. isRMHaEnabled = false;
  802. var configs = {};
  803. controller.setSpecificResourceMangerConfigs(configs, 'host1');
  804. expect(configs).to.eql({});
  805. });
  806. it('HA enabled and resource manager 1', function () {
  807. isRMHaEnabled = true;
  808. var configs = {
  809. 'yarn-site': {
  810. 'yarn.resourcemanager.hostname.rm1': 'host1',
  811. 'yarn.resourcemanager.webapp.address.rm1': 'host1:8088',
  812. 'yarn.resourcemanager.webapp.https.address.rm1': 'host1:8443'
  813. }
  814. };
  815. controller.setSpecificResourceMangerConfigs(configs, 'host2');
  816. expect(configs['yarn-site']).to.eql({
  817. 'yarn.resourcemanager.hostname.rm1': 'host2',
  818. 'yarn.resourcemanager.webapp.address.rm1': 'host2:8088',
  819. 'yarn.resourcemanager.webapp.https.address.rm1': 'host2:8443'
  820. });
  821. });
  822. it('HA enabled and resource manager 2', function () {
  823. isRMHaEnabled = true;
  824. var configs = {
  825. 'yarn-site': {
  826. 'yarn.resourcemanager.hostname.rm2': 'host2',
  827. 'yarn.resourcemanager.webapp.address.rm2': 'host2:8088',
  828. 'yarn.resourcemanager.webapp.https.address.rm2': 'host2:8443'
  829. }
  830. };
  831. controller.setSpecificResourceMangerConfigs(configs, 'host1');
  832. expect(configs['yarn-site']).to.eql({
  833. 'yarn.resourcemanager.hostname.rm2': 'host1',
  834. 'yarn.resourcemanager.webapp.address.rm2': 'host1:8088',
  835. 'yarn.resourcemanager.webapp.https.address.rm2': 'host1:8443'
  836. });
  837. });
  838. });
  839. describe('#getWebAddressPort', function(){
  840. var configs = {
  841. 'yarn-site': {
  842. 'yarn.resourcemanager.hostname.rm2': 'host2',
  843. 'yarn.resourcemanager.webapp.address.rm2': 'host2:8088',
  844. 'yarn.resourcemanager.webapp.https.address.rm2': 'host2:8443'
  845. }
  846. };
  847. var httpPort = controller.getWebAddressPort(configs, 'yarn.resourcemanager.webapp.address.rm2');
  848. expect(httpPort).to.eql('8088');
  849. var httpsPort = controller.getWebAddressPort(configs, 'yarn.resourcemanager.webapp.https.address.rm2');
  850. expect(httpsPort).to.eql('8443');
  851. configs = {
  852. 'yarn-site': {
  853. 'yarn.resourcemanager.hostname.rm2': 'host2',
  854. 'yarn.resourcemanager.webapp.address.rm2': 'host2:',
  855. 'yarn.resourcemanager.webapp.https.address.rm2': 'host2: '
  856. }
  857. };
  858. //check for falsy conditions
  859. httpPort = controller.getWebAddressPort(configs, 'yarn.resourcemanager.webapp.address.rm2');
  860. var flag = "falsy"
  861. if (httpPort)
  862. flag = "truthy"
  863. expect(flag).to.eql('falsy')
  864. httpsPort = controller.getWebAddressPort(configs, 'yarn.resourcemanager.webapp.https.address.rm2');
  865. flag = "falsy"
  866. if (httpsPort)
  867. flag = "truthy"
  868. expect(flag).to.eql("falsy")
  869. configs = {
  870. 'yarn-site': {
  871. 'yarn.resourcemanager.hostname.rm2': 'host2'
  872. }
  873. };
  874. httpPort = controller.getWebAddressPort(configs, 'yarn.resourcemanager.webapp.address.rm2');
  875. var flag = "falsy"
  876. if (httpPort != null) //check for null, still part of the falsy condition checks.
  877. flag = "truthy"
  878. expect(flag).to.eql('falsy')
  879. });
  880. describe('#setSecureConfigs()', function () {
  881. it('undefined component and security disabled', function () {
  882. var secureConfigs = [];
  883. sinon.stub(App, 'get').withArgs('isKerberosEnabled').returns(false);
  884. controller.set('secureConfigsMap', []);
  885. expect(controller.setSecureConfigs(secureConfigs, {}, 'COMP1')).to.be.false;
  886. expect(secureConfigs).to.eql([]);
  887. App.get.restore();
  888. });
  889. it('component exist and security disabled', function () {
  890. var secureConfigs = [];
  891. sinon.stub(App, 'get').withArgs('isKerberosEnabled').returns(false);
  892. controller.set('secureConfigsMap', [{
  893. componentName: 'COMP1'
  894. }]);
  895. expect(controller.setSecureConfigs(secureConfigs, {}, 'COMP1')).to.be.false;
  896. expect(secureConfigs).to.eql([]);
  897. App.get.restore();
  898. });
  899. it('undefined component and security enabled', function () {
  900. var secureConfigs = [];
  901. sinon.stub(App, 'get').withArgs('isKerberosEnabled').returns(true);
  902. controller.set('secureConfigsMap', []);
  903. expect(controller.setSecureConfigs(secureConfigs, {}, 'COMP1')).to.be.false;
  904. expect(secureConfigs).to.eql([]);
  905. App.get.restore();
  906. });
  907. it('component exist and security enabled', function () {
  908. var secureConfigs = [];
  909. sinon.stub(App, 'get').withArgs('isKerberosEnabled').returns(true);
  910. var configs = {'s1': {
  911. 'k1': 'kValue',
  912. 'p1': 'pValue'
  913. }};
  914. controller.set('secureConfigsMap', [{
  915. componentName: 'COMP1',
  916. configs: [{
  917. site: 's1',
  918. keytab: 'k1',
  919. principal: 'p1'
  920. }]
  921. }]);
  922. expect(controller.setSecureConfigs(secureConfigs, configs, 'COMP1')).to.be.true;
  923. expect(secureConfigs).to.eql([
  924. {
  925. "keytab": "kValue",
  926. "principal": "pValue"
  927. }
  928. ]);
  929. App.get.restore();
  930. });
  931. });
  932. describe('#getComponentDir()', function () {
  933. var configs = {
  934. 'hdfs-site': {
  935. 'dfs.name.dir': 'case1',
  936. 'dfs.namenode.name.dir': 'case2',
  937. 'dfs.namenode.checkpoint.dir': 'case3'
  938. },
  939. 'core-site': {
  940. 'fs.checkpoint.dir': 'case4'
  941. }
  942. };
  943. it('unknown component name', function () {
  944. expect(controller.getComponentDir(configs, 'COMP1')).to.be.empty;
  945. });
  946. it('NAMENODE component', function () {
  947. expect(controller.getComponentDir(configs, 'NAMENODE')).to.equal('case2');
  948. });
  949. it('SECONDARY_NAMENODE component', function () {
  950. expect(controller.getComponentDir(configs, 'SECONDARY_NAMENODE')).to.equal('case3');
  951. });
  952. });
  953. describe('#saveClusterStatus()', function () {
  954. var mock = {
  955. saveComponentDir: Em.K,
  956. saveSecureConfigs: Em.K
  957. };
  958. beforeEach(function () {
  959. sinon.stub(App.clusterStatus, 'setClusterStatus', Em.K);
  960. sinon.stub(App.router, 'get', function() {
  961. return mock;
  962. });
  963. sinon.spy(mock, 'saveComponentDir');
  964. sinon.spy(mock, 'saveSecureConfigs');
  965. });
  966. afterEach(function () {
  967. App.clusterStatus.setClusterStatus.restore();
  968. App.router.get.restore();
  969. mock.saveSecureConfigs.restore();
  970. mock.saveComponentDir.restore();
  971. });
  972. it('componentDir undefined and secureConfigs is empty', function () {
  973. expect(controller.saveClusterStatus([], null)).to.be.false;
  974. });
  975. it('componentDir defined and secureConfigs is empty', function () {
  976. expect(controller.saveClusterStatus([], 'dir1')).to.be.true;
  977. expect(mock.saveComponentDir.calledWith('dir1')).to.be.true;
  978. expect(mock.saveSecureConfigs.calledWith([])).to.be.true;
  979. });
  980. it('componentDir undefined and secureConfigs has data', function () {
  981. expect(controller.saveClusterStatus([1], null)).to.be.true;
  982. expect(mock.saveComponentDir.calledWith(null)).to.be.true;
  983. expect(mock.saveSecureConfigs.calledWith([1])).to.be.true;
  984. });
  985. it('componentDir defined and secureConfigs has data', function () {
  986. expect(controller.saveClusterStatus([1], 'dir1')).to.be.true;
  987. expect(mock.saveComponentDir.calledWith('dir1')).to.be.true;
  988. expect(mock.saveSecureConfigs.calledWith([1])).to.be.true;
  989. });
  990. });
  991. describe('#onSaveConfigs()', function () {
  992. beforeEach(function () {
  993. sinon.stub(controller, 'onTaskCompleted', Em.K);
  994. });
  995. afterEach(function () {
  996. controller.onTaskCompleted.restore();
  997. });
  998. it('', function () {
  999. controller.onSaveConfigs();
  1000. expect(controller.onTaskCompleted.calledOnce).to.be.true;
  1001. });
  1002. });
  1003. describe('#startZooKeeperServers()', function () {
  1004. beforeEach(function () {
  1005. sinon.stub(controller, 'updateComponent', Em.K);
  1006. });
  1007. afterEach(function () {
  1008. controller.updateComponent.restore();
  1009. });
  1010. it('', function () {
  1011. controller.set('content.masterComponentHosts', [{
  1012. component: 'ZOOKEEPER_SERVER',
  1013. hostName: 'host1'
  1014. }]);
  1015. controller.startZooKeeperServers();
  1016. expect(controller.updateComponent.calledWith('ZOOKEEPER_SERVER', ['host1'], 'ZOOKEEPER', 'Start')).to.be.true;
  1017. });
  1018. });
  1019. describe('#startNameNode()', function () {
  1020. beforeEach(function () {
  1021. sinon.stub(controller, 'updateComponent', Em.K);
  1022. });
  1023. afterEach(function () {
  1024. controller.updateComponent.restore();
  1025. });
  1026. it('reassign host does not match current', function () {
  1027. controller.set('content.masterComponentHosts', [{
  1028. component: 'NAMENODE',
  1029. hostName: 'host1'
  1030. }]);
  1031. controller.set('content.reassignHosts.source', 'host2');
  1032. controller.startNameNode();
  1033. expect(controller.updateComponent.getCall(0).args[1][0]).to.equal('host1');
  1034. expect(controller.updateComponent.getCall(0).args[0]).to.equal('NAMENODE');
  1035. expect(controller.updateComponent.getCall(0).args[2]).to.equal('HDFS');
  1036. expect(controller.updateComponent.getCall(0).args[3]).to.equal('Start');
  1037. });
  1038. it('reassign host matches current', function () {
  1039. controller.set('content.masterComponentHosts', [{
  1040. component: 'NAMENODE',
  1041. hostName: 'host1'
  1042. }]);
  1043. controller.set('content.reassignHosts.source', 'host1');
  1044. controller.startNameNode();
  1045. expect(controller.updateComponent.calledWith('NAMENODE', [], 'HDFS', 'Start')).to.be.true;
  1046. });
  1047. });
  1048. describe('#startServices()', function () {
  1049. before(function () {
  1050. sinon.stub(App.router, 'get').returns({"skip.service.checks": "false"});
  1051. });
  1052. after(function () {
  1053. App.router.get.restore();
  1054. });
  1055. it('', function () {
  1056. controller.startServices();
  1057. expect(App.ajax.send.calledOnce).to.be.true;
  1058. });
  1059. });
  1060. describe('#deleteHostComponents()', function () {
  1061. it('No host components', function () {
  1062. controller.set('hostComponents', []);
  1063. controller.set('content.reassignHosts.source', 'host1');
  1064. controller.deleteHostComponents();
  1065. expect(App.ajax.send.called).to.be.false;
  1066. });
  1067. it('delete two components', function () {
  1068. controller.set('hostComponents', [1, 2]);
  1069. controller.set('content.reassignHosts.source', 'host1');
  1070. controller.deleteHostComponents();
  1071. expect(App.ajax.send.getCall(0).args[0].data).to.eql({
  1072. "hostName": "host1",
  1073. "componentName": 1
  1074. });
  1075. expect(App.ajax.send.getCall(1).args[0].data).to.eql({
  1076. "hostName": "host1",
  1077. "componentName": 2
  1078. });
  1079. });
  1080. });
  1081. describe('#onDeleteHostComponentsError()', function () {
  1082. beforeEach(function () {
  1083. sinon.stub(controller, 'onComponentsTasksSuccess', Em.K);
  1084. sinon.stub(controller, 'onTaskError', Em.K);
  1085. });
  1086. afterEach(function () {
  1087. controller.onComponentsTasksSuccess.restore();
  1088. controller.onTaskError.restore();
  1089. });
  1090. it('task success', function () {
  1091. var error = {
  1092. responseText: 'org.apache.ambari.server.controller.spi.NoSuchResourceException'
  1093. }
  1094. controller.onDeleteHostComponentsError(error);
  1095. expect(controller.onComponentsTasksSuccess.calledOnce).to.be.true;
  1096. });
  1097. it('unknown error', function () {
  1098. var error = {
  1099. responseText: ''
  1100. }
  1101. controller.onDeleteHostComponentsError(error);
  1102. expect(controller.onTaskError.calledOnce).to.be.true;
  1103. });
  1104. });
  1105. describe('#done()', function () {
  1106. beforeEach(function () {
  1107. sinon.stub(controller, 'removeObserver', Em.K);
  1108. sinon.stub(App.router, 'send', Em.K);
  1109. });
  1110. afterEach(function () {
  1111. controller.removeObserver.restore();
  1112. App.router.send.restore();
  1113. });
  1114. it('submit disabled', function () {
  1115. controller.set('isSubmitDisabled', true);
  1116. controller.done();
  1117. expect(App.router.send.called).to.be.false;
  1118. });
  1119. it('submit enabled and does not have manual steps', function () {
  1120. controller.set('isSubmitDisabled', false);
  1121. controller.set('content.hasManualSteps', false);
  1122. controller.done();
  1123. expect(controller.removeObserver.calledWith('tasks.@each.status', controller, 'onTaskStatusChange')).to.be.true;
  1124. expect(App.router.send.calledWith('complete')).to.be.true;
  1125. });
  1126. it('submit enabled and has manual steps', function () {
  1127. controller.set('isSubmitDisabled', false);
  1128. controller.set('content.hasManualSteps', true);
  1129. controller.done();
  1130. expect(controller.removeObserver.calledWith('tasks.@each.status', controller, 'onTaskStatusChange')).to.be.true;
  1131. expect(App.router.send.calledWith('next')).to.be.true;
  1132. });
  1133. });
  1134. describe('#getServiceConfigData()', function () {
  1135. var services = [];
  1136. var stackServices = [];
  1137. beforeEach(function () {
  1138. sinon.stub(App.Service, 'find', function () {
  1139. return services;
  1140. });
  1141. sinon.stub(App.StackService, 'find', function () {
  1142. return stackServices;
  1143. });
  1144. });
  1145. afterEach(function () {
  1146. App.Service.find.restore();
  1147. App.StackService.find.restore();
  1148. });
  1149. it('No services', function () {
  1150. services = [];
  1151. controller.set('content.reassign.component_name', 'COMP1');
  1152. expect(controller.getServiceConfigData([])).to.eql([]);
  1153. });
  1154. it('No services in stackServices', function () {
  1155. services = [Em.Object.create({serviceName: 'S1'})];
  1156. stackServices = [];
  1157. controller.set('content.reassign.component_name', 'COMP1');
  1158. expect(controller.getServiceConfigData([])).to.eql([]);
  1159. });
  1160. it('Services in stackServicesm but configTypesRendered is empty', function () {
  1161. services = [Em.Object.create({serviceName: 'S1'})];
  1162. stackServices = [Em.Object.create({
  1163. serviceName: 'S1',
  1164. configTypesRendered: {}
  1165. })];
  1166. controller.set('content.reassign.component_name', 'COMP1');
  1167. expect(controller.getServiceConfigData([])[0]).to.equal("{\"Clusters\":{\"desired_config\":[]}}");
  1168. });
  1169. it('Services in stackServicesm and configTypesRendered has data, but configs is empty', function () {
  1170. services = [Em.Object.create({serviceName: 'S1'})];
  1171. stackServices = [
  1172. Em.Object.create({
  1173. serviceName: 'S1',
  1174. configTypesRendered: {'type1': {}}
  1175. })
  1176. ];
  1177. controller.set('content.reassign.component_name', 'COMP1');
  1178. expect(controller.getServiceConfigData([])[0]).to.equal("{\"Clusters\":{\"desired_config\":[]}}");
  1179. });
  1180. it('Services in stackServicesm and configTypesRendered has data, and configs present', function () {
  1181. services = [Em.Object.create({serviceName: 'S1'})];
  1182. stackServices = [
  1183. Em.Object.create({
  1184. serviceName: 'S1',
  1185. configTypesRendered: {'type1': {}}
  1186. })
  1187. ];
  1188. var configs = {
  1189. 'type1': {
  1190. 'prop1': 'value1'
  1191. }
  1192. };
  1193. controller.set('content.reassign.component_name', 'COMP1');
  1194. expect(JSON.parse(controller.getServiceConfigData(configs)[0]).Clusters.desired_config.length).to.equal(1);
  1195. });
  1196. });
  1197. describe('#cleanMySqlServer()', function () {
  1198. beforeEach(function() {
  1199. sinon.stub(App.HostComponent, 'find', function() {
  1200. return Em.A([
  1201. Em.Object.create({
  1202. 'componentName': 'MYSQL_SERVER',
  1203. 'hostName': 'host1'
  1204. })
  1205. ]);
  1206. });
  1207. });
  1208. afterEach(function() {
  1209. App.HostComponent.find.restore();
  1210. });
  1211. it('component_name is C1', function () {
  1212. controller.set('content.reassign.component_name', 'C1');
  1213. controller.cleanMySqlServer();
  1214. expect(App.ajax.send.calledWith({
  1215. name: 'service.mysql.clean',
  1216. sender: controller,
  1217. data: {
  1218. host: 'host1'
  1219. },
  1220. success: 'startPolling',
  1221. error: 'onTaskError'
  1222. })).to.be.true;
  1223. });
  1224. it('component_name is MYSQL_SERVER', function () {
  1225. controller.set('content.reassign.component_name', 'MYSQL_SERVER');
  1226. controller.set('content.reassignHosts.target', 'host2');
  1227. controller.cleanMySqlServer();
  1228. expect(App.ajax.send.calledWith({
  1229. name: 'service.mysql.clean',
  1230. sender: controller,
  1231. data: {
  1232. host: 'host2'
  1233. },
  1234. success: 'startPolling',
  1235. error: 'onTaskError'
  1236. })).to.be.true;
  1237. });
  1238. });
  1239. describe('#configureMySqlServer()', function () {
  1240. beforeEach(function() {
  1241. sinon.stub(App.HostComponent, 'find', function() {
  1242. return Em.A([
  1243. Em.Object.create({
  1244. 'componentName': 'MYSQL_SERVER',
  1245. 'hostName': 'host1'
  1246. })
  1247. ]);
  1248. });
  1249. });
  1250. afterEach(function() {
  1251. App.HostComponent.find.restore();
  1252. });
  1253. it('component_name is C1', function () {
  1254. controller.set('content.reassign.component_name', 'C1');
  1255. controller.configureMySqlServer();
  1256. expect(App.ajax.send.calledWith({
  1257. name: 'service.mysql.configure',
  1258. sender: controller,
  1259. data: {
  1260. host: 'host1'
  1261. },
  1262. success: 'startPolling',
  1263. error: 'onTaskError'
  1264. })).to.be.true;
  1265. });
  1266. it('component_name is MYSQL_SERVER', function () {
  1267. controller.set('content.reassign.component_name', 'MYSQL_SERVER');
  1268. controller.set('content.reassignHosts.target', 'host2');
  1269. controller.configureMySqlServer();
  1270. expect(App.ajax.send.calledWith({
  1271. name: 'service.mysql.configure',
  1272. sender: controller,
  1273. data: {
  1274. host: 'host2'
  1275. },
  1276. success: 'startPolling',
  1277. error: 'onTaskError'
  1278. })).to.be.true;
  1279. });
  1280. });
  1281. describe("#startRequiredServices()", function() {
  1282. beforeEach(function () {
  1283. sinon.stub(controller, 'startServices', Em.K);
  1284. });
  1285. afterEach(function () {
  1286. controller.startServices.restore();
  1287. });
  1288. it("component has related services", function() {
  1289. controller.set('content.reassign.component_name', 'JOBTRACKER');
  1290. controller.startRequiredServices();
  1291. expect(controller.startServices.calledWith(false, ['HDFS', 'ZOOKEEPER', 'HBASE', 'FLUME', 'SQOOP', 'STORM'])).to.be.true;
  1292. });
  1293. it("component does not have related services", function() {
  1294. controller.set('content.reassign.component_name', 'C1');
  1295. controller.startRequiredServices();
  1296. expect(controller.startServices.calledWith(true)).to.be.true;
  1297. });
  1298. });
  1299. describe("#setSpecificHiveConfigs()", function() {
  1300. beforeEach(function () {
  1301. sinon.stub(App.HostComponent, 'find').returns([
  1302. {
  1303. componentName: 'HIVE_METASTORE',
  1304. hostName: 'host1'
  1305. },
  1306. {
  1307. componentName: 'HIVE_METASTORE',
  1308. hostName: 'host3'
  1309. },
  1310. {
  1311. componentName: 'HIVE_SERVER',
  1312. hostName: 'host4'
  1313. }
  1314. ]);
  1315. });
  1316. afterEach(function () {
  1317. App.HostComponent.find.restore();
  1318. });
  1319. it("reassign component is HIVE_METASTORE", function() {
  1320. var configs = {
  1321. 'hive-env': {
  1322. 'hive_user': 'hive_user',
  1323. 'webhcat_user': 'webhcat_user'
  1324. },
  1325. 'hive-site': {
  1326. 'hive.metastore.uris': ''
  1327. },
  1328. 'webhcat-site': {
  1329. 'templeton.hive.properties': 'thrift'
  1330. },
  1331. 'core-site': {
  1332. }
  1333. };
  1334. controller.set('content.reassignHosts.source', 'host1');
  1335. controller.set('content.reassign.component_name', 'HIVE_METASTORE');
  1336. controller.setSpecificHiveConfigs(configs, 'host2');
  1337. expect(configs['hive-site']['hive.metastore.uris']).to.equal('thrift://host3:9083,thrift://host2:9083');
  1338. expect(configs['webhcat-site']['templeton.hive.properties']).to.equal('thrift');
  1339. expect(configs['core-site']['hadoop.proxyuser.hive_user.hosts']).to.equal('host3,host2,host4');
  1340. expect(configs['core-site']['hadoop.proxyuser.webhcat_user.hosts']).to.equal('host3,host2,host4');
  1341. });
  1342. it("reassign component is HIVE_SERVER", function() {
  1343. var configs = {
  1344. 'hive-env': {
  1345. 'hive_user': 'hive_user',
  1346. 'webhcat_user': 'webhcat_user'
  1347. },
  1348. 'hive-site': {
  1349. 'hive.metastore.uris': ''
  1350. },
  1351. 'webhcat-site': {
  1352. 'templeton.hive.properties': 'thrift'
  1353. },
  1354. 'core-site': {
  1355. }
  1356. };
  1357. controller.set('content.reassignHosts.source', 'host1');
  1358. controller.set('content.reassign.component_name', 'HIVE_SERVER');
  1359. controller.setSpecificHiveConfigs(configs, 'host2');
  1360. expect(configs['hive-site']['hive.metastore.uris']).to.equal('thrift://host1:9083,thrift://host3:9083');
  1361. expect(configs['webhcat-site']['templeton.hive.properties']).to.equal('thrift');
  1362. expect(configs['core-site']['hadoop.proxyuser.hive_user.hosts']).to.equal('host1,host3,host4,host2');
  1363. expect(configs['core-site']['hadoop.proxyuser.webhcat_user.hosts']).to.equal('host1,host3,host4,host2');
  1364. });
  1365. });
  1366. describe("#startMySqlServer()", function() {
  1367. beforeEach(function () {
  1368. sinon.stub(App.HostComponent, 'find').returns([
  1369. Em.Object.create({
  1370. componentName: 'MYSQL_SERVER',
  1371. hostName: 'host1'
  1372. })
  1373. ]);
  1374. });
  1375. afterEach(function () {
  1376. App.HostComponent.find.restore();
  1377. });
  1378. it("", function() {
  1379. controller.startMySqlServer();
  1380. expect(App.ajax.send.calledWith({
  1381. name: 'common.host.host_component.update',
  1382. sender: controller,
  1383. data: {
  1384. context: "Start MySQL Server",
  1385. hostName: 'host1',
  1386. serviceName: "HIVE",
  1387. componentName: "MYSQL_SERVER",
  1388. HostRoles: {
  1389. state: "STARTED"
  1390. }
  1391. },
  1392. success: 'startPolling',
  1393. error: 'onTaskError'
  1394. })).to.be.true;
  1395. });
  1396. });
  1397. describe("#restartMySqlServer()", function() {
  1398. beforeEach(function () {
  1399. sinon.stub(App.HostComponent, 'find').returns([
  1400. Em.Object.create({
  1401. componentName: 'MYSQL_SERVER',
  1402. hostName: 'host1'
  1403. })
  1404. ]);
  1405. });
  1406. afterEach(function () {
  1407. App.HostComponent.find.restore();
  1408. });
  1409. it("", function() {
  1410. controller.set('content', Em.Object.create({
  1411. cluster: Em.Object.create({
  1412. name: 'cl1'
  1413. })
  1414. }));
  1415. controller.restartMySqlServer();
  1416. expect(App.ajax.send.calledWith({
  1417. name: 'restart.hostComponents',
  1418. sender: controller,
  1419. data: {
  1420. context: 'Restart MySql Server',
  1421. resource_filters: [{
  1422. component_name: "MYSQL_SERVER",
  1423. hosts: 'host1',
  1424. service_name: "HIVE"
  1425. }],
  1426. operation_level: {
  1427. level: "HOST_COMPONENT",
  1428. cluster_name: 'cl1',
  1429. service_name: "HIVE",
  1430. hostcomponent_name: "MYSQL_SERVER"
  1431. }
  1432. },
  1433. success: 'startPolling',
  1434. error: 'onTaskError'
  1435. })).to.be.true;
  1436. });
  1437. });
  1438. describe("#startNewMySqlServer()", function() {
  1439. it("", function() {
  1440. controller.set('content', Em.Object.create({
  1441. reassignHosts: Em.Object.create({
  1442. target: 'host1'
  1443. })
  1444. }));
  1445. controller.startNewMySqlServer();
  1446. expect(App.ajax.send.calledWith({
  1447. name: 'common.host.host_component.update',
  1448. sender: controller,
  1449. data: {
  1450. context: "Start MySQL Server",
  1451. hostName: 'host1',
  1452. serviceName: "HIVE",
  1453. componentName: "MYSQL_SERVER",
  1454. HostRoles: {
  1455. state: "STARTED"
  1456. }
  1457. },
  1458. success: 'startPolling',
  1459. error: 'onTaskError'
  1460. })).to.be.true;
  1461. });
  1462. });
  1463. });