details_test.js 125 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783
  1. /**
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. var App = require('app');
  19. require('controllers/main/host/details');
  20. require('models/service');
  21. require('models/host_component');
  22. require('models/host_stack_version');
  23. var batchUtils = require('utils/batch_scheduled_requests');
  24. var hostsManagement = require('utils/hosts');
  25. var controller;
  26. function getController() {
  27. return App.MainHostDetailsController.create(App.InstallComponent, {
  28. content: Em.Object.create({
  29. hostComponents: []
  30. })
  31. });
  32. }
  33. describe('App.MainHostDetailsController', function () {
  34. beforeEach(function () {
  35. sinon.stub(App.ajax, 'send').returns({
  36. then: Em.K,
  37. complete: Em.K
  38. });
  39. controller = getController();
  40. });
  41. afterEach(function () {
  42. App.ajax.send.restore();
  43. });
  44. App.TestAliases.testAsComputedFilterBy(getController(), 'serviceNonClientActiveComponents', 'serviceActiveComponents', 'isClient', false);
  45. describe('#routeHome()', function () {
  46. it('transiotion to dashboard', function () {
  47. sinon.stub(App.router, 'transitionTo', Em.K);
  48. controller.routeHome();
  49. expect(App.router.transitionTo.calledWith('main.dashboard.index')).to.be.true;
  50. App.router.transitionTo.restore();
  51. });
  52. });
  53. describe('#startComponent()', function () {
  54. it('call sendComponentCommand', function () {
  55. var event = {
  56. context: Em.Object.create({
  57. displayName: 'comp'
  58. })
  59. };
  60. sinon.stub(App, 'showConfirmationPopup', function (callback) {
  61. callback();
  62. });
  63. sinon.stub(controller, 'sendComponentCommand');
  64. controller.startComponent(event);
  65. expect(App.showConfirmationPopup.calledOnce).to.be.true;
  66. expect(controller.sendComponentCommand.calledWith(Em.Object.create({
  67. displayName: 'comp'
  68. })), Em.I18n.t('requestInfo.startHostComponent') + " comp", App.HostComponentStatus.started).to.be.true;
  69. App.showConfirmationPopup.restore();
  70. controller.sendComponentCommand.restore();
  71. });
  72. });
  73. describe('#stopComponent()', function () {
  74. beforeEach(function () {
  75. sinon.stub(App, 'showConfirmationPopup', Em.clb);
  76. sinon.stub(controller, 'checkNnLastCheckpointTime', Em.clb);
  77. sinon.stub(controller, 'sendComponentCommand');
  78. });
  79. afterEach(function () {
  80. App.showConfirmationPopup.restore();
  81. controller.sendComponentCommand.restore();
  82. controller.checkNnLastCheckpointTime.restore();
  83. });
  84. it('call sendComponentCommand', function () {
  85. var event = {
  86. context: Em.Object.create({
  87. displayName: 'comp'
  88. })
  89. };
  90. controller.stopComponent(event);
  91. expect(App.showConfirmationPopup.calledOnce).to.be.true;
  92. expect(controller.sendComponentCommand.calledWith(Em.Object.create({
  93. displayName: 'comp'
  94. })), Em.I18n.t('requestInfo.stopHostComponent') + " comp", App.HostComponentStatus.stopped).to.be.true;
  95. });
  96. it('stop NN, should check last NN checkpoint before stop', function () {
  97. var event = {
  98. context: Em.Object.create({
  99. displayName: 'NameNode',
  100. componentName: 'NAMENODE'
  101. })
  102. };
  103. controller.stopComponent(event);
  104. expect(controller.checkNnLastCheckpointTime.calledOnce).to.be.true;
  105. expect(App.showConfirmationPopup.calledOnce).to.be.true;
  106. expect(controller.sendComponentCommand.calledWith(event.context, Em.I18n.t('requestInfo.stopHostComponent') + " NameNode", App.HostComponentStatus.stopped)).to.be.true;
  107. });
  108. });
  109. describe("#pullNnCheckPointTime()", function() {
  110. it("valid request is sent", function() {
  111. controller.pullNnCheckPointTime('host1');
  112. expect(App.ajax.send.calledWith({
  113. name: 'common.host_component.getNnCheckPointTime',
  114. sender: controller,
  115. data: {
  116. host: 'host1'
  117. },
  118. success: 'parseNnCheckPointTime'
  119. })).to.be.true;
  120. });
  121. });
  122. describe('#sendComponentCommand()', function () {
  123. it('single component', function () {
  124. controller.set('content.hostName', 'host1');
  125. var component = Em.Object.create({
  126. service: {serviceName: 'S1'},
  127. componentName: 'COMP1'
  128. });
  129. controller.sendComponentCommand(component, {}, 'state');
  130. expect(App.ajax.send.getCall(0).args[0].name).to.be.equal('common.host.host_component.update');
  131. expect(App.ajax.send.getCall(0).args[0].data).to.be.eql({
  132. "hostName": "host1",
  133. "context": {},
  134. "component": component,
  135. "HostRoles": {
  136. "state": "state"
  137. },
  138. "componentName": "COMP1",
  139. "serviceName": "S1"
  140. });
  141. });
  142. it('multiple component', function () {
  143. controller.set('content.hostName', 'host1');
  144. var component = [
  145. Em.Object.create({
  146. service: {serviceName: 'S1'},
  147. componentName: 'COMP1'
  148. }),
  149. Em.Object.create({
  150. service: {serviceName: 'S1'},
  151. componentName: 'COMP2'
  152. })
  153. ];
  154. controller.sendComponentCommand(component, {}, 'state');
  155. expect(App.ajax.send.getCall(0).args[0].name).to.be.equal('common.host.host_components.update');
  156. expect(App.ajax.send.getCall(0).args[0].data).to.be.eql({
  157. "hostName": "host1",
  158. "context": {},
  159. "component": component,
  160. "HostRoles": {
  161. "state": "state"
  162. },
  163. "query": "HostRoles/component_name.in(COMP1,COMP2)"
  164. });
  165. });
  166. });
  167. describe('#sendComponentCommandSuccessCallback()', function () {
  168. beforeEach(function () {
  169. sinon.stub(controller, 'mimicWorkStatusChange', Em.K);
  170. sinon.stub(controller, 'showBackgroundOperationsPopup', Em.K);
  171. });
  172. afterEach(function () {
  173. controller.showBackgroundOperationsPopup.restore();
  174. controller.mimicWorkStatusChange.restore();
  175. });
  176. it('testMode, starting component', function () {
  177. var params = {
  178. component: Em.Object.create({}),
  179. HostRoles: {
  180. state: App.HostComponentStatus.started
  181. }
  182. };
  183. App.set('testMode', true);
  184. controller.sendComponentCommandSuccessCallback({}, {}, params);
  185. expect(controller.mimicWorkStatusChange.calledWith(Em.Object.create({
  186. workStatus: App.HostComponentStatus.starting
  187. }), App.HostComponentStatus.starting, App.HostComponentStatus.started)).to.be.true;
  188. expect(controller.showBackgroundOperationsPopup.calledOnce).to.be.true;
  189. });
  190. it('testMode, stopping component', function () {
  191. var params = {
  192. component: Em.Object.create({}),
  193. HostRoles: {
  194. state: App.HostComponentStatus.stopped
  195. }
  196. };
  197. App.set('testMode', true);
  198. controller.sendComponentCommandSuccessCallback({}, {}, params);
  199. expect(controller.mimicWorkStatusChange.calledWith(Em.Object.create({
  200. workStatus: App.HostComponentStatus.stopping
  201. }), App.HostComponentStatus.stopping, App.HostComponentStatus.stopped)).to.be.true;
  202. expect(controller.showBackgroundOperationsPopup.calledOnce).to.be.true;
  203. });
  204. it('testMode, stopping component', function () {
  205. var params = {
  206. component: Em.Object.create({}),
  207. HostRoles: {
  208. state: App.HostComponentStatus.stopped
  209. }
  210. };
  211. App.set('testMode', false);
  212. controller.sendComponentCommandSuccessCallback({}, {}, params);
  213. expect(controller.mimicWorkStatusChange.called).to.be.false;
  214. expect(controller.showBackgroundOperationsPopup.calledOnce).to.be.true;
  215. });
  216. });
  217. describe('#ajaxErrorCallback()', function () {
  218. it('call mainServiceItemController.ajaxErrorCallback', function () {
  219. sinon.stub(controller, 'ajaxErrorCallback', Em.K);
  220. controller.ajaxErrorCallback('request', 'ajaxOptions', 'error', 'opt', 'params');
  221. expect(controller.ajaxErrorCallback.calledWith('request', 'ajaxOptions', 'error', 'opt', 'params')).to.be.true;
  222. controller.ajaxErrorCallback.restore();
  223. });
  224. });
  225. describe('#showBackgroundOperationsPopup()', function () {
  226. var mock = {
  227. done: function (callback) {
  228. callback(this.initValue);
  229. }
  230. };
  231. var bgController = {
  232. showPopup: Em.K
  233. };
  234. beforeEach(function () {
  235. var stub = sinon.stub(App.router, 'get');
  236. stub.withArgs('userSettingsController').returns({
  237. dataLoading: function () {
  238. return mock;
  239. }
  240. });
  241. stub.withArgs('backgroundOperationsController').returns(bgController);
  242. sinon.spy(bgController, 'showPopup');
  243. sinon.spy(mock, 'done');
  244. });
  245. afterEach(function () {
  246. bgController.showPopup.restore();
  247. mock.done.restore();
  248. App.router.get.restore();
  249. });
  250. it('initValue is true, callback is undefined', function () {
  251. mock.initValue = true;
  252. controller.showBackgroundOperationsPopup();
  253. expect(mock.done.calledOnce).to.be.true;
  254. expect(bgController.showPopup.calledOnce).to.be.true;
  255. });
  256. it('initValue is false, callback is defined', function () {
  257. mock.initValue = false;
  258. var callback = sinon.stub();
  259. controller.showBackgroundOperationsPopup(callback);
  260. expect(mock.done.calledOnce).to.be.true;
  261. expect(bgController.showPopup.calledOnce).to.be.false;
  262. expect(callback.calledOnce).to.be.true;
  263. });
  264. });
  265. describe('#serviceActiveComponents', function () {
  266. it('No host-components', function () {
  267. controller.set('content', {hostComponents: []});
  268. expect(controller.get('serviceActiveComponents')).to.be.empty;
  269. });
  270. it('No host-components in active state', function () {
  271. controller.set('content', {
  272. hostComponents: [Em.Object.create({
  273. service: {
  274. isInPassive: true
  275. }
  276. })]
  277. });
  278. expect(controller.get('serviceActiveComponents')).to.be.empty;
  279. });
  280. it('Host-components in active state', function () {
  281. controller.set('content', {
  282. hostComponents: [Em.Object.create({
  283. service: {
  284. isInPassive: false
  285. }
  286. })]
  287. });
  288. expect(controller.get('serviceActiveComponents')).to.eql([Em.Object.create({
  289. service: {
  290. isInPassive: false
  291. }
  292. })]);
  293. });
  294. });
  295. describe('#serviceNonClientActiveComponents', function () {
  296. it('No active host-components', function () {
  297. controller.reopen({
  298. serviceActiveComponents: []
  299. });
  300. controller.set('serviceActiveComponents', []);
  301. expect(controller.get('serviceNonClientActiveComponents')).to.be.empty;
  302. });
  303. it('Active host-component is client', function () {
  304. controller.reopen({
  305. serviceActiveComponents: [Em.Object.create({
  306. isClient: true
  307. })]
  308. });
  309. expect(controller.get('serviceNonClientActiveComponents')).to.be.empty;
  310. });
  311. it('Active host-component is not client', function () {
  312. controller.reopen({
  313. serviceActiveComponents: [Em.Object.create({
  314. isClient: false
  315. })]
  316. });
  317. expect(controller.get('serviceNonClientActiveComponents')).to.eql([Em.Object.create({
  318. isClient: false
  319. })]);
  320. });
  321. });
  322. describe.skip('#deleteComponent()', function () {
  323. var jQueryMock,
  324. cases = [
  325. {
  326. isDisabled: false,
  327. showCallCount: 1,
  328. title: 'confirm popup should be displayed'
  329. },
  330. {
  331. isDisabled: true,
  332. showCallCount: 0,
  333. title: 'confirm popup shouldn\'t be displayed'
  334. }
  335. ];
  336. beforeEach(function () {
  337. jQueryMock = sinon.stub(window, '$');
  338. sinon.spy(App.ModalPopup, 'show');
  339. sinon.stub(controller, '_doDeleteHostComponent', Em.K);
  340. });
  341. afterEach(function () {
  342. jQueryMock.restore();
  343. App.ModalPopup.show.restore();
  344. controller._doDeleteHostComponent.restore();
  345. });
  346. cases.forEach(function (item) {
  347. it(item.title, function () {
  348. jQueryMock.returns({
  349. closest: function () {
  350. return {
  351. hasClass: function () {
  352. return item.isDisabled;
  353. }
  354. }
  355. }
  356. });
  357. var event = {
  358. context: Em.Object.create({})
  359. },
  360. popup = controller.deleteComponent(event);
  361. expect(App.ModalPopup.show.callCount).to.equal(item.showCallCount);
  362. if (item.showCallCount) {
  363. popup.onPrimary();
  364. expect(controller._doDeleteHostComponent.calledWith(Em.Object.create({}))).to.be.true;
  365. }
  366. });
  367. });
  368. });
  369. describe('#mimicWorkStatusChange()', function () {
  370. var clock;
  371. beforeEach(function () {
  372. clock = sinon.useFakeTimers();
  373. });
  374. afterEach(function () {
  375. clock.restore();
  376. });
  377. it('change status of object', function () {
  378. var entity = Em.Object.create({
  379. workStatus: ''
  380. });
  381. controller.mimicWorkStatusChange(entity, 'STATE1', 'STATE2');
  382. expect(entity.get('workStatus')).to.equal('STATE1');
  383. clock.tick(App.testModeDelayForActions);
  384. expect(entity.get('workStatus')).to.equal('STATE2');
  385. });
  386. it('change status of objects in array', function () {
  387. var entity = [Em.Object.create({
  388. workStatus: ''
  389. })];
  390. controller.mimicWorkStatusChange(entity, 'STATE1', 'STATE2');
  391. expect(entity[0].get('workStatus')).to.equal('STATE1');
  392. clock.tick(App.testModeDelayForActions);
  393. expect(entity[0].get('workStatus')).to.equal('STATE2');
  394. });
  395. });
  396. describe('#upgradeComponent()', function () {
  397. beforeEach(function () {
  398. sinon.spy(App, "showConfirmationPopup");
  399. });
  400. afterEach(function () {
  401. App.showConfirmationPopup.restore();
  402. });
  403. it('confirm popup should be displayed', function () {
  404. var popup = controller.upgradeComponent({context: Em.Object.create()});
  405. expect(App.showConfirmationPopup.calledOnce).to.be.true;
  406. popup.onPrimary();
  407. expect(App.ajax.send.calledOnce).to.be.true;
  408. });
  409. });
  410. describe('#restartComponent()', function () {
  411. beforeEach(function () {
  412. sinon.spy(App, "showConfirmationPopup");
  413. sinon.stub(batchUtils, "restartHostComponents", Em.K);
  414. sinon.stub(controller, 'checkNnLastCheckpointTime', function(callback) {
  415. callback();
  416. });
  417. });
  418. afterEach(function () {
  419. App.showConfirmationPopup.restore();
  420. batchUtils.restartHostComponents.restore();
  421. controller.checkNnLastCheckpointTime.restore();
  422. });
  423. it('popup should be displayed', function () {
  424. var popup = controller.restartComponent({context: Em.Object.create({'displayName': 'Comp1'})});
  425. expect(App.showConfirmationPopup.calledOnce).to.be.true;
  426. popup.onPrimary();
  427. expect(batchUtils.restartHostComponents.calledOnce).to.be.true;
  428. });
  429. it('restart NN, should check last NN checkpoint before restart', function () {
  430. var event = {
  431. context: Em.Object.create({
  432. displayName: 'NameNode',
  433. componentName: 'NAMENODE'
  434. })
  435. };
  436. controller.restartComponent(event);
  437. expect(controller.checkNnLastCheckpointTime.calledOnce).to.equal(true);
  438. expect(App.showConfirmationPopup.calledOnce).to.be.true;
  439. });
  440. });
  441. describe('#addComponent()', function () {
  442. beforeEach(function () {
  443. sinon.spy(App, "showConfirmationPopup");
  444. sinon.stub(controller, "addClientComponent", Em.K);
  445. sinon.stub(controller, "installHostComponentCall", Em.K);
  446. sinon.stub(controller, "checkComponentDependencies", Em.K);
  447. controller.set('content', {
  448. hostComponents: [Em.Object.create({
  449. componentName: "HDFS_CLIENT"
  450. })]
  451. });
  452. controller.reopen({
  453. securityEnabled: false
  454. });
  455. });
  456. afterEach(function () {
  457. App.showConfirmationPopup.restore();
  458. controller.addClientComponent.restore();
  459. controller.installHostComponentCall.restore();
  460. controller.checkComponentDependencies.restore();
  461. });
  462. it('add ZOOKEEPER_SERVER', function () {
  463. var event = {
  464. context: Em.Object.create({
  465. componentName: 'ZOOKEEPER_SERVER'
  466. })
  467. };
  468. controller.addComponent(event);
  469. expect(App.showConfirmationPopup.calledOnce).to.be.true;
  470. });
  471. it('add WEBHCAT_SERVER', function () {
  472. var event = {
  473. context: Em.Object.create({
  474. componentName: 'WEBHCAT_SERVER'
  475. })
  476. };
  477. controller.addComponent(event);
  478. expect(App.showConfirmationPopup.calledOnce).to.be.true;
  479. });
  480. it('add slave component', function () {
  481. var event = {
  482. context: Em.Object.create({
  483. componentName: 'HIVE_CLIENT'
  484. })
  485. };
  486. controller.set('securityEnabled', false);
  487. controller.addComponent(event);
  488. expect(controller.addClientComponent.calledWith(Em.Object.create({
  489. componentName: 'HIVE_CLIENT'
  490. }))).to.be.true;
  491. });
  492. });
  493. describe('#formatClientsMessage()', function () {
  494. var testCases = [
  495. {
  496. title: 'subComponentNames is null',
  497. client: Em.Object.create({
  498. subComponentNames: null,
  499. displayName: 'CLIENTS'
  500. }),
  501. result: 'CLIENTS'
  502. },
  503. {
  504. title: 'subComponentNames is empty',
  505. client: Em.Object.create({
  506. subComponentNames: [],
  507. displayName: 'CLIENTS'
  508. }),
  509. result: 'CLIENTS'
  510. },
  511. {
  512. title: 'displayName is null',
  513. client: Em.Object.create({
  514. subComponentNames: ['DATANODE'],
  515. displayName: null
  516. }),
  517. result: ' (DataNode)'
  518. },
  519. {
  520. title: 'displayName is CLIENTS',
  521. client: Em.Object.create({
  522. subComponentNames: ['DATANODE'],
  523. displayName: 'CLIENTS'
  524. }),
  525. result: 'CLIENTS (DataNode)'
  526. }
  527. ];
  528. testCases.forEach(function (test) {
  529. it(test.title, function () {
  530. expect(controller.formatClientsMessage(test.client)).to.equal(test.result);
  531. });
  532. });
  533. });
  534. describe('#addClientComponent()', function () {
  535. var component = Em.Object.create({
  536. componentName: ' Comp1'
  537. });
  538. beforeEach(function () {
  539. sinon.spy(controller, 'showAddComponentPopup');
  540. sinon.stub(controller, 'installHostComponentCall', Em.K);
  541. });
  542. afterEach(function () {
  543. controller.showAddComponentPopup.restore();
  544. controller.installHostComponentCall.restore();
  545. });
  546. it('any CLIENT component', function () {
  547. controller.set('content.hostName', 'host1');
  548. var popup = controller.addClientComponent(component);
  549. expect(controller.showAddComponentPopup.calledOnce).to.be.true;
  550. popup.onPrimary();
  551. expect(controller.installHostComponentCall.calledWith('host1', component)).to.be.true;
  552. });
  553. });
  554. describe("#loadOozieConfigs()", function() {
  555. it("valid request is sent", function() {
  556. controller.loadOozieConfigs({Clusters: {
  557. desired_configs: {
  558. 'oozie-env': {
  559. tag: 'tag'
  560. }
  561. }
  562. }});
  563. expect(App.ajax.send.calledWith({
  564. name: 'admin.get.all_configurations',
  565. sender: controller,
  566. data: {
  567. urlParams: '(type=oozie-env&tag=tag)'
  568. },
  569. success: 'onLoadOozieConfigs',
  570. error: 'onLoadConfigsErrorCallback'
  571. })).to.be.true;
  572. });
  573. });
  574. describe("#loadStormConfigs()", function() {
  575. it("valid request is sent", function() {
  576. controller.loadStormConfigs({Clusters: {
  577. desired_configs: {
  578. 'storm-site': {
  579. tag: 'tag'
  580. }
  581. }
  582. }});
  583. expect(App.ajax.send.calledWith({
  584. name: 'admin.get.all_configurations',
  585. sender: controller,
  586. data: {
  587. urlParams: '(type=storm-site&tag=tag)'
  588. },
  589. success: 'onLoadStormConfigs'
  590. })).to.be.true;
  591. });
  592. });
  593. describe("#onLoadStormConfigs()", function() {
  594. var data = {items: [
  595. {
  596. type: 'storm-site',
  597. properties: {
  598. 'nimbus.seeds': ''
  599. }
  600. }
  601. ]};
  602. beforeEach(function () {
  603. sinon.stub(controller, 'getStormNimbusHosts').returns("host1");
  604. sinon.stub(controller, 'updateZkConfigs', Em.K);
  605. sinon.stub(controller, 'saveConfigsBatch', Em.K);
  606. controller.set('nimbusHost', 'host2');
  607. controller.onLoadStormConfigs(data);
  608. });
  609. afterEach(function () {
  610. controller.getStormNimbusHosts.restore();
  611. controller.updateZkConfigs.restore();
  612. controller.saveConfigsBatch.restore();
  613. });
  614. it("updateZkConfigs called with valid arguments", function() {
  615. expect(controller.updateZkConfigs.calledWith({'storm-site': {
  616. 'nimbus.seeds': "'host1'"
  617. }})).to.be.true;
  618. });
  619. it('saveConfigsBatch called with valid arguments', function () {
  620. expect(controller.saveConfigsBatch.calledWith([
  621. {
  622. properties: {
  623. 'storm-site': {
  624. 'nimbus.seeds': "'host1'"
  625. }
  626. },
  627. properties_attributes: {
  628. 'storm-site': {}
  629. }
  630. }
  631. ], 'NIMBUS', 'host2')).to.be.true;
  632. });
  633. });
  634. describe("#loadHiveConfigs()", function() {
  635. it("valid request is sent", function() {
  636. controller.loadHiveConfigs({Clusters: {
  637. desired_configs: {
  638. 'hive-site': {
  639. tag: 'tag'
  640. },
  641. 'webhcat-site': {
  642. tag: 'tag'
  643. },
  644. 'hive-env': {
  645. tag: 'tag'
  646. },
  647. 'core-site': {
  648. tag: 'tag'
  649. }
  650. }
  651. }});
  652. expect(App.ajax.send.calledWith({
  653. name: 'admin.get.all_configurations',
  654. sender: controller,
  655. data: {
  656. urlParams: '(type=hive-site&tag=tag)|(type=webhcat-site&tag=tag)|(type=hive-env&tag=tag)|(type=core-site&tag=tag)'
  657. },
  658. success: 'onLoadHiveConfigs'
  659. })).to.be.true;
  660. });
  661. });
  662. describe("#loadRangerConfigs()", function() {
  663. it("valid request is sent", function() {
  664. controller.loadRangerConfigs({Clusters: {
  665. desired_configs: {
  666. 'hdfs-site': {
  667. tag: 'tag'
  668. },
  669. 'kms-env': {
  670. tag: 'tag'
  671. },
  672. 'core-site': {
  673. tag: 'tag'
  674. }
  675. }
  676. }});
  677. expect(App.ajax.send.calledWith({
  678. name: 'admin.get.all_configurations',
  679. sender: controller,
  680. data: {
  681. urlParams: '(type=core-site&tag=tag)|(type=hdfs-site&tag=tag)|(type=kms-env&tag=tag)'
  682. },
  683. success: 'onLoadRangerConfigs'
  684. })).to.be.true;
  685. });
  686. });
  687. describe("#getRangerKMSServerHosts()", function() {
  688. beforeEach(function(){
  689. sinon.stub(App.HostComponent, 'find').returns([{
  690. componentName: 'RANGER_KMS_SERVER',
  691. hostName: 'host1'
  692. }]);
  693. controller.set('rangerKMSServerHost', 'host2');
  694. controller.set('content.hostName', 'host1');
  695. controller.set('deleteRangerKMSServer', true);
  696. controller.set('fromDeleteHost', true);
  697. this.hosts = controller.getRangerKMSServerHosts();
  698. });
  699. afterEach(function(){
  700. App.HostComponent.find.restore();
  701. });
  702. it('hosts list is valid', function() {
  703. expect(this.hosts).to.eql(['host2']);
  704. });
  705. it('rangerKMSServerHost is empty', function () {
  706. expect(controller.get('rangerKMSServerHost')).to.be.empty;
  707. });
  708. it('deleteRangerKMSServer is false', function () {
  709. expect(controller.get('deleteRangerKMSServer')).to.be.false;
  710. });
  711. it('fromDeleteHost is false', function () {
  712. expect(controller.get('fromDeleteHost')).to.be.false;
  713. });
  714. });
  715. describe("#getStormNimbusHosts()", function() {
  716. beforeEach(function(){
  717. sinon.stub(App.HostComponent, 'find').returns([{
  718. componentName: 'NIMBUS',
  719. hostName: 'host1'
  720. }]);
  721. controller.set('nimbusHost', 'host2');
  722. controller.set('content.hostName', 'host1');
  723. controller.set('deleteNimbusHost', true);
  724. controller.set('fromDeleteHost', true);
  725. this.hosts = controller.getStormNimbusHosts();
  726. });
  727. afterEach(function(){
  728. App.HostComponent.find.restore();
  729. });
  730. it("hosts list is valid", function() {
  731. expect(this.hosts).to.eql(['host2']);
  732. });
  733. it('nimbusHost is empty', function () {
  734. expect(controller.get('nimbusHost')).to.be.empty;
  735. });
  736. it('deleteNimbusHost is false', function () {
  737. expect(controller.get('deleteNimbusHost')).to.be.false;
  738. });
  739. it('fromDeleteHost is false', function () {
  740. expect(controller.get('fromDeleteHost')).to.be.false;
  741. });
  742. });
  743. describe('#showAddComponentPopup()', function () {
  744. var message = 'Comp1',
  745. component = Em.Object.create({
  746. componentName: ' Comp1'
  747. });
  748. beforeEach(function () {
  749. sinon.spy(App.ModalPopup, 'show');
  750. });
  751. afterEach(function () {
  752. App.ModalPopup.show.restore();
  753. });
  754. it('should display add component confirmation', function () {
  755. var popup = controller.showAddComponentPopup(message, false, Em.K);
  756. expect(App.ModalPopup.show.calledOnce).to.be.true;
  757. expect(popup.get('addComponentMsg')).to.eql(Em.I18n.t('hosts.host.addComponent.msg').format(message));
  758. });
  759. });
  760. describe('#installNewComponentSuccessCallback()', function () {
  761. beforeEach(function () {
  762. sinon.stub(controller, "showBackgroundOperationsPopup", Em.K);
  763. });
  764. afterEach(function () {
  765. controller.showBackgroundOperationsPopup.restore();
  766. });
  767. it('data is null', function () {
  768. var data = {Requests: null};
  769. expect(controller.installNewComponentSuccessCallback(null, {}, {})).to.be.false;
  770. expect(controller.showBackgroundOperationsPopup.called).to.be.false;
  771. });
  772. it('data.Requests is null', function () {
  773. var data = {Requests: null};
  774. expect(controller.installNewComponentSuccessCallback(data, {}, {})).to.be.false;
  775. expect(controller.showBackgroundOperationsPopup.called).to.be.false;
  776. });
  777. it('data.Requests.id is null', function () {
  778. var data = {Requests: {id: null}};
  779. expect(controller.installNewComponentSuccessCallback(data, {}, {})).to.be.false;
  780. expect(controller.showBackgroundOperationsPopup.called).to.be.false;
  781. });
  782. it('data.Requests.id is correct', function () {
  783. var data = {Requests: {id: 1}};
  784. expect(controller.installNewComponentSuccessCallback(data, {}, {component: []})).to.be.true;
  785. expect(controller.showBackgroundOperationsPopup.calledOnce).to.be.true;
  786. });
  787. });
  788. describe('#refreshComponentConfigs()', function () {
  789. beforeEach(function () {
  790. sinon.spy(App, "showConfirmationPopup");
  791. sinon.stub(controller, "sendRefreshComponentConfigsCommand", Em.K);
  792. });
  793. afterEach(function () {
  794. App.showConfirmationPopup.restore();
  795. controller.sendRefreshComponentConfigsCommand.restore();
  796. });
  797. it('popup should be displayed', function () {
  798. var popup = controller.refreshComponentConfigs({context: Em.Object.create({'displayName': 'Comp1'})});
  799. expect(App.showConfirmationPopup.calledOnce).to.be.true;
  800. popup.onPrimary();
  801. expect(controller.sendRefreshComponentConfigsCommand.calledOnce).to.be.true;
  802. });
  803. });
  804. describe('#sendRefreshComponentConfigsCommand()', function () {
  805. it('Query should be sent', function () {
  806. var component = Em.Object.create({
  807. service: {},
  808. componentName: 'COMP1',
  809. host: {}
  810. });
  811. controller.sendRefreshComponentConfigsCommand(component, {});
  812. expect(App.ajax.send.calledOnce).to.be.true;
  813. });
  814. });
  815. describe('#loadConfigs()', function () {
  816. it('Query should be sent', function () {
  817. controller.loadConfigs();
  818. expect(App.ajax.send.calledOnce).to.be.true;
  819. });
  820. });
  821. describe('#constructConfigUrlParams()', function () {
  822. it('URL params should be empty', function () {
  823. var data = {};
  824. App.Service.find().clear();
  825. expect(controller.constructConfigUrlParams(data)).to.eql([]);
  826. });
  827. it('isHaEnabled = true', function () {
  828. App.store.load(App.Service, {
  829. id: 'HDFS',
  830. service_name: 'HDFS'
  831. });
  832. var data = {Clusters: {desired_configs: {'core-site': {tag: 1}}}};
  833. App.HostComponent.find().clear();
  834. App.propertyDidChange('isHaEnabled');
  835. expect(controller.constructConfigUrlParams(data)).to.eql(['(type=core-site&tag=1)']);
  836. App.store.load(App.HostComponent, {
  837. id: 'SECONDARY_NAMENODE_host1',
  838. component_name: 'SECONDARY_NAMENODE'
  839. });
  840. App.set('currentStackVersion', 'HDP-2.0.1');
  841. });
  842. it('HBASE is installed', function () {
  843. App.store.load(App.Service, {
  844. id: 'HBASE',
  845. service_name: 'HBASE'
  846. });
  847. App.propertyDidChange('isHaEnabled');
  848. var data = {Clusters: {desired_configs: {'hbase-site': {tag: 1}}}};
  849. expect(controller.constructConfigUrlParams(data)).to.eql(['(type=hbase-site&tag=1)']);
  850. App.Service.find().clear();
  851. });
  852. it('HIVE is installed', function () {
  853. App.store.load(App.Service, {
  854. id: 'HIVE',
  855. service_name: 'HIVE'
  856. });
  857. var data = {Clusters: {desired_configs: {'webhcat-site': {tag: 1}, 'hive-site': {tag: 1}}}};
  858. expect(controller.constructConfigUrlParams(data)).to.eql(['(type=webhcat-site&tag=1)', '(type=hive-site&tag=1)']);
  859. App.Service.find().clear();
  860. });
  861. it('STORM is installed', function () {
  862. App.store.load(App.Service, {
  863. id: 'STORM',
  864. service_name: 'STORM'
  865. });
  866. var data = {Clusters: {desired_configs: {'storm-site': {tag: 1}}}};
  867. expect(controller.constructConfigUrlParams(data)).to.eql(['(type=storm-site&tag=1)']);
  868. App.Service.find().clear();
  869. });
  870. it('YARN for 2.2 stack is installed', function () {
  871. App.set('currentStackVersion', 'HDP-2.2.0');
  872. App.store.load(App.Service, {
  873. id: 'YARN',
  874. service_name: 'YARN'
  875. });
  876. var data = {Clusters: {desired_configs: {'yarn-site': {tag: 1}, 'zoo.cfg': {tag: 1}}}};
  877. expect(controller.constructConfigUrlParams(data)).to.eql(['(type=yarn-site&tag=1)', '(type=zoo.cfg&tag=1)']);
  878. App.set('currentStackVersion', 'HDP-2.0.1');
  879. App.Service.find().clear();
  880. });
  881. it('isRMHaEnabled true', function () {
  882. sinon.stub(App, 'get').withArgs('isRMHaEnabled').returns(true);
  883. var data = {Clusters: {desired_configs: {'yarn-site': {tag: 1}, 'zoo.cfg': {tag: 1}}}};
  884. expect(controller.constructConfigUrlParams(data)).to.eql(['(type=yarn-site&tag=1)', '(type=zoo.cfg&tag=1)']);
  885. App.get.restore();
  886. });
  887. });
  888. describe('#loadConfigsSuccessCallback()', function () {
  889. var mockUrlParams = [];
  890. beforeEach(function () {
  891. sinon.stub(controller, "constructConfigUrlParams", function () {
  892. return mockUrlParams;
  893. });
  894. });
  895. afterEach(function () {
  896. controller.constructConfigUrlParams.restore();
  897. });
  898. it('url params is empty', function () {
  899. expect(controller.loadConfigsSuccessCallback()).to.be.false;
  900. expect(App.ajax.send.called).to.be.false;
  901. });
  902. it('url params are correct', function () {
  903. mockUrlParams = ['param1'];
  904. expect(controller.loadConfigsSuccessCallback()).to.be.true;
  905. expect(App.ajax.send.calledOnce).to.be.true;
  906. });
  907. });
  908. describe('#saveZkConfigs()', function () {
  909. var yarnCases = [
  910. {
  911. isYARNInstalled: true,
  912. isHadoop22Stack: true,
  913. isRMHaEnabled: true,
  914. shouldYarnSiteBeModified: true,
  915. title: 'HDP 2.2, YARN installed, RM HA enabled'
  916. },
  917. {
  918. isYARNInstalled: true,
  919. isHadoop22Stack: false,
  920. isRMHaEnabled: true,
  921. shouldYarnSiteBeModified: true,
  922. title: 'HDP < 2.2, YARN installed, RM HA enabled'
  923. },
  924. {
  925. isYARNInstalled: true,
  926. isHadoop22Stack: true,
  927. isRMHaEnabled: false,
  928. shouldYarnSiteBeModified: true,
  929. title: 'HDP 2.2, YARN installed, RM HA disabled'
  930. },
  931. {
  932. isYARNInstalled: false,
  933. isHadoop22Stack: true,
  934. isRMHaEnabled: false,
  935. shouldYarnSiteBeModified: false,
  936. title: 'HDP 2.2, YARN not installed'
  937. },
  938. {
  939. isYARNInstalled: true,
  940. isHadoop22Stack: false,
  941. isRMHaEnabled: false,
  942. shouldYarnSiteBeModified: false,
  943. title: 'HDP < 2.2, YARN installed, RM HA disabled'
  944. },
  945. {
  946. isYARNInstalled: false,
  947. isHadoop22Stack: false,
  948. isRMHaEnabled: false,
  949. shouldYarnSiteBeModified: false,
  950. title: 'HDP < 2.2, YARN not installed'
  951. }
  952. ],
  953. yarnData = {
  954. items: [
  955. {
  956. type: 'yarn-site',
  957. properties: {
  958. p: 'v'
  959. }
  960. }
  961. ]
  962. };
  963. beforeEach(function () {
  964. sinon.stub(controller, 'saveConfigsBatch', Em.K);
  965. });
  966. afterEach(function () {
  967. controller.saveConfigsBatch.restore();
  968. });
  969. it('call saveConfigsBatch()', function () {
  970. var data = {items: []};
  971. controller.saveZkConfigs(data);
  972. expect(controller.saveConfigsBatch.calledOnce).to.be.true;
  973. });
  974. yarnCases.forEach(function (item) {
  975. it(item.title, function () {
  976. var servicesMock = item.isYARNInstalled ? [
  977. {
  978. serviceName: 'YARN'
  979. }
  980. ] : [];
  981. sinon.stub(App, 'get').withArgs('isHadoop22Stack').returns(item.isHadoop22Stack).
  982. withArgs('isRMHaEnabled').returns(item.isRMHaEnabled);
  983. sinon.stub(App.Service, 'find').returns(servicesMock);
  984. controller.saveZkConfigs(yarnData);
  985. expect(controller.saveConfigsBatch.firstCall.args[0].someProperty('properties.yarn-site')).to.equal(item.shouldYarnSiteBeModified);
  986. expect(controller.saveConfigsBatch.firstCall.args[0].someProperty('properties_attributes.yarn-site')).to.equal(item.shouldYarnSiteBeModified);
  987. App.get.restore();
  988. App.Service.find.restore();
  989. });
  990. });
  991. });
  992. describe("#saveConfigsBatch()", function () {
  993. it("no groups", function () {
  994. controller.saveConfigsBatch([]);
  995. expect(App.ajax.send.called).to.be.false;
  996. });
  997. it("configs is empty", function () {
  998. controller.saveConfigsBatch([{}]);
  999. expect(App.ajax.send.called).to.be.false;
  1000. });
  1001. it("configs is correct", function () {
  1002. controller.saveConfigsBatch([{'properties': {'site': {}}, 'properties_attributes': {'site': {}}}]);
  1003. expect(App.ajax.send.calledOnce).to.be.true;
  1004. });
  1005. });
  1006. describe('#updateZkConfigs()', function () {
  1007. var makeHostComponentModel = function(componentName, hostNames) {
  1008. return hostNames.map(function(hostName) {
  1009. return {
  1010. componentName: componentName,
  1011. hostName: hostName
  1012. };
  1013. });
  1014. };
  1015. var tests = [
  1016. {
  1017. appGetterStubs: {
  1018. isHaEnabled: true
  1019. },
  1020. hostComponentModel: makeHostComponentModel('ZOOKEEPER_SERVER', ['host1', 'host2']),
  1021. configs: {
  1022. "core-site": {
  1023. "ha.zookeeper.quorum": "host2:8080"
  1024. }
  1025. },
  1026. m: 'NameNode HA enabled, ha.zookeeper.quorum config should be updated',
  1027. e: {
  1028. configs: {
  1029. "core-site": {
  1030. "ha.zookeeper.quorum": "host1:2181,host2:2181"
  1031. }
  1032. }
  1033. }
  1034. },
  1035. {
  1036. appGetterStubs: {
  1037. isHaEnabled: false
  1038. },
  1039. hostComponentModel: makeHostComponentModel('ZOOKEEPER_SERVER', ['host1', 'host2']),
  1040. configs: {
  1041. "core-site": {
  1042. "ha.zookeeper.quorum": "host3:8080"
  1043. }
  1044. },
  1045. m: 'NameNode HA disabled, ha.zookeeper.quorum config should be untouched',
  1046. e: {
  1047. configs: {
  1048. "core-site": {
  1049. "ha.zookeeper.quorum": "host3:8080"
  1050. }
  1051. }
  1052. }
  1053. },
  1054. {
  1055. hostComponentModel: makeHostComponentModel('ZOOKEEPER_SERVER', ['host1', 'host2']),
  1056. configs: {
  1057. "hbase-site": {
  1058. "hbase.zookeeper.quorum": "host3"
  1059. }
  1060. },
  1061. m: 'hbase.zookeeper.quorum property update test',
  1062. e: {
  1063. configs: {
  1064. "hbase-site": {
  1065. "hbase.zookeeper.quorum": "host1,host2"
  1066. }
  1067. }
  1068. }
  1069. },
  1070. {
  1071. hostComponentModel: makeHostComponentModel('ZOOKEEPER_SERVER', ['host1', 'host2']),
  1072. ctrlStubs: {
  1073. 'content.hostName': 'host2',
  1074. fromDeleteHost: true
  1075. },
  1076. configs: {
  1077. "zoo.cfg": {
  1078. "clientPort": "1919"
  1079. },
  1080. "accumulo-site": {
  1081. "instance.zookeeper.host": "host3:2020"
  1082. }
  1083. },
  1084. m: 'instance.zookeeper.host property update test, zookeper marked to delete from host2',
  1085. e: {
  1086. configs: {
  1087. "zoo.cfg": {
  1088. "clientPort": "1919"
  1089. },
  1090. "accumulo-site": {
  1091. "instance.zookeeper.host": "host1:1919"
  1092. }
  1093. }
  1094. }
  1095. },
  1096. {
  1097. hostComponentModel: makeHostComponentModel('ZOOKEEPER_SERVER', ['host1', 'host2']),
  1098. configs: {
  1099. "webhcat-site": {
  1100. "templeton.zookeeper.hosts": "host3:2020"
  1101. }
  1102. },
  1103. m: 'templeton.zookeeper.hosts property update test',
  1104. e: {
  1105. configs: {
  1106. "webhcat-site": {
  1107. "templeton.zookeeper.hosts": "host1:2181,host2:2181"
  1108. }
  1109. }
  1110. }
  1111. },
  1112. {
  1113. hostComponentModel: makeHostComponentModel('ZOOKEEPER_SERVER', ['host1', 'host2']),
  1114. configs: {
  1115. "hive-site": {
  1116. "hive.cluster.delegation.token.store.zookeeper.connectString": "host3:2020"
  1117. }
  1118. },
  1119. m: 'hive.cluster.delegation.token.store.zookeeper.connectString property update test',
  1120. e: {
  1121. configs: {
  1122. "hive-site": {
  1123. "hive.cluster.delegation.token.store.zookeeper.connectString": "host1:2181,host2:2181"
  1124. }
  1125. }
  1126. }
  1127. },
  1128. {
  1129. hostComponentModel: makeHostComponentModel('ZOOKEEPER_SERVER', ['host1', 'host2']),
  1130. configs: {
  1131. "storm-site": {
  1132. "storm.zookeeper.servers": "['host3','host2']"
  1133. }
  1134. },
  1135. m: 'storm.zookeeper.servers property update test',
  1136. e: {
  1137. configs: {
  1138. "storm-site": {
  1139. "storm.zookeeper.servers": "['host1','host2']"
  1140. }
  1141. }
  1142. }
  1143. },
  1144. {
  1145. appGetterStubs: {
  1146. isRMHaEnabled: true
  1147. },
  1148. hostComponentModel: makeHostComponentModel('ZOOKEEPER_SERVER', ['host1', 'host2']),
  1149. configs: {
  1150. "yarn-site": {
  1151. "yarn.resourcemanager.zk-address": "host3:2181"
  1152. }
  1153. },
  1154. m: 'yarn.resourcemanager.zk-address property, ResourceManager HA enabled. Property value should be changed.',
  1155. e: {
  1156. configs: {
  1157. "yarn-site": {
  1158. "yarn.resourcemanager.zk-address": "host1:2181,host2:2181"
  1159. }
  1160. }
  1161. }
  1162. },
  1163. {
  1164. appGetterStubs: {
  1165. isRMHaEnabled: false
  1166. },
  1167. hostComponentModel: makeHostComponentModel('ZOOKEEPER_SERVER', ['host1', 'host2']),
  1168. configs: {
  1169. "yarn-site": {
  1170. "yarn.resourcemanager.zk-address": "host3:2181"
  1171. }
  1172. },
  1173. m: 'yarn.resourcemanager.zk-address property, ResourceManager HA not activated. Property value should be untouched.',
  1174. e: {
  1175. configs: {
  1176. "yarn-site": {
  1177. "yarn.resourcemanager.zk-address": "host3:2181"
  1178. }
  1179. }
  1180. }
  1181. },
  1182. {
  1183. appGetterStubs: {
  1184. currentStackVersionNumber: '2.2'
  1185. },
  1186. hostComponentModel: makeHostComponentModel('ZOOKEEPER_SERVER', ['host1', 'host2']),
  1187. configs: {
  1188. "hive-site": {
  1189. "hive.zookeeper.quorum": "host3:2181"
  1190. }
  1191. },
  1192. m: 'hive.zookeeper.quorum property, current stack version is 2.2 property should be updated.',
  1193. e: {
  1194. configs: {
  1195. "hive-site": {
  1196. "hive.zookeeper.quorum": "host1:2181,host2:2181"
  1197. }
  1198. }
  1199. }
  1200. },
  1201. {
  1202. appGetterStubs: {
  1203. currentStackVersionNumber: '2.1'
  1204. },
  1205. hostComponentModel: makeHostComponentModel('ZOOKEEPER_SERVER', ['host1', 'host2']),
  1206. configs: {
  1207. "hive-site": {
  1208. "hive.zookeeper.quorum": "host3:2181"
  1209. }
  1210. },
  1211. m: 'hive.zookeeper.quorum property, current stack version is 2.1 property should be untouched.',
  1212. e: {
  1213. configs: {
  1214. "hive-site": {
  1215. "hive.zookeeper.quorum": "host3:2181"
  1216. }
  1217. }
  1218. }
  1219. },
  1220. {
  1221. appGetterStubs: {
  1222. currentStackVersionNumber: '2.1'
  1223. },
  1224. hostComponentModel: makeHostComponentModel('ZOOKEEPER_SERVER', ['host1', 'host2']),
  1225. configs: {
  1226. "yarn-site": {
  1227. "hadoop.registry.zk.quorum": "host3:2181"
  1228. }
  1229. },
  1230. m: 'hadoop.registry.zk.quorum property, current stack version is 2.1 property should be untouched.',
  1231. e: {
  1232. configs: {
  1233. "yarn-site": {
  1234. "hadoop.registry.zk.quorum": "host3:2181"
  1235. }
  1236. }
  1237. }
  1238. },
  1239. {
  1240. appGetterStubs: {
  1241. currentStackVersionNumber: '2.2'
  1242. },
  1243. hostComponentModel: makeHostComponentModel('ZOOKEEPER_SERVER', ['host1', 'host2']),
  1244. configs: {
  1245. "yarn-site": {
  1246. "hadoop.registry.zk.quorum": "host3:2181"
  1247. }
  1248. },
  1249. m: 'hadoop.registry.zk.quorum property, current stack version is 2.2 property should be changed.',
  1250. e: {
  1251. configs: {
  1252. "yarn-site": {
  1253. "hadoop.registry.zk.quorum": "host1:2181,host2:2181"
  1254. }
  1255. }
  1256. }
  1257. }
  1258. ];
  1259. tests.forEach(function(test) {
  1260. it(test.m, function() {
  1261. if (test.appGetterStubs) {
  1262. Em.keys(test.appGetterStubs).forEach(function(key) {
  1263. sinon.stub(App, 'get').withArgs(key).returns(test.appGetterStubs[key]);
  1264. });
  1265. }
  1266. if (test.ctrlStubs) {
  1267. var stub = sinon.stub(controller, 'get');
  1268. Em.keys(test.ctrlStubs).forEach(function(key) {
  1269. stub.withArgs(key).returns(test.ctrlStubs[key]);
  1270. });
  1271. }
  1272. sinon.stub(App.HostComponent, 'find').returns(test.hostComponentModel);
  1273. controller.updateZkConfigs(test.configs);
  1274. expect(test.configs).to.be.eql(test.e.configs);
  1275. if (test.ctrlStubs) controller.get.restore();
  1276. if (test.appGetterStubs) App.get.restore();
  1277. App.HostComponent.find.restore();
  1278. });
  1279. });
  1280. });
  1281. describe('#installComponent()', function () {
  1282. beforeEach(function () {
  1283. sinon.spy(App.ModalPopup, "show");
  1284. });
  1285. afterEach(function () {
  1286. App.ModalPopup.show.restore();
  1287. });
  1288. it('popup should be displayed', function () {
  1289. var event = {context: Em.Object.create()};
  1290. var popup = controller.installComponent(event);
  1291. expect(App.ModalPopup.show.calledOnce).to.be.true;
  1292. popup.onPrimary();
  1293. expect(App.ajax.send.called).to.be.true;
  1294. });
  1295. });
  1296. describe('#decommission()', function () {
  1297. beforeEach(function () {
  1298. sinon.spy(App, "showConfirmationPopup");
  1299. sinon.stub(controller, "runDecommission", Em.K);
  1300. });
  1301. afterEach(function () {
  1302. App.showConfirmationPopup.restore();
  1303. controller.runDecommission.restore();
  1304. });
  1305. it('popup should be displayed', function () {
  1306. var popup = controller.decommission(Em.Object.create({service: {}}));
  1307. expect(App.showConfirmationPopup.calledOnce).to.be.true;
  1308. popup.onPrimary();
  1309. expect(controller.runDecommission.calledOnce).to.be.true;
  1310. });
  1311. });
  1312. describe('#recommission()', function () {
  1313. beforeEach(function () {
  1314. sinon.spy(App, "showConfirmationPopup");
  1315. sinon.stub(controller, "runRecommission", Em.K);
  1316. });
  1317. afterEach(function () {
  1318. App.showConfirmationPopup.restore();
  1319. controller.runRecommission.restore();
  1320. });
  1321. it('popup should be displayed', function () {
  1322. var popup = controller.recommission(Em.Object.create({service: {}}));
  1323. expect(App.showConfirmationPopup.calledOnce).to.be.true;
  1324. popup.onPrimary();
  1325. expect(controller.runRecommission.calledOnce).to.be.true;
  1326. });
  1327. });
  1328. describe('#runDecommission()', function () {
  1329. beforeEach(function () {
  1330. sinon.stub(controller, "doDecommission", Em.K);
  1331. sinon.stub(controller, "showBackgroundOperationsPopup", Em.K);
  1332. });
  1333. afterEach(function () {
  1334. controller.doDecommission.restore();
  1335. controller.showBackgroundOperationsPopup.restore();
  1336. });
  1337. it('HDFS service', function () {
  1338. controller.runDecommission('host1', 'HDFS');
  1339. expect(controller.doDecommission.calledWith('host1', 'HDFS', "NAMENODE", "DATANODE")).to.be.true;
  1340. });
  1341. it('YARN service', function () {
  1342. controller.runDecommission('host1', 'YARN');
  1343. expect(controller.doDecommission.calledWith('host1', 'YARN', "RESOURCEMANAGER", "NODEMANAGER")).to.be.true;
  1344. });
  1345. it('HBASE service', function () {
  1346. sinon.stub(controller, 'warnBeforeDecommission', Em.K);
  1347. controller.runDecommission('host1', 'HBASE');
  1348. expect(controller.warnBeforeDecommission.calledWith('host1')).to.be.true;
  1349. controller.warnBeforeDecommission.restore();
  1350. });
  1351. });
  1352. describe('#runRecommission()', function () {
  1353. beforeEach(function () {
  1354. sinon.stub(controller, "doRecommissionAndStart", Em.K);
  1355. sinon.stub(controller, "showBackgroundOperationsPopup", Em.K);
  1356. });
  1357. afterEach(function () {
  1358. controller.doRecommissionAndStart.restore();
  1359. controller.showBackgroundOperationsPopup.restore();
  1360. });
  1361. it('HDFS service', function () {
  1362. controller.runRecommission('host1', 'HDFS');
  1363. expect(controller.doRecommissionAndStart.calledWith('host1', 'HDFS', "NAMENODE", "DATANODE")).to.be.true;
  1364. expect(controller.showBackgroundOperationsPopup.calledOnce).to.be.true;
  1365. });
  1366. it('YARN service', function () {
  1367. controller.runRecommission('host1', 'YARN');
  1368. expect(controller.doRecommissionAndStart.calledWith('host1', 'YARN', "RESOURCEMANAGER", "NODEMANAGER")).to.be.true;
  1369. expect(controller.showBackgroundOperationsPopup.calledOnce).to.be.true;
  1370. });
  1371. it('HBASE service', function () {
  1372. controller.runRecommission('host1', 'HBASE');
  1373. expect(controller.doRecommissionAndStart.calledWith('host1', 'HBASE', "HBASE_MASTER", "HBASE_REGIONSERVER")).to.be.true;
  1374. expect(controller.showBackgroundOperationsPopup.calledOnce).to.be.true;
  1375. });
  1376. });
  1377. describe('#doDecommission()', function () {
  1378. it('Query should be sent', function () {
  1379. controller.doDecommission('', '', '', '');
  1380. expect(App.ajax.send.calledOnce).to.be.true;
  1381. });
  1382. });
  1383. describe('#doDecommissionRegionServer()', function () {
  1384. it('Query should be sent', function () {
  1385. controller.doDecommissionRegionServer('', '', '', '');
  1386. expect(App.ajax.send.calledOnce).to.be.true;
  1387. });
  1388. });
  1389. describe('#warnBeforeDecommission()', function () {
  1390. beforeEach(function () {
  1391. sinon.stub(controller, "showHbaseActiveWarning", Em.K);
  1392. sinon.stub(controller, "checkRegionServerState", Em.K);
  1393. });
  1394. afterEach(function () {
  1395. controller.checkRegionServerState.restore();
  1396. controller.showHbaseActiveWarning.restore();
  1397. });
  1398. it('Component in passive state', function () {
  1399. controller.set('content.hostComponents', [Em.Object.create({
  1400. componentName: 'HBASE_REGIONSERVER',
  1401. passiveState: 'ON'
  1402. })]);
  1403. controller.warnBeforeDecommission('host1');
  1404. expect(controller.checkRegionServerState.calledOnce).to.be.true;
  1405. });
  1406. it('Component is not in passive state', function () {
  1407. controller.set('content.hostComponents', [Em.Object.create({
  1408. componentName: 'HBASE_REGIONSERVER',
  1409. passiveState: 'OFF'
  1410. })]);
  1411. controller.warnBeforeDecommission('host1');
  1412. expect(controller.showHbaseActiveWarning.calledOnce).to.be.true;
  1413. });
  1414. });
  1415. describe('#checkRegionServerState()', function () {
  1416. var result;
  1417. beforeEach(function () {
  1418. result = controller.checkRegionServerState('host1');
  1419. });
  1420. it('returns object', function () {
  1421. expect(result).to.be.an('object');
  1422. });
  1423. it('request is sent with correct data', function () {
  1424. expect(App.ajax.send.getCall(0).args[0].data.hostNames).to.equal('host1');
  1425. });
  1426. });
  1427. describe('#checkRegionServerStateSuccessCallback()', function () {
  1428. beforeEach(function () {
  1429. sinon.stub(controller, "doDecommissionRegionServer", Em.K);
  1430. sinon.stub(controller, "showRegionServerWarning", Em.K);
  1431. });
  1432. afterEach(function () {
  1433. controller.doDecommissionRegionServer.restore();
  1434. controller.showRegionServerWarning.restore();
  1435. });
  1436. it('Decommission all regionservers', function () {
  1437. var data = {
  1438. items: [
  1439. {
  1440. HostRoles: {
  1441. host_name: 'host1'
  1442. }
  1443. },
  1444. {
  1445. HostRoles: {
  1446. host_name: 'host2'
  1447. }
  1448. }
  1449. ]
  1450. };
  1451. controller.checkRegionServerStateSuccessCallback(data, {}, {hostNames: 'host1,host2'});
  1452. expect(controller.showRegionServerWarning.calledOnce).to.be.true;
  1453. });
  1454. it('Decommission one of two regionservers', function () {
  1455. var data = {
  1456. items: [
  1457. {
  1458. HostRoles: {
  1459. host_name: 'host1'
  1460. }
  1461. },
  1462. {
  1463. HostRoles: {
  1464. host_name: 'host2'
  1465. }
  1466. }
  1467. ]
  1468. };
  1469. controller.checkRegionServerStateSuccessCallback(data, {}, {hostNames: 'host1'});
  1470. expect(controller.doDecommissionRegionServer.calledWith('host1', "HBASE", "HBASE_MASTER", "HBASE_REGIONSERVER")).to.be.true;
  1471. });
  1472. it('Decommission one of three regionservers', function () {
  1473. var data = {
  1474. items: [
  1475. {
  1476. HostRoles: {
  1477. host_name: 'host1'
  1478. }
  1479. },
  1480. {
  1481. HostRoles: {
  1482. host_name: 'host2'
  1483. }
  1484. },
  1485. {
  1486. HostRoles: {
  1487. host_name: 'host3'
  1488. }
  1489. }
  1490. ]
  1491. };
  1492. controller.checkRegionServerStateSuccessCallback(data, {}, {hostNames: 'host1'});
  1493. expect(controller.doDecommissionRegionServer.calledWith('host1', "HBASE", "HBASE_MASTER", "HBASE_REGIONSERVER")).to.be.true;
  1494. });
  1495. });
  1496. describe('#showRegionServerWarning()', function () {
  1497. beforeEach(function () {
  1498. sinon.stub(App.ModalPopup, 'show', Em.K);
  1499. });
  1500. afterEach(function () {
  1501. App.ModalPopup.show.restore();
  1502. });
  1503. it('modal popup is shown', function () {
  1504. controller.showRegionServerWarning();
  1505. expect(App.ModalPopup.show.calledOnce).to.be.true;
  1506. });
  1507. });
  1508. describe('#doRecommissionAndStart()', function () {
  1509. it('Query should be sent', function () {
  1510. controller.doRecommissionAndStart('', '', '', '');
  1511. expect(App.ajax.send.calledOnce).to.be.true;
  1512. });
  1513. });
  1514. describe('#decommissionSuccessCallback()', function () {
  1515. beforeEach(function () {
  1516. sinon.stub(controller, "showBackgroundOperationsPopup", Em.K);
  1517. });
  1518. afterEach(function () {
  1519. controller.showBackgroundOperationsPopup.restore();
  1520. });
  1521. it('data is null', function () {
  1522. expect(controller.decommissionSuccessCallback(null)).to.be.false;
  1523. expect(controller.showBackgroundOperationsPopup.called).to.be.false;
  1524. });
  1525. it('data has Requests', function () {
  1526. var data = {Requests: []};
  1527. expect(controller.decommissionSuccessCallback(data)).to.be.true;
  1528. expect(controller.showBackgroundOperationsPopup.calledOnce).to.be.true;
  1529. });
  1530. it('data has resources', function () {
  1531. var data = {
  1532. resources: [
  1533. {RequestSchedule: {}}
  1534. ]
  1535. };
  1536. expect(controller.decommissionSuccessCallback(data)).to.be.true;
  1537. expect(controller.showBackgroundOperationsPopup.calledOnce).to.be.true;
  1538. });
  1539. });
  1540. describe('#doAction()', function () {
  1541. beforeEach(function () {
  1542. sinon.stub(controller, "validateAndDeleteHost", Em.K);
  1543. sinon.stub(controller, "doStartAllComponents", Em.K);
  1544. sinon.stub(controller, "doStopAllComponents", Em.K);
  1545. sinon.stub(controller, "doRestartAllComponents", Em.K);
  1546. sinon.stub(controller, "onOffPassiveModeForHost", Em.K);
  1547. sinon.stub(controller, "setRackIdForHost", Em.K);
  1548. });
  1549. afterEach(function () {
  1550. controller.validateAndDeleteHost.restore();
  1551. controller.doStartAllComponents.restore();
  1552. controller.doStopAllComponents.restore();
  1553. controller.doRestartAllComponents.restore();
  1554. controller.onOffPassiveModeForHost.restore();
  1555. controller.setRackIdForHost.restore();
  1556. });
  1557. it('"deleteHost" action', function () {
  1558. var option = {context: {action: "deleteHost"}};
  1559. controller.doAction(option);
  1560. expect(controller.validateAndDeleteHost.calledOnce).to.be.true;
  1561. });
  1562. it('"startAllComponents" action, isNotHeartBeating = false', function () {
  1563. var option = {context: {action: "startAllComponents"}};
  1564. controller.set('content', {isNotHeartBeating: false});
  1565. controller.doAction(option);
  1566. expect(controller.doStartAllComponents.calledOnce).to.be.true;
  1567. });
  1568. it('"startAllComponents" action, isNotHeartBeating = true', function () {
  1569. var option = {context: {action: "startAllComponents"}};
  1570. controller.set('content', {isNotHeartBeating: true});
  1571. controller.doAction(option);
  1572. expect(controller.doStartAllComponents.called).to.be.false;
  1573. });
  1574. it('"stopAllComponents" action, isNotHeartBeating = false', function () {
  1575. var option = {context: {action: "stopAllComponents"}};
  1576. controller.set('content', {isNotHeartBeating: false});
  1577. controller.doAction(option);
  1578. expect(controller.doStopAllComponents.calledOnce).to.be.true;
  1579. });
  1580. it('"stopAllComponents" action, isNotHeartBeating = true', function () {
  1581. var option = {context: {action: "stopAllComponents"}};
  1582. controller.set('content', {isNotHeartBeating: true});
  1583. controller.doAction(option);
  1584. expect(controller.doStopAllComponents.called).to.be.false;
  1585. });
  1586. it('"restartAllComponents" action, isNotHeartBeating = false', function () {
  1587. var option = {context: {action: "restartAllComponents"}};
  1588. controller.set('content', {isNotHeartBeating: false});
  1589. controller.doAction(option);
  1590. expect(controller.doRestartAllComponents.calledOnce).to.be.true;
  1591. });
  1592. it('"restartAllComponents" action, isNotHeartBeating = true', function () {
  1593. var option = {context: {action: "restartAllComponents"}};
  1594. controller.set('content', {isNotHeartBeating: true});
  1595. controller.doAction(option);
  1596. expect(controller.doRestartAllComponents.called).to.be.false;
  1597. });
  1598. it('"onOffPassiveModeForHost" action', function () {
  1599. var option = {context: {action: "onOffPassiveModeForHost"}};
  1600. controller.doAction(option);
  1601. expect(controller.onOffPassiveModeForHost.calledWith({action: "onOffPassiveModeForHost"})).to.be.true;
  1602. });
  1603. it('"setRackId" action', function () {
  1604. var option = {context: {action: "setRackId"}};
  1605. controller.doAction(option);
  1606. expect(controller.setRackIdForHost.calledOnce).to.be.true;
  1607. });
  1608. });
  1609. describe("#setRackIdForHost()", function() {
  1610. beforeEach(function(){
  1611. sinon.stub(hostsManagement, 'setRackInfo', Em.K);
  1612. });
  1613. afterEach(function() {
  1614. hostsManagement.setRackInfo.restore();
  1615. });
  1616. it('setRackInfo called with valid arguments', function() {
  1617. controller.set('content.rack', 'rack');
  1618. controller.set('content.hostName', 'host1');
  1619. controller.setRackIdForHost();
  1620. expect(hostsManagement.setRackInfo.calledWith({message: Em.I18n.t('hosts.host.details.setRackId')}, [{hostName: 'host1'}], 'rack')).to.be.true;
  1621. });
  1622. });
  1623. describe('#onOffPassiveModeForHost()', function () {
  1624. beforeEach(function () {
  1625. sinon.spy(App, "showConfirmationPopup");
  1626. sinon.stub(controller, "hostPassiveModeRequest", Em.K);
  1627. });
  1628. afterEach(function () {
  1629. App.showConfirmationPopup.restore();
  1630. controller.hostPassiveModeRequest.restore();
  1631. });
  1632. it('popup should be displayed, active = true', function () {
  1633. var popup = controller.onOffPassiveModeForHost({active: true});
  1634. expect(App.showConfirmationPopup.calledOnce).to.be.true;
  1635. popup.onPrimary();
  1636. expect(controller.hostPassiveModeRequest.calledWith('ON')).to.be.true;
  1637. });
  1638. it('popup should be displayed, active = false', function () {
  1639. var popup = controller.onOffPassiveModeForHost({active: false});
  1640. expect(App.showConfirmationPopup.calledOnce).to.be.true;
  1641. popup.onPrimary();
  1642. expect(controller.hostPassiveModeRequest.calledWith('OFF')).to.be.true;
  1643. });
  1644. });
  1645. describe('#hostPassiveModeRequest()', function () {
  1646. it('Query should be sent', function () {
  1647. controller.hostPassiveModeRequest('', '');
  1648. expect(App.ajax.send.calledOnce).to.be.true;
  1649. });
  1650. });
  1651. describe('#doStartAllComponents()', function () {
  1652. beforeEach(function () {
  1653. sinon.spy(App, "showConfirmationPopup");
  1654. sinon.stub(controller, 'sendComponentCommand', Em.K);
  1655. });
  1656. afterEach(function () {
  1657. App.showConfirmationPopup.restore();
  1658. controller.sendComponentCommand.restore();
  1659. });
  1660. it('serviceNonClientActiveComponents is empty', function () {
  1661. controller.reopen({
  1662. serviceNonClientActiveComponents: Em.A([])
  1663. });
  1664. controller.doStartAllComponents();
  1665. expect(App.showConfirmationPopup.called).to.be.false;
  1666. });
  1667. it('serviceNonClientActiveComponents is correct', function () {
  1668. controller.reopen({
  1669. serviceNonClientActiveComponents: Em.A([{}])
  1670. });
  1671. var popup = controller.doStartAllComponents();
  1672. expect(App.showConfirmationPopup.calledOnce).to.be.true;
  1673. popup.onPrimary();
  1674. expect(controller.sendComponentCommand.calledWith(
  1675. controller.get('serviceNonClientActiveComponents'),
  1676. Em.I18n.t('hosts.host.maintainance.startAllComponents.context'),
  1677. App.HostComponentStatus.started)
  1678. ).to.be.true;
  1679. });
  1680. });
  1681. describe('#doStopAllComponents()', function () {
  1682. beforeEach(function () {
  1683. sinon.spy(App, "showConfirmationPopup");
  1684. sinon.stub(controller, 'sendComponentCommand', Em.K);
  1685. sinon.stub(controller, 'checkNnLastCheckpointTime', function(callback){
  1686. callback();
  1687. });
  1688. });
  1689. afterEach(function () {
  1690. App.showConfirmationPopup.restore();
  1691. controller.sendComponentCommand.restore();
  1692. controller.checkNnLastCheckpointTime.restore();
  1693. });
  1694. it('serviceNonClientActiveComponents is empty', function () {
  1695. controller.reopen({
  1696. serviceNonClientActiveComponents: []
  1697. });
  1698. controller.doStopAllComponents();
  1699. expect(App.showConfirmationPopup.called).to.be.false;
  1700. });
  1701. it('serviceNonClientActiveComponents is correct', function () {
  1702. controller.reopen({
  1703. serviceNonClientActiveComponents: Em.A([{}])
  1704. });
  1705. var popup = controller.doStopAllComponents();
  1706. expect(App.showConfirmationPopup.calledOnce).to.be.true;
  1707. popup.onPrimary();
  1708. expect(controller.sendComponentCommand.calledWith(
  1709. controller.get('serviceNonClientActiveComponents'),
  1710. Em.I18n.t('hosts.host.maintainance.stopAllComponents.context'),
  1711. App.HostComponentStatus.stopped)
  1712. ).to.be.true;
  1713. });
  1714. it('serviceNonClientActiveComponents is correct, NAMENODE started', function () {
  1715. controller.reopen({
  1716. serviceNonClientActiveComponents: Em.A([Em.Object.create({
  1717. componentName: 'NAMENODE',
  1718. workStatus: 'STARTED'
  1719. })])
  1720. });
  1721. controller.set('content.hostComponents', [Em.Object.create({
  1722. componentName: 'NAMENODE',
  1723. workStatus: 'STARTED'
  1724. })]);
  1725. controller.doStopAllComponents();
  1726. expect(controller.checkNnLastCheckpointTime.calledOnce).to.be.true;
  1727. expect(App.showConfirmationPopup.calledOnce).to.be.true;
  1728. });
  1729. });
  1730. describe('#doRestartAllComponents()', function () {
  1731. beforeEach(function () {
  1732. sinon.spy(App, "showConfirmationPopup");
  1733. sinon.stub(batchUtils, 'restartHostComponents', Em.K);
  1734. sinon.stub(controller, 'checkNnLastCheckpointTime', function(callback){
  1735. callback();
  1736. });
  1737. });
  1738. afterEach(function () {
  1739. App.showConfirmationPopup.restore();
  1740. batchUtils.restartHostComponents.restore();
  1741. controller.checkNnLastCheckpointTime.restore();
  1742. });
  1743. it('serviceActiveComponents is empty', function () {
  1744. controller.reopen({
  1745. serviceActiveComponents: []
  1746. });
  1747. controller.doRestartAllComponents();
  1748. expect(App.showConfirmationPopup.called).to.be.false;
  1749. });
  1750. it('serviceActiveComponents is correct', function () {
  1751. var components = [{}];
  1752. controller.reopen({
  1753. serviceActiveComponents: components
  1754. });
  1755. var popup = controller.doRestartAllComponents();
  1756. expect(App.showConfirmationPopup.calledOnce).to.be.true;
  1757. popup.onPrimary();
  1758. expect(batchUtils.restartHostComponents.calledWith(components)).to.be.true;
  1759. });
  1760. it('serviceActiveComponents is correct, NAMENODE started', function () {
  1761. controller.reopen({
  1762. serviceActiveComponents: Em.A([Em.Object.create({
  1763. componentName: 'NAMENODE',
  1764. workStatus: 'STARTED'
  1765. })])
  1766. });
  1767. controller.set('content.hostComponents', [Em.Object.create({
  1768. componentName: 'NAMENODE',
  1769. workStatus: 'STARTED'
  1770. })]);
  1771. controller.doRestartAllComponents();
  1772. expect(controller.checkNnLastCheckpointTime.calledOnce).to.be.true;
  1773. expect(App.showConfirmationPopup.calledOnce).to.be.true;
  1774. });
  1775. });
  1776. describe('#getHostComponentsInfo()', function () {
  1777. var result = {
  1778. zkServerInstalled: false,
  1779. lastComponents: [],
  1780. masterComponents: [],
  1781. runningComponents: [],
  1782. nonDeletableComponents: [],
  1783. unknownComponents: [],
  1784. toDecommissionComponents: []
  1785. };
  1786. it('content.hostComponents is null', function () {
  1787. controller.set('content', {hostComponents: null});
  1788. expect(controller.getHostComponentsInfo()).to.eql(result);
  1789. });
  1790. it('content.hostComponents is empty', function () {
  1791. controller.set('content', {hostComponents: []});
  1792. expect(controller.getHostComponentsInfo()).to.eql(result);
  1793. });
  1794. it('content.hostComponents has ZOOKEEPER_SERVER', function () {
  1795. App.HostComponent.find().clear();
  1796. controller.set('content', {
  1797. hostComponents: [Em.Object.create({
  1798. componentName: 'ZOOKEEPER_SERVER',
  1799. workStatus: 'INIT',
  1800. isDeletable: true
  1801. })]
  1802. });
  1803. expect(controller.getHostComponentsInfo().zkServerInstalled).to.be.true;
  1804. });
  1805. it('content.hostComponents has last component', function () {
  1806. sinon.stub(App.HostComponent, 'find', function () {
  1807. return [
  1808. {
  1809. id: 'TASKTRACKER_host1',
  1810. componentName: 'TASKTRACKER'
  1811. }
  1812. ];
  1813. });
  1814. controller.set('content', {
  1815. hostComponents: [Em.Object.create({
  1816. componentName: 'TASKTRACKER',
  1817. displayName: 'TaskTracker',
  1818. workStatus: 'INIT',
  1819. isDeletable: true
  1820. })]
  1821. });
  1822. expect(controller.getHostComponentsInfo().lastComponents).to.eql(['TaskTracker']);
  1823. App.HostComponent.find.restore();
  1824. });
  1825. it('content.hostComponents has master non-deletable component', function () {
  1826. sinon.stub(App.HostComponent, 'find', function () {
  1827. return [
  1828. {
  1829. id: 'TASKTRACKER_host1',
  1830. componentName: 'TASKTRACKER'
  1831. }
  1832. ];
  1833. });
  1834. controller.set('content', {
  1835. hostComponents: [Em.Object.create({
  1836. componentName: 'TASKTRACKER',
  1837. workStatus: 'INIT',
  1838. isDeletable: false,
  1839. isMaster: true,
  1840. displayName: 'ZK1'
  1841. })]
  1842. });
  1843. expect(controller.getHostComponentsInfo().masterComponents).to.eql(['ZK1']);
  1844. expect(controller.getHostComponentsInfo().nonDeletableComponents).to.eql(['ZK1']);
  1845. App.HostComponent.find.restore();
  1846. });
  1847. it('content.hostComponents has running component', function () {
  1848. sinon.stub(App.HostComponent, 'find', function () {
  1849. return [
  1850. {
  1851. id: 'TASKTRACKER_host1',
  1852. componentName: 'TASKTRACKER'
  1853. }
  1854. ];
  1855. });
  1856. controller.set('content', {
  1857. hostComponents: [Em.Object.create({
  1858. componentName: 'TASKTRACKER',
  1859. workStatus: 'STARTED',
  1860. isDeletable: true,
  1861. displayName: 'ZK1'
  1862. })]
  1863. });
  1864. expect(controller.getHostComponentsInfo().runningComponents).to.eql(['ZK1']);
  1865. App.HostComponent.find.restore();
  1866. });
  1867. it('content.hostComponents has non-deletable component', function () {
  1868. sinon.stub(App.HostComponent, 'find', function () {
  1869. return [
  1870. {
  1871. id: 'TASKTRACKER_host1',
  1872. componentName: 'TASKTRACKER'
  1873. }
  1874. ];
  1875. });
  1876. controller.set('content', {
  1877. hostComponents: [Em.Object.create({
  1878. componentName: 'TASKTRACKER',
  1879. workStatus: 'INIT',
  1880. isDeletable: false,
  1881. displayName: 'ZK1'
  1882. })]
  1883. });
  1884. expect(controller.getHostComponentsInfo().nonDeletableComponents).to.eql(['ZK1']);
  1885. App.HostComponent.find.restore();
  1886. });
  1887. it('content.hostComponents has component with UNKNOWN state', function () {
  1888. sinon.stub(App.HostComponent, 'find', function () {
  1889. return [
  1890. {
  1891. id: 'TASKTRACKER_host1',
  1892. componentName: 'TASKTRACKER'
  1893. }
  1894. ];
  1895. });
  1896. controller.set('content', {
  1897. hostComponents: [Em.Object.create({
  1898. componentName: 'TASKTRACKER',
  1899. workStatus: 'UNKNOWN',
  1900. isDeletable: false,
  1901. displayName: 'ZK1'
  1902. })]
  1903. });
  1904. expect(controller.getHostComponentsInfo().unknownComponents).to.eql(['ZK1']);
  1905. App.HostComponent.find.restore();
  1906. });
  1907. });
  1908. describe('#validateAndDeleteHost()', function () {
  1909. beforeEach(function () {
  1910. sinon.spy(App, "showConfirmationPopup");
  1911. sinon.stub(controller, "getHostComponentsInfo", function () {
  1912. return this.get('mockHostComponentsInfo');
  1913. });
  1914. sinon.stub(controller, "raiseDeleteComponentsError", Em.K);
  1915. sinon.stub(controller, "confirmDeleteHost", Em.K);
  1916. });
  1917. afterEach(function () {
  1918. App.showConfirmationPopup.restore();
  1919. controller.getHostComponentsInfo.restore();
  1920. controller.raiseDeleteComponentsError.restore();
  1921. controller.confirmDeleteHost.restore();
  1922. });
  1923. it('masterComponents exist', function () {
  1924. controller.set('mockHostComponentsInfo', {
  1925. masterComponents: [
  1926. {}
  1927. ]
  1928. });
  1929. controller.validateAndDeleteHost();
  1930. expect(controller.raiseDeleteComponentsError.calledWith({masterComponents: [
  1931. {}
  1932. ]}, 'masterList')).to.be.true;
  1933. });
  1934. it('nonDeletableComponents exist', function () {
  1935. controller.set('mockHostComponentsInfo', {
  1936. masterComponents: [],
  1937. nonDeletableComponents: [
  1938. {}
  1939. ]
  1940. });
  1941. controller.validateAndDeleteHost();
  1942. expect(controller.raiseDeleteComponentsError.calledWith({
  1943. masterComponents: [],
  1944. nonDeletableComponents: [
  1945. {}
  1946. ]
  1947. }, 'nonDeletableList')).to.be.true;
  1948. });
  1949. it('runningComponents exist', function () {
  1950. controller.set('mockHostComponentsInfo', {
  1951. masterComponents: [],
  1952. nonDeletableComponents: [],
  1953. runningComponents: [{}]
  1954. });
  1955. controller.validateAndDeleteHost();
  1956. expect(controller.raiseDeleteComponentsError.calledWith({
  1957. masterComponents: [],
  1958. nonDeletableComponents: [],
  1959. runningComponents: [{}]
  1960. }, 'runningList')).to.be.true;
  1961. });
  1962. it('zkServerInstalled = true', function () {
  1963. controller.set('mockHostComponentsInfo', {
  1964. masterComponents: [],
  1965. nonDeletableComponents: [],
  1966. runningComponents: [],
  1967. unknownComponents: [],
  1968. lastComponents: [],
  1969. zkServerInstalled: true
  1970. });
  1971. var popup = controller.validateAndDeleteHost();
  1972. expect(App.showConfirmationPopup.calledOnce).to.be.true;
  1973. popup.onPrimary();
  1974. expect(controller.confirmDeleteHost.calledWith({
  1975. masterComponents: [],
  1976. nonDeletableComponents: [],
  1977. runningComponents: [],
  1978. unknownComponents: [],
  1979. lastComponents: [],
  1980. zkServerInstalled: true
  1981. })).to.be.true;
  1982. });
  1983. it('zkServerInstalled = false', function () {
  1984. controller.set('mockHostComponentsInfo', {
  1985. masterComponents: [],
  1986. nonDeletableComponents: [],
  1987. runningComponents: [],
  1988. unknownComponents: [],
  1989. lastComponents: [],
  1990. zkServerInstalled: false
  1991. });
  1992. controller.validateAndDeleteHost();
  1993. expect(controller.confirmDeleteHost.calledWith({
  1994. masterComponents: [],
  1995. nonDeletableComponents: [],
  1996. runningComponents: [],
  1997. unknownComponents: [],
  1998. lastComponents: [],
  1999. zkServerInstalled: false
  2000. })).to.be.true;
  2001. });
  2002. });
  2003. describe('#raiseDeleteComponentsError()', function () {
  2004. beforeEach(function () {
  2005. sinon.stub(App.ModalPopup, "show", Em.K);
  2006. });
  2007. afterEach(function () {
  2008. App.ModalPopup.show.restore();
  2009. });
  2010. it('Popup should be displayed', function () {
  2011. controller.raiseDeleteComponentsError([], '');
  2012. expect(App.ModalPopup.show.calledOnce).to.be.true;
  2013. });
  2014. });
  2015. describe('#confirmDeleteHost()', function () {
  2016. it('Popup should be displayed', function () {
  2017. sinon.spy(App.ModalPopup, "show");
  2018. sinon.stub(controller, 'doDeleteHost');
  2019. var popup = controller.confirmDeleteHost({toDecommissionComponents:[]});
  2020. expect(App.ModalPopup.show.calledOnce).to.be.true;
  2021. popup.onPrimary();
  2022. expect(controller.doDeleteHost.calledOnce).to.be.true;
  2023. App.ModalPopup.show.restore();
  2024. controller.doDeleteHost.restore();
  2025. });
  2026. });
  2027. describe('#setRackId', function () {
  2028. beforeEach(function () {
  2029. sinon.stub(hostsManagement, 'setRackInfo', Em.K);
  2030. });
  2031. afterEach(function () {
  2032. hostsManagement.setRackInfo.restore();
  2033. });
  2034. it('should call setRackInfo with appropriate arguments', function () {
  2035. var mockedHost = Em.Object.create({
  2036. rack: 'rackId'
  2037. });
  2038. controller.setRackId({
  2039. context: mockedHost
  2040. });
  2041. expect(hostsManagement.setRackInfo.calledWith({message: Em.I18n.t('hosts.host.details.setRackId')}, [mockedHost], 'rackId')).to.be.true;
  2042. });
  2043. });
  2044. describe('#restartAllStaleConfigComponents()', function () {
  2045. beforeEach(function () {
  2046. sinon.spy(App, "showConfirmationPopup");
  2047. sinon.stub(batchUtils, "restartHostComponents", Em.K);
  2048. sinon.stub(controller, 'checkNnLastCheckpointTime', function(callback){
  2049. callback();
  2050. });
  2051. });
  2052. afterEach(function () {
  2053. App.showConfirmationPopup.restore();
  2054. batchUtils.restartHostComponents.restore();
  2055. controller.checkNnLastCheckpointTime.restore();
  2056. });
  2057. it('popup should be displayed', function () {
  2058. controller.set('content', {
  2059. componentsWithStaleConfigs: [
  2060. {}
  2061. ]
  2062. });
  2063. var popup = controller.restartAllStaleConfigComponents();
  2064. expect(App.showConfirmationPopup.calledOnce).to.be.true;
  2065. popup.onPrimary();
  2066. expect(batchUtils.restartHostComponents.calledWith([
  2067. {}
  2068. ])).to.be.true;
  2069. });
  2070. it('popup ro check NameNode checkpoint should be displayed first', function () {
  2071. controller.set('content.componentsWithStaleConfigs', [Em.Object.create({
  2072. componentName: 'NAMENODE',
  2073. workStatus: 'STARTED'
  2074. })]);
  2075. controller.set('content.hostComponents', [Em.Object.create({
  2076. componentName: 'NAMENODE',
  2077. workStatus: 'STARTED'
  2078. })]);
  2079. controller.restartAllStaleConfigComponents();
  2080. expect(controller.checkNnLastCheckpointTime.calledOnce).to.be.true;
  2081. expect(App.showConfirmationPopup.calledOnce).to.be.true;
  2082. });
  2083. });
  2084. describe.skip('#moveComponent()', function () {
  2085. var jQueryMock,
  2086. mock = {
  2087. saveComponentToReassign: Em.K,
  2088. getSecurityStatus: Em.K,
  2089. setCurrentStep: Em.K
  2090. },
  2091. cases = [
  2092. {
  2093. isDisabled: false,
  2094. showConfirmationPopupCallCount: 1,
  2095. title: 'popup should be displayed'
  2096. },
  2097. {
  2098. isDisabled: true,
  2099. showConfirmationPopupCallCount: 0,
  2100. title: 'popup shouldn\'t be displayed'
  2101. }
  2102. ];
  2103. beforeEach(function () {
  2104. jQueryMock = sinon.stub(window, '$');
  2105. sinon.spy(App, "showConfirmationPopup");
  2106. sinon.stub(App.router, 'get').withArgs('reassignMasterController').returns(mock);
  2107. sinon.stub(App.router, 'transitionTo', Em.K);
  2108. sinon.spy(mock, "saveComponentToReassign");
  2109. sinon.spy(mock, "getSecurityStatus");
  2110. sinon.spy(mock, "setCurrentStep");
  2111. });
  2112. afterEach(function () {
  2113. window.$.restore();
  2114. App.showConfirmationPopup.restore();
  2115. App.router.get.restore();
  2116. App.router.transitionTo.restore();
  2117. mock.saveComponentToReassign.restore();
  2118. mock.getSecurityStatus.restore();
  2119. mock.setCurrentStep.restore();
  2120. });
  2121. cases.forEach(function (item) {
  2122. it(item.title, function () {
  2123. jQueryMock.returns({
  2124. closest: function () {
  2125. return {
  2126. hasClass: function () {
  2127. return item.isDisabled;
  2128. }
  2129. }
  2130. }
  2131. });
  2132. var popup = controller.moveComponent({context: {}});
  2133. expect(App.showConfirmationPopup.callCount).to.equal(item.showConfirmationPopupCallCount);
  2134. if (item.showConfirmationPopupCallCount) {
  2135. popup.onPrimary();
  2136. expect(App.router.get.calledWith('reassignMasterController')).to.be.true;
  2137. expect(mock.saveComponentToReassign.calledWith({})).to.be.true;
  2138. expect(mock.getSecurityStatus.calledOnce).to.be.true;
  2139. expect(mock.setCurrentStep.calledWith('1')).to.be.true;
  2140. expect(App.router.transitionTo.calledWith('reassign')).to.be.true;
  2141. }
  2142. });
  2143. });
  2144. });
  2145. describe('#refreshConfigs()', function () {
  2146. beforeEach(function () {
  2147. sinon.spy(App, "showConfirmationPopup");
  2148. sinon.stub(batchUtils, "restartHostComponents", Em.K);
  2149. });
  2150. afterEach(function () {
  2151. App.showConfirmationPopup.restore();
  2152. batchUtils.restartHostComponents.restore();
  2153. });
  2154. it('No components', function () {
  2155. var event = {context: Em.A([])};
  2156. controller.refreshConfigs(event);
  2157. expect(App.showConfirmationPopup.called).to.be.false;
  2158. });
  2159. it('Some components present', function () {
  2160. var event = {context: Em.A([Em.Object.create()])};
  2161. var popup = controller.refreshConfigs(event);
  2162. expect(App.showConfirmationPopup.calledOnce).to.be.true;
  2163. popup.onPrimary();
  2164. expect(batchUtils.restartHostComponents.calledWith(event.context)).to.be.true;
  2165. });
  2166. });
  2167. describe('#getTotalComponent()', function () {
  2168. beforeEach(function () {
  2169. sinon.stub(App.SlaveComponent, 'find', function () {
  2170. return Em.Object.create({
  2171. componentName: "SLAVE",
  2172. totalCount: 1
  2173. });
  2174. });
  2175. sinon.stub(App.ClientComponent, 'find', function () {
  2176. return Em.Object.create({
  2177. componentName: "CLIENT",
  2178. totalCount: 1
  2179. });
  2180. });
  2181. sinon.stub(App.HostComponent, 'find', function () {
  2182. return [Em.Object.create({
  2183. componentName: "MASTER",
  2184. totalCount: 1
  2185. })]
  2186. });
  2187. });
  2188. afterEach(function () {
  2189. App.SlaveComponent.find.restore();
  2190. App.ClientComponent.find.restore();
  2191. App.HostComponent.find.restore();
  2192. });
  2193. it('component is slave', function () {
  2194. expect(controller.getTotalComponent(Em.Object.create({
  2195. componentName: "SLAVE",
  2196. isSlave: true
  2197. }))).to.equal(1);
  2198. });
  2199. it('component is client', function () {
  2200. expect(controller.getTotalComponent(Em.Object.create({
  2201. componentName: "CLIENT",
  2202. isClient: true
  2203. }))).to.equal(1);
  2204. });
  2205. it('component is master', function () {
  2206. expect(controller.getTotalComponent(Em.Object.create({
  2207. componentName: "MASTER"
  2208. }))).to.equal(1);
  2209. });
  2210. it('unknown component', function () {
  2211. expect(controller.getTotalComponent(Em.Object.create({
  2212. componentName: "UNKNOWN"
  2213. }))).to.equal(0);
  2214. });
  2215. });
  2216. describe('#downloadClientConfigsCall', function () {
  2217. beforeEach(function () {
  2218. sinon.stub(controller, 'downloadClientConfigsCall', Em.K);
  2219. });
  2220. afterEach(function () {
  2221. controller.downloadClientConfigsCall.restore();
  2222. });
  2223. it('should launch controller.downloadClientConfigsCall method', function () {
  2224. controller.downloadClientConfigs({
  2225. context: Em.Object.create({
  2226. componentName: 'name',
  2227. hostName: 'host1',
  2228. displayName: 'dName'
  2229. })
  2230. });
  2231. expect(controller.downloadClientConfigsCall.calledWith({
  2232. componentName: 'name',
  2233. hostName: 'host1',
  2234. displayName: 'dName'
  2235. })).to.be.true;
  2236. });
  2237. });
  2238. describe('#executeCustomCommands', function () {
  2239. beforeEach(function () {
  2240. sinon.spy(App, "showConfirmationPopup");
  2241. });
  2242. afterEach(function () {
  2243. App.showConfirmationPopup.restore();
  2244. });
  2245. it('confirm popup should be displayed', function () {
  2246. var popup = controller.executeCustomCommand({context: Em.Object.create()});
  2247. expect(App.showConfirmationPopup.calledOnce).to.be.true;
  2248. popup.onPrimary();
  2249. expect(App.ajax.send.calledOnce).to.be.true;
  2250. });
  2251. });
  2252. describe('#_doDeleteHostComponent()', function () {
  2253. it('single component', function () {
  2254. controller.set('content.hostName', 'host1');
  2255. var component = Em.Object.create({componentName: 'COMP'});
  2256. controller._doDeleteHostComponent(component);
  2257. expect(App.ajax.send.getCall(0).args[0].name).to.be.equal('common.delete.host_component');
  2258. expect(App.ajax.send.getCall(0).args[0].data).to.be.eql({
  2259. componentName: 'COMP',
  2260. hostName: 'host1'
  2261. });
  2262. });
  2263. it('all components', function () {
  2264. controller.set('content.hostName', 'host1');
  2265. controller._doDeleteHostComponent(null);
  2266. expect(App.ajax.send.getCall(0).args[0].name).to.be.equal('common.delete.host');
  2267. expect(App.ajax.send.getCall(0).args[0].data).to.be.eql({
  2268. componentName: '',
  2269. hostName: 'host1'
  2270. });
  2271. });
  2272. });
  2273. describe('#_doDeleteHostComponentSuccessCallback()', function () {
  2274. beforeEach(function () {
  2275. sinon.stub(controller, 'removeHostComponentModel', Em.K);
  2276. sinon.stub(controller, 'isServiceMetricsLoaded', function (callback) {
  2277. callback();
  2278. });
  2279. sinon.stub(controller, 'loadConfigs', Em.K);
  2280. });
  2281. afterEach(function () {
  2282. controller.removeHostComponentModel.restore();
  2283. controller.isServiceMetricsLoaded.restore();
  2284. controller.loadConfigs.restore();
  2285. });
  2286. it('ZOOKEEPER_SERVER component', function () {
  2287. var data = {
  2288. componentName: 'ZOOKEEPER_SERVER'
  2289. };
  2290. controller._doDeleteHostComponentSuccessCallback({}, {}, data);
  2291. expect(controller.get('_deletedHostComponentResult')).to.be.null;
  2292. expect(controller.get('fromDeleteZkServer')).to.be.true;
  2293. expect(controller.loadConfigs.calledOnce).to.be.true;
  2294. });
  2295. it('Not ZOOKEEPER_SERVER component', function () {
  2296. var data = {
  2297. componentName: 'COMP'
  2298. };
  2299. controller.set('fromDeleteZkServer', false);
  2300. controller._doDeleteHostComponentSuccessCallback({}, {}, data);
  2301. expect(controller.get('_deletedHostComponentResult')).to.be.null;
  2302. expect(controller.get('fromDeleteZkServer')).to.be.false;
  2303. });
  2304. it('should call `removeHostComponentModel` with correct params', function () {
  2305. var data = {
  2306. componentName: 'COMPONENT',
  2307. hostName: 'h1'
  2308. };
  2309. controller._doDeleteHostComponentSuccessCallback({}, {}, data);
  2310. expect(controller.removeHostComponentModel.calledWith('COMPONENT', 'h1')).to.be.true;
  2311. });
  2312. it('HIVE_METASTORE component', function () {
  2313. var data = {
  2314. componentName: 'HIVE_METASTORE'
  2315. };
  2316. controller._doDeleteHostComponentSuccessCallback({}, {}, data);
  2317. expect(controller.get('_deletedHostComponentResult')).to.be.null;
  2318. expect(controller.get('deleteHiveMetaStore')).to.be.true;
  2319. expect(controller.loadConfigs.calledWith('loadHiveConfigs')).to.be.true;
  2320. });
  2321. it('NIMBUS component', function () {
  2322. var data = {
  2323. componentName: 'NIMBUS'
  2324. };
  2325. controller._doDeleteHostComponentSuccessCallback({}, {}, data);
  2326. expect(controller.get('_deletedHostComponentResult')).to.be.null;
  2327. expect(controller.get('deleteNimbusHost')).to.be.true;
  2328. expect(controller.loadConfigs.calledWith('loadStormConfigs')).to.be.true;
  2329. });
  2330. it('RANGER_KMS_SERVER component', function () {
  2331. var data = {
  2332. componentName: 'RANGER_KMS_SERVER'
  2333. };
  2334. controller._doDeleteHostComponentSuccessCallback({}, {}, data);
  2335. expect(controller.get('_deletedHostComponentResult')).to.be.null;
  2336. expect(controller.get('deleteRangerKMSServer')).to.be.true;
  2337. expect(controller.loadConfigs.calledWith('loadRangerConfigs')).to.be.true;
  2338. });
  2339. });
  2340. describe('#upgradeComponentSuccessCallback()', function () {
  2341. beforeEach(function () {
  2342. sinon.stub(controller, 'showBackgroundOperationsPopup', Em.K);
  2343. sinon.stub(controller, 'mimicWorkStatusChange', Em.K);
  2344. });
  2345. afterEach(function () {
  2346. controller.mimicWorkStatusChange.restore();
  2347. controller.showBackgroundOperationsPopup.restore();
  2348. });
  2349. it('testMode is true', function () {
  2350. App.set('testMode', true);
  2351. controller.upgradeComponentSuccessCallback({}, {}, {component: "COMP"});
  2352. expect(controller.mimicWorkStatusChange.calledWith("COMP", App.HostComponentStatus.starting, App.HostComponentStatus.started)).to.be.true;
  2353. expect(controller.showBackgroundOperationsPopup.calledOnce).to.be.true;
  2354. });
  2355. it('testMode is false', function () {
  2356. App.set('testMode', false);
  2357. controller.upgradeComponentSuccessCallback({}, {}, {component: "COMP"});
  2358. expect(controller.mimicWorkStatusChange.called).to.be.false;
  2359. expect(controller.showBackgroundOperationsPopup.calledOnce).to.be.true;
  2360. });
  2361. });
  2362. describe('#refreshComponentConfigsSuccessCallback()', function () {
  2363. it('call showBackgroundOperationsPopup', function () {
  2364. sinon.stub(controller, 'showBackgroundOperationsPopup', Em.K);
  2365. controller.refreshComponentConfigsSuccessCallback();
  2366. expect(controller.showBackgroundOperationsPopup.calledOnce).to.be.true;
  2367. controller.showBackgroundOperationsPopup.restore();
  2368. });
  2369. });
  2370. describe('#checkZkConfigs()', function () {
  2371. beforeEach(function () {
  2372. sinon.stub(controller, 'removeObserver');
  2373. sinon.stub(controller, 'loadConfigs');
  2374. sinon.stub(controller, 'isServiceMetricsLoaded', function (callback) {
  2375. callback();
  2376. });
  2377. });
  2378. afterEach(function () {
  2379. controller.loadConfigs.restore();
  2380. controller.removeObserver.restore();
  2381. controller.isServiceMetricsLoaded.restore();
  2382. App.router.get.restore();
  2383. });
  2384. it('No operations of ZOOKEEPER_SERVER', function () {
  2385. sinon.stub(App.router, 'get').withArgs('backgroundOperationsController.services').returns([]);
  2386. controller.checkZkConfigs();
  2387. expect(controller.removeObserver.called).to.be.false;
  2388. expect(controller.loadConfigs.called).to.be.false;
  2389. });
  2390. it('Operation of ZOOKEEPER_SERVER running', function () {
  2391. sinon.stub(App.router, 'get').withArgs('backgroundOperationsController.services').returns([Em.Object.create({
  2392. id: 1,
  2393. isRunning: true
  2394. })]);
  2395. controller.set('zkRequestId', 1);
  2396. controller.checkZkConfigs();
  2397. expect(controller.removeObserver.called).to.be.false;
  2398. expect(controller.loadConfigs.called).to.be.false;
  2399. });
  2400. it('Operation of ZOOKEEPER_SERVER finished', function () {
  2401. sinon.stub(App.router, 'get').withArgs('backgroundOperationsController.services').returns([Em.Object.create({
  2402. id: 1
  2403. })]);
  2404. var clock = sinon.useFakeTimers();
  2405. controller.set('zkRequestId', 1);
  2406. controller.checkZkConfigs();
  2407. expect(controller.removeObserver.calledWith('App.router.backgroundOperationsController.serviceTimestamp', controller, controller.checkZkConfigs)).to.be.true;
  2408. clock.tick(App.get('componentsUpdateInterval'));
  2409. expect(controller.loadConfigs.calledOnce).to.be.true;
  2410. clock.restore();
  2411. });
  2412. });
  2413. describe('#_doDeleteHostComponentErrorCallback()', function () {
  2414. it('call showBackgroundOperationsPopup', function () {
  2415. controller._doDeleteHostComponentErrorCallback({}, 'textStatus', {}, {url: 'url'});
  2416. expect(controller.get('_deletedHostComponentResult')).to.be.eql({xhr: {}, url: 'url', method: 'DELETE'});
  2417. });
  2418. });
  2419. describe('#installComponentSuccessCallback()', function () {
  2420. beforeEach(function () {
  2421. sinon.stub(controller, 'showBackgroundOperationsPopup', Em.K);
  2422. sinon.stub(controller, 'mimicWorkStatusChange', Em.K);
  2423. });
  2424. afterEach(function () {
  2425. controller.mimicWorkStatusChange.restore();
  2426. controller.showBackgroundOperationsPopup.restore();
  2427. });
  2428. it('testMode is true', function () {
  2429. App.set('testMode', true);
  2430. controller.installComponentSuccessCallback({}, {}, {component: "COMP"});
  2431. expect(controller.mimicWorkStatusChange.calledWith("COMP", App.HostComponentStatus.installing, App.HostComponentStatus.stopped)).to.be.true;
  2432. expect(controller.showBackgroundOperationsPopup.calledOnce).to.be.true;
  2433. });
  2434. it('testMode is false', function () {
  2435. App.set('testMode', false);
  2436. controller.installComponentSuccessCallback({}, {}, {component: "COMP"});
  2437. expect(controller.mimicWorkStatusChange.called).to.be.false;
  2438. expect(controller.showBackgroundOperationsPopup.calledOnce).to.be.true;
  2439. });
  2440. });
  2441. describe('#showHbaseActiveWarning()', function () {
  2442. it('popup should be displayed', function () {
  2443. sinon.spy(App.ModalPopup, "show");
  2444. var popup = controller.showHbaseActiveWarning(Em.Object.create({service: {}}));
  2445. expect(App.ModalPopup.show.calledOnce).to.be.true;
  2446. App.ModalPopup.show.restore();
  2447. });
  2448. });
  2449. describe('#updateHost()', function () {
  2450. it('popup should be displayed', function () {
  2451. sinon.stub(batchUtils, "infoPassiveState", Em.K);
  2452. controller.updateHost({}, {}, {passive_state: 'state'});
  2453. expect(controller.get('content.passiveState')).to.equal('state');
  2454. expect(batchUtils.infoPassiveState.calledWith('state')).to.be.true;
  2455. batchUtils.infoPassiveState.restore();
  2456. });
  2457. });
  2458. describe('#updateComponentPassiveState()', function () {
  2459. it('popup should be displayed', function () {
  2460. controller.set('content.hostName', 'host1');
  2461. var component = Em.Object.create({
  2462. componentName: 'COMP1'
  2463. });
  2464. controller.updateComponentPassiveState(component, 'state', 'message');
  2465. expect(App.ajax.send.getCall(0).args[0].data).to.be.eql({
  2466. "hostName": "host1",
  2467. "componentName": "COMP1",
  2468. "component": component,
  2469. "passive_state": "state",
  2470. "context": "message"
  2471. });
  2472. });
  2473. });
  2474. describe('#updateHostComponent()', function () {
  2475. it('popup should be displayed', function () {
  2476. sinon.stub(batchUtils, "infoPassiveState", Em.K);
  2477. var params = {
  2478. component: Em.Object.create(),
  2479. passive_state: 'state'
  2480. };
  2481. controller.updateHostComponent({}, {}, params);
  2482. expect(params.component.get('passiveState')).to.equal('state');
  2483. expect(batchUtils.infoPassiveState.calledWith('state')).to.be.true;
  2484. batchUtils.infoPassiveState.restore();
  2485. });
  2486. });
  2487. describe('#toggleMaintenanceMode()', function () {
  2488. beforeEach(function () {
  2489. sinon.spy(App, "showConfirmationPopup");
  2490. sinon.stub(controller, 'updateComponentPassiveState');
  2491. });
  2492. afterEach(function () {
  2493. App.showConfirmationPopup.restore();
  2494. controller.updateComponentPassiveState.restore();
  2495. });
  2496. it('passive state is ON', function () {
  2497. var event = {
  2498. context: Em.Object.create({
  2499. passiveState: 'ON'
  2500. })
  2501. };
  2502. var popup = controller.toggleMaintenanceMode(event);
  2503. expect(App.showConfirmationPopup.calledOnce).to.be.true;
  2504. popup.onPrimary();
  2505. expect(controller.updateComponentPassiveState.calledWith(Em.Object.create({
  2506. passiveState: 'ON'
  2507. }), 'OFF')).to.be.true;
  2508. });
  2509. it('passive state is OFF', function () {
  2510. var event = {
  2511. context: Em.Object.create({
  2512. passiveState: 'OFF'
  2513. })
  2514. };
  2515. var popup = controller.toggleMaintenanceMode(event);
  2516. expect(App.showConfirmationPopup.calledOnce).to.be.true;
  2517. popup.onPrimary();
  2518. expect(controller.updateComponentPassiveState.calledWith(Em.Object.create({
  2519. passiveState: 'OFF'
  2520. }), 'ON')).to.be.true;
  2521. });
  2522. });
  2523. describe('#installClients()', function () {
  2524. var cases = [
  2525. {
  2526. context: [
  2527. Em.Object.create({
  2528. componentName: 'c0',
  2529. workStatus: 'INSTALLED'
  2530. }),
  2531. Em.Object.create({
  2532. componentName: 'c1',
  2533. workStatus: 'INIT'
  2534. }),
  2535. Em.Object.create({
  2536. componentName: 'c2',
  2537. workStatus: 'INSTALL_FAILED'
  2538. })
  2539. ],
  2540. dependencies: {
  2541. c0: [],
  2542. c1: [],
  2543. c2: []
  2544. },
  2545. getSecurityTypeCalled: null, //should have same value as getKDCSessionStateCalled, always
  2546. getKDCSessionStateCalled: true,
  2547. sendComponentCommandCalled: true,
  2548. showAlertPopupCalled: false,
  2549. title: 'No clients to add, some clients to install'
  2550. },
  2551. {
  2552. context: [
  2553. Em.Object.create({
  2554. componentName: 'c3',
  2555. displayName: 'c3'
  2556. })
  2557. ],
  2558. dependencies: {
  2559. c3: []
  2560. },
  2561. getSecurityTypeCalled: null, //should have same value as getKDCSessionStateCalled, always
  2562. getKDCSessionStateCalled: true,
  2563. sendComponentCommandCalled: false,
  2564. showAlertPopupCalled: false,
  2565. title: 'No clients to install, some clients to add'
  2566. },
  2567. {
  2568. context: [
  2569. Em.Object.create({
  2570. componentName: 'c4',
  2571. displayName: 'c4'
  2572. })
  2573. ],
  2574. dependencies: {
  2575. c4: ['c5']
  2576. },
  2577. getSecurityTypeCalled: null, //should have same value as getKDCSessionStateCalled, always
  2578. getKDCSessionStateCalled: false,
  2579. sendComponentCommandCalled: false,
  2580. showAlertPopupCalled: true,
  2581. title: 'Clients to add have unresolved dependencies'
  2582. },
  2583. {
  2584. context: [
  2585. Em.Object.create({
  2586. componentName: 'c5',
  2587. displayName: 'c5'
  2588. }),
  2589. Em.Object.create({
  2590. componentName: 'c6',
  2591. displayName: 'c6'
  2592. })
  2593. ],
  2594. dependencies: {
  2595. c5: ['c6'],
  2596. c6: ['c5']
  2597. },
  2598. getSecurityTypeCalled: null, //should have same value as getKDCSessionStateCalled, always
  2599. getKDCSessionStateCalled: true,
  2600. sendComponentCommandCalled: false,
  2601. showAlertPopupCalled: false,
  2602. title: 'Clients to add have mutual dependencies'
  2603. }
  2604. ];
  2605. beforeEach(function () {
  2606. sinon.stub(controller, 'sendComponentCommand', Em.K);
  2607. sinon.stub(controller, 'showAddComponentPopup', Em.K);
  2608. sinon.stub(App.get('router.mainAdminKerberosController'), 'getKDCSessionState', function (arg) {
  2609. return arg();
  2610. });
  2611. sinon.stub(App.get('router.mainAdminKerberosController'), 'getSecurityType', function (arg) {
  2612. return arg();
  2613. });
  2614. sinon.stub(App, 'showAlertPopup', Em.K);
  2615. sinon.stub(App.StackServiceComponent, 'find', function (componentName) {
  2616. return Em.Object.create({
  2617. displayName: componentName
  2618. });
  2619. });
  2620. controller.set('content.hostComponents', []);
  2621. });
  2622. afterEach(function () {
  2623. controller.sendComponentCommand.restore();
  2624. controller.showAddComponentPopup.restore();
  2625. App.get('router.mainAdminKerberosController').getKDCSessionState.restore();
  2626. App.get('router.mainAdminKerberosController').getSecurityType.restore();
  2627. App.showAlertPopup.restore();
  2628. App.StackServiceComponent.find.restore();
  2629. controller.checkComponentDependencies.restore();
  2630. });
  2631. cases.forEach(function (item) {
  2632. it(item.title, function () {
  2633. sinon.stub(controller, 'checkComponentDependencies', function (componentName, params) {
  2634. return item.dependencies[componentName];
  2635. });
  2636. controller.installClients({
  2637. context: item.context
  2638. });
  2639. expect(App.get('router.mainAdminKerberosController').getSecurityType.calledOnce).to.equal(item.getKDCSessionStateCalled);
  2640. expect(App.get('router.mainAdminKerberosController').getKDCSessionState.calledOnce).to.equal(item.getKDCSessionStateCalled);
  2641. expect(controller.sendComponentCommand.calledOnce).to.equal(item.sendComponentCommandCalled);
  2642. expect(App.showAlertPopup.calledOnce).to.equal(item.showAlertPopupCalled);
  2643. });
  2644. });
  2645. });
  2646. describe("#executeCustomCommandSuccessCallback()", function () {
  2647. it("BO popup should be shown", function () {
  2648. var mock = {
  2649. showPopup: Em.K
  2650. };
  2651. sinon.stub(App.router, 'get').returns(mock);
  2652. sinon.spy(mock, 'showPopup');
  2653. var data = {
  2654. Requests: {
  2655. id: 1
  2656. }
  2657. };
  2658. controller.executeCustomCommandSuccessCallback(data, {}, {});
  2659. expect(App.router.get.calledWith('backgroundOperationsController')).to.be.true;
  2660. expect(mock.showPopup.calledOnce).to.be.true;
  2661. App.router.get.restore();
  2662. mock.showPopup.restore();
  2663. });
  2664. });
  2665. describe("#executeCustomCommandErrorCallback()", function () {
  2666. beforeEach(function () {
  2667. sinon.stub($, 'parseJSON');
  2668. sinon.spy(App, 'showAlertPopup');
  2669. });
  2670. afterEach(function () {
  2671. App.showAlertPopup.restore();
  2672. $.parseJSON.restore();
  2673. });
  2674. it("data empty", function () {
  2675. controller.executeCustomCommandErrorCallback(null);
  2676. expect(App.showAlertPopup.calledWith(Em.I18n.t('services.service.actions.run.executeCustomCommand.error'), Em.I18n.t('services.service.actions.run.executeCustomCommand.error'))).to.be.true;
  2677. expect($.parseJSON.called).to.be.false;
  2678. });
  2679. it("responseText empty", function () {
  2680. var data = {
  2681. responseText: null
  2682. };
  2683. controller.executeCustomCommandErrorCallback(data);
  2684. expect(App.showAlertPopup.calledWith(Em.I18n.t('services.service.actions.run.executeCustomCommand.error'), Em.I18n.t('services.service.actions.run.executeCustomCommand.error'))).to.be.true;
  2685. expect($.parseJSON.called).to.be.false;
  2686. });
  2687. it("data empty", function () {
  2688. var data = {
  2689. responseText: "test"
  2690. };
  2691. controller.executeCustomCommandErrorCallback(data);
  2692. expect(App.showAlertPopup.calledWith(Em.I18n.t('services.service.actions.run.executeCustomCommand.error'), Em.I18n.t('services.service.actions.run.executeCustomCommand.error'))).to.be.true;
  2693. expect($.parseJSON.calledWith('test')).to.be.true;
  2694. });
  2695. });
  2696. describe("#doDeleteHost()", function () {
  2697. beforeEach(function () {
  2698. controller.set('fromDeleteHost', false);
  2699. controller.set('content.hostName', 'host1');
  2700. sinon.stub(controller, '_doDeleteHostComponent', function (comp, callback) {
  2701. callback();
  2702. });
  2703. });
  2704. afterEach(function () {
  2705. controller._doDeleteHostComponent.restore();
  2706. });
  2707. it("Host has no components", function () {
  2708. controller.set('content.hostComponents', Em.A([]));
  2709. controller.doDeleteHost(Em.K);
  2710. expect(controller.get('fromDeleteHost')).to.be.true;
  2711. expect(App.ajax.send.getCall(0).args[0].data.hostName).to.be.equal('host1');
  2712. expect(App.ajax.send.getCall(0).args[0].name).to.be.equal('common.delete.host');
  2713. });
  2714. it("Host has components", function () {
  2715. controller.set('content.hostComponents', Em.A([Em.Object.create({
  2716. componentName: 'COMP1'
  2717. })]));
  2718. controller.doDeleteHost(Em.K);
  2719. expect(controller._doDeleteHostComponent.calledWith(Em.Object.create({
  2720. componentName: 'COMP1'
  2721. }))).to.be.true;
  2722. expect(controller.get('fromDeleteHost')).to.be.true;
  2723. expect(App.ajax.send.getCall(0).args[0].data.hostName).to.be.equal('host1');
  2724. expect(App.ajax.send.getCall(0).args[0].name).to.be.equal('common.delete.host');
  2725. });
  2726. });
  2727. describe("#deleteHostSuccessCallback", function () {
  2728. it("call updateHost", function () {
  2729. var mock = {
  2730. updateHost: function (callback) {
  2731. callback();
  2732. },
  2733. getAllHostNames: Em.K
  2734. };
  2735. sinon.stub(App.router, 'get').withArgs('updateController').returns(mock).withArgs('clusterController').returns(mock);
  2736. sinon.spy(mock, 'updateHost');
  2737. sinon.spy(mock, 'getAllHostNames');
  2738. sinon.stub(controller, 'loadConfigs', Em.K);
  2739. sinon.stub(App.router, 'transitionTo', Em.K);
  2740. sinon.stub(controller, 'isServiceMetricsLoaded', function (callback) {
  2741. callback();
  2742. });
  2743. controller.deleteHostSuccessCallback();
  2744. expect(App.router.get.calledWith('updateController')).to.be.true;
  2745. expect(mock.updateHost.calledOnce).to.be.true;
  2746. expect(controller.loadConfigs.called).to.be.false;
  2747. expect(App.router.transitionTo.calledWith('hosts.index')).to.be.true;
  2748. expect(App.router.get.calledWith('clusterController')).to.be.true;
  2749. expect(mock.getAllHostNames.calledOnce).to.be.true;
  2750. App.router.get.restore();
  2751. mock.updateHost.restore();
  2752. mock.getAllHostNames.restore();
  2753. controller.loadConfigs.restore();
  2754. controller.isServiceMetricsLoaded.restore();
  2755. App.router.transitionTo.restore();
  2756. });
  2757. });
  2758. describe("#deleteHostErrorCallback", function () {
  2759. it("call defaultErrorHandler", function () {
  2760. sinon.stub(controller, 'loadConfigs', Em.K);
  2761. sinon.stub(App.ajax, 'defaultErrorHandler', Em.K);
  2762. sinon.stub(controller, 'isServiceMetricsLoaded', function (callback) {
  2763. callback();
  2764. });
  2765. controller.deleteHostErrorCallback({
  2766. status: 'status',
  2767. statusText: "statusText"
  2768. }, 'textStatus', 'errorThrown', {url: 'url'});
  2769. expect(controller.loadConfigs.calledOnce).to.be.true;
  2770. expect(App.ajax.defaultErrorHandler.calledOnce).to.be.true;
  2771. App.ajax.defaultErrorHandler.restore();
  2772. controller.loadConfigs.restore();
  2773. controller.isServiceMetricsLoaded.restore();
  2774. });
  2775. });
  2776. describe('#installVersionConfirmation()', function () {
  2777. beforeEach(function () {
  2778. sinon.spy(App, "showConfirmationPopup");
  2779. sinon.stub(controller, 'installVersion', Em.K);
  2780. });
  2781. afterEach(function () {
  2782. App.showConfirmationPopup.restore();
  2783. controller.installVersion.restore();
  2784. });
  2785. it('confirm popup should be displayed', function () {
  2786. var event = {context: Em.Object.create({displayName: 'displayName'})};
  2787. var popup = controller.installVersionConfirmation(event);
  2788. expect(App.showConfirmationPopup.calledOnce).to.be.true;
  2789. popup.onPrimary();
  2790. expect(controller.installVersion.calledWith(event)).to.be.true;
  2791. });
  2792. });
  2793. describe("#installVersion()", function () {
  2794. it("call App.ajax.send", function () {
  2795. controller.set('content.hostName', 'host1');
  2796. controller.installVersion({context: {}});
  2797. expect(App.ajax.send.getCall(0).args[0]).to.eql({
  2798. name: 'host.stack_versions.install',
  2799. sender: controller,
  2800. data: {
  2801. hostName: 'host1',
  2802. version: {}
  2803. },
  2804. success: 'installVersionSuccessCallback'
  2805. });
  2806. });
  2807. });
  2808. describe("#installVersionSuccessCallback()", function () {
  2809. var version = Em.Object.create({
  2810. id: 1,
  2811. status: 'INIT'
  2812. });
  2813. beforeEach(function () {
  2814. this.mock = sinon.stub(App.HostStackVersion, 'find');
  2815. this.mock.returns(version);
  2816. sinon.stub(App.db, 'set', Em.K);
  2817. sinon.stub(App.clusterStatus, 'setClusterStatus', Em.K);
  2818. controller.installVersionSuccessCallback({Requests: {id: 1}}, {}, {version: version});
  2819. });
  2820. afterEach(function () {
  2821. this.mock.restore();
  2822. App.db.set.restore();
  2823. App.clusterStatus.setClusterStatus.restore();
  2824. });
  2825. it("status is INSTALLING", function () {
  2826. expect(version.get('status')).to.equal('INSTALLING');
  2827. });
  2828. it('valid data is saved to the localDB', function () {
  2829. expect(App.db.set.calledWith('repoVersionInstall', 'id', [1])).to.be.true;
  2830. });
  2831. it('clusterStatus is updated', function () {
  2832. expect(App.clusterStatus.setClusterStatus.calledOnce).to.be.true;
  2833. });
  2834. });
  2835. describe('#getHiveHosts()', function () {
  2836. var cases = [
  2837. {
  2838. 'input': {
  2839. 'hiveMetastoreHost': '',
  2840. 'fromDeleteHost': false,
  2841. 'deleteHiveMetaStore': false,
  2842. 'deleteWebHCatServer': false
  2843. },
  2844. 'hiveHosts': ['h1', 'h2', 'h4'],
  2845. 'title': 'adding HiveServer2'
  2846. },
  2847. {
  2848. 'input': {
  2849. 'hiveMetastoreHost': 'h0',
  2850. 'fromDeleteHost': false,
  2851. 'deleteHiveMetaStore': false,
  2852. 'deleteWebHCatServer': false
  2853. },
  2854. 'hiveHosts': ['h0', 'h1', 'h2', 'h4'],
  2855. 'title': 'adding Hive Metastore'
  2856. },
  2857. {
  2858. 'input': {
  2859. 'webhcatServerHost': 'h0',
  2860. 'fromDeleteHost': false,
  2861. 'deleteHiveMetaStore': false,
  2862. 'deleteWebHCatServer': false
  2863. },
  2864. 'hiveHosts': ['h0', 'h1', 'h2', 'h4'],
  2865. 'title': 'adding WebHCat Server'
  2866. },
  2867. {
  2868. 'input': {
  2869. 'hiveMetastoreHost': '',
  2870. 'content.hostName': 'h1',
  2871. 'fromDeleteHost': false,
  2872. 'deleteHiveMetaStore': true,
  2873. 'deleteWebHCatServer': false
  2874. },
  2875. 'hiveHosts': ['h2', 'h4'],
  2876. 'title': 'deleting Hive component'
  2877. },
  2878. {
  2879. 'input': {
  2880. 'hiveMetastoreHost': '',
  2881. 'content.hostName': 'h4',
  2882. 'fromDeleteHost': false,
  2883. 'deleteHiveMetaStore': false,
  2884. 'deleteWebHCatServer': true
  2885. },
  2886. 'hiveHosts': ['h1', 'h2'],
  2887. 'title': 'deleting WebHCat Server'
  2888. },
  2889. {
  2890. 'input': {
  2891. 'hiveMetastoreHost': '',
  2892. 'content.hostName': 'h2',
  2893. 'fromDeleteHost': true,
  2894. 'deleteHiveMetaStore': false,
  2895. 'deleteWebHCatServer': false
  2896. },
  2897. 'hiveHosts': ['h1', 'h4'],
  2898. 'title': 'deleting host with Hive component'
  2899. },
  2900. {
  2901. 'input': {
  2902. 'webhcatServerHost': '',
  2903. 'content.hostName': 'h2',
  2904. 'fromDeleteHost': true,
  2905. 'deleteHiveMetaStore': false,
  2906. 'deleteWebHCatServer': false
  2907. },
  2908. 'hiveHosts': ['h1', 'h4'],
  2909. 'title': 'deleting host with WebHCat Server'
  2910. }
  2911. ];
  2912. before(function () {
  2913. sinon.stub(App.HostComponent, 'find').returns([
  2914. {
  2915. componentName: 'HIVE_METASTORE',
  2916. hostName: 'h2'
  2917. },
  2918. {
  2919. componentName: 'HIVE_METASTORE',
  2920. hostName: 'h1'
  2921. },
  2922. {
  2923. componentName: 'HIVE_SERVER',
  2924. hostName: 'h3'
  2925. },
  2926. {
  2927. componentName: 'WEBHCAT_SERVER',
  2928. hostName: 'h4'
  2929. }
  2930. ]);
  2931. });
  2932. after(function () {
  2933. App.HostComponent.find.restore();
  2934. });
  2935. cases.forEach(function (item) {
  2936. it(item.title, function () {
  2937. Em.keys(item.input).forEach(function (key) {
  2938. controller.set(key, item.input[key]);
  2939. });
  2940. var hostsMap = controller.getHiveHosts().toArray();
  2941. var expectedHosts = hostsMap.filter(function(hostInfo) {
  2942. return ['WEBHCAT_SERVER', 'HIVE_METASTORE'].contains(hostInfo.component) && hostInfo.isInstalled === true;
  2943. }).mapProperty('hostName').uniq();
  2944. expect(expectedHosts).to.include.same.members(item.hiveHosts);
  2945. expect(controller.get('hiveMetastoreHost')).to.be.empty;
  2946. expect(controller.get('webhcatServerHost')).to.be.empty;
  2947. expect(controller.get('fromDeleteHost')).to.be.false;
  2948. expect(controller.get('deleteHiveMetaStore')).to.be.false;
  2949. });
  2950. });
  2951. });
  2952. describe('#onLoadRangerConfigs()', function () {
  2953. var cases = [
  2954. {
  2955. 'kmsHosts': ['host1'],
  2956. 'kmsPort': 'port',
  2957. 'title': 'single host',
  2958. 'hostToInstall': undefined,
  2959. 'result': [
  2960. {
  2961. properties: {
  2962. 'core-site': {'hadoop.security.key.provider.path': 'kms://http@host1:port/kms'},
  2963. 'hdfs-site': {'dfs.encryption.key.provider.uri': 'kms://http@host1:port/kms'}
  2964. },
  2965. properties_attributes: {
  2966. 'core-site': undefined,
  2967. 'hdfs-site': undefined
  2968. }
  2969. }
  2970. ]
  2971. },
  2972. {
  2973. 'kmsHosts': ['host1', 'host2'],
  2974. 'kmsPort': 'port',
  2975. 'title': 'two hosts',
  2976. 'hostToInstall': 'host2',
  2977. 'result': [
  2978. {
  2979. properties: {
  2980. 'core-site': {'hadoop.security.key.provider.path': 'kms://http@host1;host2:port/kms'},
  2981. 'hdfs-site': {'dfs.encryption.key.provider.uri': 'kms://http@host1;host2:port/kms'}
  2982. },
  2983. properties_attributes: {
  2984. 'core-site': undefined,
  2985. 'hdfs-site': undefined
  2986. }
  2987. }
  2988. ]
  2989. }
  2990. ];
  2991. beforeEach(function () {
  2992. sinon.spy(controller, 'saveConfigsBatch')
  2993. });
  2994. afterEach(function () {
  2995. controller.saveConfigsBatch.restore();
  2996. });
  2997. cases.forEach(function (item) {
  2998. it(item.title, function () {
  2999. controller.set('rangerKMSServerHost', item.hostToInstall);
  3000. sinon.stub(controller, 'getRangerKMSServerHosts').returns(item.kmsHosts);
  3001. var data = {
  3002. items: [
  3003. {
  3004. type: 'kms-env',
  3005. properties: {'kms_port': item.kmsPort}
  3006. },
  3007. {
  3008. type: 'core-site',
  3009. properties: {}
  3010. },
  3011. {
  3012. type: 'hdfs-site',
  3013. properties: {}
  3014. }
  3015. ]
  3016. };
  3017. controller.onLoadRangerConfigs(data);
  3018. expect(controller.saveConfigsBatch.calledWith(item.result, 'RANGER_KMS_SERVER', item.hostToInstall)).to.be.true;
  3019. });
  3020. });
  3021. });
  3022. describe("#removeHostComponentModel()", function () {
  3023. beforeEach(function () {
  3024. App.cache['services'] = [
  3025. {
  3026. ServiceInfo: {
  3027. service_name: 'S1'
  3028. },
  3029. host_components: ['C1_host1']
  3030. }
  3031. ];
  3032. sinon.stub(App.HostComponent, 'find').returns([
  3033. Em.Object.create({
  3034. id: 'C1_host1',
  3035. componentName: 'C1',
  3036. hostName: 'host1',
  3037. service: Em.Object.create({
  3038. serviceName: 'S1'
  3039. })
  3040. })
  3041. ]);
  3042. sinon.stub(App.serviceMapper, 'deleteRecord', Em.K);
  3043. controller.removeHostComponentModel('C1', 'host1');
  3044. });
  3045. afterEach(function () {
  3046. App.HostComponent.find.restore();
  3047. App.serviceMapper.deleteRecord.restore();
  3048. });
  3049. it("App.cache is updated", function () {
  3050. expect(App.cache['services'][0].host_components).to.be.empty;
  3051. });
  3052. it('Record is deleted', function () {
  3053. expect(App.serviceMapper.deleteRecord.calledOnce).to.be.true;
  3054. });
  3055. });
  3056. describe("#updateStormConfigs()", function () {
  3057. beforeEach(function () {
  3058. this.serviceMock = sinon.stub(App.Service, 'find');
  3059. sinon.stub(controller, 'loadConfigs');
  3060. this.mock = sinon.stub(App, 'get')
  3061. });
  3062. afterEach(function () {
  3063. this.serviceMock.restore();
  3064. this.mock.restore();
  3065. controller.loadConfigs.restore();
  3066. });
  3067. it("storm not installed, hadoop stack is 2.2", function () {
  3068. this.serviceMock.returns(Em.Object.create({
  3069. isLoaded: false
  3070. }));
  3071. this.mock.returns(false);
  3072. controller.updateStormConfigs();
  3073. expect(controller.loadConfigs.called).to.be.false;
  3074. });
  3075. it("storm installed, hadoop stack is 2.2", function () {
  3076. this.serviceMock.returns(Em.Object.create({
  3077. isLoaded: true
  3078. }));
  3079. this.mock.returns(false);
  3080. controller.updateStormConfigs();
  3081. expect(controller.loadConfigs.called).to.be.false;
  3082. });
  3083. it("storm installed, hadoop stack is 2.3", function () {
  3084. this.serviceMock.returns(Em.Object.create({
  3085. isLoaded: true
  3086. }));
  3087. this.mock.returns(true);
  3088. controller.updateStormConfigs();
  3089. expect(controller.loadConfigs.calledWith('loadStormConfigs')).to.be.true;
  3090. });
  3091. });
  3092. describe("#parseNnCheckPointTime", function () {
  3093. var tests = [
  3094. {
  3095. m: "NameNode on this host has JMX data, the last checkpoint time is less than 12 hours ago",
  3096. data:
  3097. {
  3098. "href" : "",
  3099. "HostRoles" : {
  3100. "cluster_name" : "c123",
  3101. "component_name" : "NAMENODE",
  3102. "host_name" : "c6401.ambari.apache.org"
  3103. },
  3104. "metrics" : {
  3105. "dfs" : {
  3106. "FSNamesystem" : {
  3107. "HAState" : "active",
  3108. "LastCheckpointTime" : 1435775648000
  3109. }
  3110. }
  3111. }
  3112. },
  3113. result: false
  3114. },
  3115. {
  3116. m: "NameNode on this host has JMX data, the last checkpoint time is > 12 hours ago",
  3117. data:
  3118. {
  3119. "href" : "",
  3120. "HostRoles" : {
  3121. "cluster_name" : "c123",
  3122. "component_name" : "NAMENODE",
  3123. "host_name" : "c6401.ambari.apache.org"
  3124. },
  3125. "metrics" : {
  3126. "dfs" : {
  3127. "FSNamesystem" : {
  3128. "HAState" : "active",
  3129. "LastCheckpointTime" : 1435617248000
  3130. }
  3131. }
  3132. }
  3133. },
  3134. result: "c6401.ambari.apache.org"
  3135. },
  3136. {
  3137. m: "NameNode(standby) on this host has JMX data",
  3138. data:
  3139. {
  3140. "href" : "",
  3141. "HostRoles" : {
  3142. "cluster_name" : "c123",
  3143. "component_name" : "NAMENODE",
  3144. "host_name" : "c6401.ambari.apache.org"
  3145. },
  3146. "metrics" : {
  3147. "dfs" : {
  3148. "FSNamesystem" : {
  3149. "HAState" : "standby",
  3150. "LastCheckpointTime" : 1435617248000
  3151. }
  3152. }
  3153. }
  3154. },
  3155. result: false
  3156. },
  3157. {
  3158. m: "NameNode on this host has no JMX data",
  3159. data:
  3160. {
  3161. "href" : "",
  3162. "HostRoles" : {
  3163. "cluster_name" : "c123",
  3164. "component_name" : "NAMENODE",
  3165. "host_name" : "c6401.ambari.apache.org"
  3166. },
  3167. "metrics" : {
  3168. "dfs" : {
  3169. "FSNamesystem" : {
  3170. "HAState" : "active"
  3171. }
  3172. }
  3173. }
  3174. },
  3175. result: null
  3176. },
  3177. {
  3178. m: "NameNode on this host has no JMX data",
  3179. data:
  3180. {
  3181. "href" : "",
  3182. "HostRoles" : {
  3183. "cluster_name" : "c123",
  3184. "component_name" : "NAMENODE",
  3185. "host_name" : "c6401.ambari.apache.org"
  3186. },
  3187. "metrics" : {
  3188. }
  3189. },
  3190. result: null
  3191. }
  3192. ];
  3193. beforeEach(function () {
  3194. sinon.stub(App, 'dateTime').returns(1435790048000);
  3195. });
  3196. afterEach(function () {
  3197. App.dateTime.restore();
  3198. });
  3199. tests.forEach(function (test) {
  3200. it(test.m, function () {
  3201. var mainHostDetailsController = App.MainHostDetailsController.create({isNNCheckpointTooOld: null});
  3202. mainHostDetailsController.parseNnCheckPointTime(test.data);
  3203. expect(mainHostDetailsController.get('isNNCheckpointTooOld')).to.equal(test.result);
  3204. });
  3205. });
  3206. });
  3207. describe("#checkComponentDependencies()", function() {
  3208. beforeEach(function () {
  3209. this.mock = sinon.stub(App.StackServiceComponent, 'find');
  3210. sinon.stub(App.HostComponent, 'find').returns([{
  3211. hostName: 'host1',
  3212. componentName: 'C1'
  3213. }]);
  3214. });
  3215. afterEach(function () {
  3216. this.mock.restore();
  3217. App.HostComponent.find.restore();
  3218. });
  3219. it("no dependencies", function () {
  3220. var opt = {scope: '*'};
  3221. this.mock.returns(Em.Object.create({
  3222. dependencies: []
  3223. }));
  3224. expect(controller.checkComponentDependencies('C1', opt)).to.be.empty;
  3225. });
  3226. it("dependecies already installed", function () {
  3227. var opt = {scope: '*', installedComponents: ['C2']};
  3228. this.mock.returns(Em.Object.create({
  3229. dependencies: [{componentName: 'C2'}]
  3230. }));
  3231. expect(controller.checkComponentDependencies('C1', opt)).to.be.empty;
  3232. });
  3233. it("dependecies should be added", function () {
  3234. var opt = {scope: '*', installedComponents: ['C2']};
  3235. this.mock.returns(Em.Object.create({
  3236. dependencies: [{componentName: 'C3'}]
  3237. }));
  3238. expect(controller.checkComponentDependencies('C1', opt)).to.eql(['C3']);
  3239. });
  3240. it("scope is host", function () {
  3241. var opt = {scope: 'host', hostName: 'host1'};
  3242. this.mock.returns(Em.Object.create({
  3243. dependencies: [{componentName: 'C3', scope: 'host'}]
  3244. }));
  3245. expect(controller.checkComponentDependencies('C1', opt)).to.eql(['C3']);
  3246. });
  3247. });
  3248. describe('#onLoadHiveConfigs', function() {
  3249. beforeEach(function() {
  3250. sinon.stub(controller, 'saveConfigsBatch', Em.K);
  3251. });
  3252. afterEach(function() {
  3253. controller.saveConfigsBatch.restore();
  3254. });
  3255. var makeHostComponentModel = function(componentName, hostNames) {
  3256. if (Em.isArray(componentName)) {
  3257. return componentName.map(function(componentName, index) {
  3258. return makeHostComponentModel(componentName, hostNames[index]);
  3259. }).reduce(function(p,c) { return p.concat(c); }, []);
  3260. }
  3261. return hostNames.map(function(hostName) {
  3262. return {
  3263. componentName: componentName,
  3264. hostName: hostName
  3265. };
  3266. });
  3267. };
  3268. var makeFileNameProps = function(fileName, configs) {
  3269. var ret = {
  3270. type: fileName,
  3271. properties: {}
  3272. };
  3273. var propRet = {};
  3274. configs.forEach(function(property) {
  3275. propRet[property[0]] = property[1];
  3276. });
  3277. ret.properties = propRet;
  3278. return ret;
  3279. };
  3280. var makeEmptyPropAttrs = function() {
  3281. var fileNames = Array.prototype.slice.call(arguments);
  3282. var ret = {};
  3283. fileNames.forEach(function(fileName) {
  3284. ret[fileName] = {};
  3285. });
  3286. return ret;
  3287. };
  3288. var inlineComponentHostInfo = function(hostComponentModel) {
  3289. return hostComponentModel.mapProperty('componentName').uniq()
  3290. .map(function(componentName) {
  3291. return componentName + ":" + hostComponentModel.filterProperty('componentName', componentName).mapProperty('hostName').join();
  3292. }).join(',');
  3293. };
  3294. var tests = [
  3295. {
  3296. hostComponentModel: makeHostComponentModel(['HIVE_SERVER', 'HIVE_METASTORE'], [['host1', 'host2'], ['host1']]),
  3297. configs: {
  3298. items: [
  3299. makeFileNameProps('hive-site', [
  3300. ['hive.metastore.uris', 'thrift://host1:9090']
  3301. ]),
  3302. makeFileNameProps('hive-env', [
  3303. ['hive_user', 'hive_user_val'],
  3304. ['webhcat_user', 'webhcat_user_val']
  3305. ]),
  3306. makeFileNameProps('webhcat-site', [
  3307. ['templeton.hive.properties', 'hive.metastore.local=false,hive.metastore.uris=thrift://host1:9083,hive.metastore.sasl.enabled=false']
  3308. ]),
  3309. makeFileNameProps('core-site', [
  3310. ['hadoop.proxyuser.hive_user_val.hosts', 'host1'],
  3311. ['hadoop.proxyuser.webhcat_user_val.hosts', 'host1']
  3312. ])
  3313. ]
  3314. },
  3315. m: 'Components: {0}, appropriate configs should be changed, thrift port 9090, Controller stubs: {1}',
  3316. e: {
  3317. configs: [
  3318. {
  3319. "properties": {
  3320. "hive-site": makeFileNameProps('hive-site', [
  3321. ['hive.metastore.uris', 'thrift://host1:9090']
  3322. ]).properties,
  3323. "webhcat-site": makeFileNameProps('webhcat-site', [
  3324. ['templeton.hive.properties', 'hive.metastore.local=false,hive.metastore.uris=thrift://host1:9090,hive.metastore.sasl.enabled=false']
  3325. ]).properties,
  3326. "hive-env": makeFileNameProps('hive-env', [
  3327. ['hive_user', 'hive_user_val'],
  3328. ['webhcat_user', 'webhcat_user_val']
  3329. ]).properties
  3330. },
  3331. "properties_attributes": makeEmptyPropAttrs("hive-site", "webhcat-site", "hive-env")
  3332. },
  3333. {
  3334. "properties": {
  3335. "core-site": makeFileNameProps('core-site', [
  3336. ['hadoop.proxyuser.hive_user_val.hosts', 'host1,host2'],
  3337. ['hadoop.proxyuser.webhcat_user_val.hosts', 'host1,host2']
  3338. ]).properties
  3339. },
  3340. "properties_attributes": makeEmptyPropAttrs("core-site")
  3341. },
  3342. ]
  3343. }
  3344. },
  3345. {
  3346. hostComponentModel: makeHostComponentModel(['HIVE_SERVER', 'HIVE_METASTORE', 'WEBHCAT_SERVER'], [['host1', 'host2'], ['host1'], ['host2']]),
  3347. ctrlStubs: {
  3348. webhcatServerHost: 'host3'
  3349. },
  3350. configs: {
  3351. items: [
  3352. makeFileNameProps('hive-site', [
  3353. ['hive.metastore.uris', 'thrift://host1']
  3354. ]),
  3355. makeFileNameProps('hive-env', [
  3356. ['hive_user', 'hive_user_val'],
  3357. ['webhcat_user', 'webhcat_user_val']
  3358. ]),
  3359. makeFileNameProps('webhcat-site', [
  3360. ['templeton.hive.properties', 'hive.metastore.local=false,hive.metastore.uris=thrift://host1:9083,hive.metastore.sasl.enabled=false']
  3361. ]),
  3362. makeFileNameProps('core-site', [
  3363. ['hadoop.proxyuser.hive_user_val.hosts', 'host1'],
  3364. ['hadoop.proxyuser.webhcat_user_val.hosts', 'host1']
  3365. ])
  3366. ]
  3367. },
  3368. m: 'Components: {0}, appropriate configs should be changed, thrift port should be default 9083, Controller Stubs: {1}',
  3369. e: {
  3370. configs: [
  3371. {
  3372. "properties": {
  3373. "hive-site": makeFileNameProps('hive-site', [
  3374. ['hive.metastore.uris', 'thrift://host1:9083,thrift://host2:9083,thrift://host3:9083']
  3375. ]).properties,
  3376. "webhcat-site": makeFileNameProps('webhcat-site', [
  3377. ['templeton.hive.properties', 'hive.metastore.local=false,hive.metastore.uris=thrift://host1:9083\\,thrift://host2:9083\\,thrift://host3:9083,hive.metastore.sasl.enabled=false']
  3378. ]).properties,
  3379. "hive-env": makeFileNameProps('hive-env', [
  3380. ['hive_user', 'hive_user_val'],
  3381. ['webhcat_user', 'webhcat_user_val']
  3382. ]).properties
  3383. },
  3384. "properties_attributes": makeEmptyPropAttrs("hive-site", "webhcat-site", "hive-env")
  3385. },
  3386. {
  3387. "properties": {
  3388. "core-site": makeFileNameProps('core-site', [
  3389. ['hadoop.proxyuser.hive_user_val.hosts', 'host1,host2,host3'],
  3390. ['hadoop.proxyuser.webhcat_user_val.hosts', 'host1,host2,host3']
  3391. ]).properties
  3392. },
  3393. "properties_attributes": makeEmptyPropAttrs("core-site")
  3394. },
  3395. ]
  3396. }
  3397. },
  3398. {
  3399. hostComponentModel: makeHostComponentModel(['HIVE_SERVER', 'HIVE_METASTORE', 'WEBHCAT_SERVER'], [['host1'], ['host1'], ['host1']]),
  3400. ctrlStubs: {
  3401. webhcatServerHost: 'host3',
  3402. hiveMetastoreHost: 'host2'
  3403. },
  3404. configs: {
  3405. items: [
  3406. makeFileNameProps('hive-site', [
  3407. ['hive.metastore.uris', 'thrift://host1:1111']
  3408. ]),
  3409. makeFileNameProps('hive-env', [
  3410. ['hive_user', 'hive_user_val'],
  3411. ['webhcat_user', 'webhcat_user_val']
  3412. ]),
  3413. makeFileNameProps('webhcat-site', [
  3414. ['templeton.hive.properties', 'hive.metastore.local=false,hive.metastore.uris=thrift://host1:9083,hive.metastore.sasl.enabled=false']
  3415. ]),
  3416. makeFileNameProps('core-site', [
  3417. ['hadoop.proxyuser.hive_user_val.hosts', 'host1'],
  3418. ['hadoop.proxyuser.webhcat_user_val.hosts', 'host1']
  3419. ])
  3420. ]
  3421. },
  3422. m: 'Components: {0}, appropriate configs should be changed, thrift port should be 1111, Controller Stubs: {1}',
  3423. e: {
  3424. configs: [
  3425. {
  3426. "properties": {
  3427. "hive-site": makeFileNameProps('hive-site', [
  3428. ['hive.metastore.uris', 'thrift://host1:1111,thrift://host2:1111,thrift://host3:1111']
  3429. ]).properties,
  3430. "webhcat-site": makeFileNameProps('webhcat-site', [
  3431. ['templeton.hive.properties', 'hive.metastore.local=false,hive.metastore.uris=thrift://host1:1111\\,thrift://host2:1111\\,thrift://host3:1111,hive.metastore.sasl.enabled=false']
  3432. ]).properties,
  3433. "hive-env": makeFileNameProps('hive-env', [
  3434. ['hive_user', 'hive_user_val'],
  3435. ['webhcat_user', 'webhcat_user_val']
  3436. ]).properties
  3437. },
  3438. "properties_attributes": makeEmptyPropAttrs("hive-site", "webhcat-site", "hive-env")
  3439. },
  3440. {
  3441. "properties": {
  3442. "core-site": makeFileNameProps('core-site', [
  3443. ['hadoop.proxyuser.hive_user_val.hosts', 'host1,host2,host3'],
  3444. ['hadoop.proxyuser.webhcat_user_val.hosts', 'host1,host2,host3']
  3445. ]).properties
  3446. },
  3447. "properties_attributes": makeEmptyPropAttrs("core-site")
  3448. },
  3449. ]
  3450. }
  3451. },
  3452. {
  3453. hostComponentModel: makeHostComponentModel(['HIVE_SERVER', 'HIVE_METASTORE', 'WEBHCAT_SERVER'], [['host1', 'host2'], ['host1','host2'], ['host1', 'host3']]),
  3454. ctrlStubs: {
  3455. fromDeleteHost: true,
  3456. 'content.hostName': 'host2',
  3457. webhcatServerHost: '',
  3458. hiveMetastoreHost: ''
  3459. },
  3460. configs: {
  3461. items: [
  3462. makeFileNameProps('hive-site', [
  3463. ['hive.metastore.uris', 'thrift://host1:1111']
  3464. ]),
  3465. makeFileNameProps('hive-env', [
  3466. ['hive_user', 'hive_user_val'],
  3467. ['webhcat_user', 'webhcat_user_val']
  3468. ]),
  3469. makeFileNameProps('webhcat-site', [
  3470. ['templeton.hive.properties', 'hive.metastore.local=false,hive.metastore.uris=thrift://host1:9083,hive.metastore.sasl.enabled=false']
  3471. ]),
  3472. makeFileNameProps('core-site', [
  3473. ['hadoop.proxyuser.hive_user_val.hosts', 'host1'],
  3474. ['hadoop.proxyuser.webhcat_user_val.hosts', 'host1']
  3475. ])
  3476. ]
  3477. },
  3478. m: 'Components: {0}, appropriate configs should be changed, thrift port should be default 9083, Controller Stubs: {1}',
  3479. e: {
  3480. configs: [
  3481. {
  3482. "properties": {
  3483. "hive-site": makeFileNameProps('hive-site', [
  3484. ['hive.metastore.uris', 'thrift://host1:1111,thrift://host3:1111']
  3485. ]).properties,
  3486. "webhcat-site": makeFileNameProps('webhcat-site', [
  3487. ['templeton.hive.properties', 'hive.metastore.local=false,hive.metastore.uris=thrift://host1:1111\\,thrift://host3:1111,hive.metastore.sasl.enabled=false']
  3488. ]).properties,
  3489. "hive-env": makeFileNameProps('hive-env', [
  3490. ['hive_user', 'hive_user_val'],
  3491. ['webhcat_user', 'webhcat_user_val']
  3492. ]).properties
  3493. },
  3494. "properties_attributes": makeEmptyPropAttrs("hive-site", "webhcat-site", "hive-env")
  3495. },
  3496. {
  3497. "properties": {
  3498. "core-site": makeFileNameProps('core-site', [
  3499. ['hadoop.proxyuser.hive_user_val.hosts', 'host1,host3'],
  3500. ['hadoop.proxyuser.webhcat_user_val.hosts', 'host1,host3']
  3501. ]).properties
  3502. },
  3503. "properties_attributes": makeEmptyPropAttrs("core-site")
  3504. },
  3505. ]
  3506. }
  3507. }
  3508. ];
  3509. tests.forEach(function(test) {
  3510. it(test.m.format(inlineComponentHostInfo(test.hostComponentModel), test.ctrlStubs ? JSON.stringify(test.ctrlStubs) : 'None'), function() {
  3511. if (test.appGetterStubs) {
  3512. Em.keys(test.appGetterStubs).forEach(function(key) {
  3513. sinon.stub(App, 'get').withArgs(key).returns(test.appGetterStubs[key]);
  3514. });
  3515. }
  3516. if (test.ctrlStubs) {
  3517. var stub = sinon.stub(controller, 'get');
  3518. Em.keys(test.ctrlStubs).forEach(function(key) {
  3519. stub.withArgs(key).returns(test.ctrlStubs[key]);
  3520. });
  3521. }
  3522. sinon.stub(App.HostComponent, 'find').returns(test.hostComponentModel);
  3523. controller.onLoadHiveConfigs(test.configs);
  3524. var configs = controller.saveConfigsBatch.args[0];
  3525. var properties = configs[0];
  3526. expect(properties).to.be.eql(test.e.configs);
  3527. if (test.ctrlStubs) controller.get.restore();
  3528. if (test.appGetterStubs) App.get.restore();
  3529. App.HostComponent.find.restore();
  3530. });
  3531. });
  3532. });
  3533. });