details_test.js 130 KB

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