details_test.js 132 KB

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