item_test.js 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311
  1. /**
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. App = require('app');
  19. require('ember');
  20. require('models/host_component');
  21. require('views/common/modal_popup');
  22. require('mixins/common/userPref');
  23. require('controllers/application');
  24. require('controllers/global/background_operations_controller');
  25. require('controllers/global/cluster_controller');
  26. require('controllers/main/service/reassign_controller');
  27. require('controllers/main/service/item');
  28. var batchUtils = require('utils/batch_scheduled_requests');
  29. describe('App.MainServiceItemController', function () {
  30. describe('#setStartStopState', function () {
  31. var tests = [
  32. {
  33. serviceController: {
  34. serviceName: "YARN"
  35. },
  36. backgroundOperationsController: {
  37. services: [
  38. {
  39. isRunning: true,
  40. dependentService: "ALL_SERVICES"
  41. }
  42. ]
  43. },
  44. isPending: true,
  45. m: 'operaion is active because all services are running'
  46. },
  47. {
  48. serviceController: {
  49. serviceName: "HBASE"
  50. },
  51. backgroundOperationsController: {
  52. services: [
  53. {
  54. isRunning: true,
  55. dependentService: "HBASE"
  56. }
  57. ]
  58. },
  59. isPending: true,
  60. m: 'operaion is active button because current service is running'
  61. },
  62. {
  63. serviceController: {
  64. serviceName: "HDFS"
  65. },
  66. backgroundOperationsController: {
  67. services: [
  68. ]
  69. },
  70. isPending: true,
  71. m: 'pending is true - backgroundOperationsController.services is empty'
  72. },
  73. {
  74. serviceController: {
  75. serviceName: "HBASE"
  76. },
  77. backgroundOperationsController: {
  78. services: [
  79. {
  80. isRunning: false,
  81. dependentService: "ALL_SERVICES"
  82. }
  83. ]
  84. },
  85. isPending: false,
  86. m: 'pending is false - operation is not running'
  87. },
  88. {
  89. serviceController: {
  90. serviceName: "HBASE"
  91. },
  92. backgroundOperationsController: {
  93. services: [
  94. {
  95. isRunning: true,
  96. dependentService: "HDFS"
  97. }
  98. ]
  99. },
  100. isPending: false,
  101. m: 'pending is false - current service is not running'
  102. }
  103. ];
  104. tests.forEach(function (test) {
  105. describe(test.m, function () {
  106. var mainServiceItemController;
  107. beforeEach(function () {
  108. sinon.stub(App.router, 'get', function(k) {
  109. if ('backgroundOperationsController.services' === k) return test.backgroundOperationsController.services;
  110. return Em.get(App.router, k);
  111. });
  112. mainServiceItemController = App.MainServiceItemController.create({content: {serviceName: test.serviceController.serviceName}});
  113. mainServiceItemController.setStartStopState();
  114. });
  115. afterEach(function () {
  116. App.router.get.restore();
  117. });
  118. it('isPending is ' + test.isPending, function () {
  119. expect(mainServiceItemController.get('isPending')).to.equal(test.isPending);
  120. });
  121. });
  122. })
  123. });
  124. describe('#reassignMaster()', function () {
  125. var tests = [
  126. {
  127. host_components: [
  128. {componentName: "RESOURCEMANGER"}
  129. ],
  130. componentName: "RESOURCEMANGER",
  131. result: true,
  132. m: 'run reassignMaster'
  133. },
  134. {
  135. host_components: [
  136. {componentName: "RESOURCEMANGER"}
  137. ],
  138. componentName: "DATANODE",
  139. result: false,
  140. m: 'don\t run reassignMaster'
  141. }
  142. ];
  143. tests.forEach(function (test) {
  144. describe(test.m, function () {
  145. var reassignMasterController = App.ReassignMasterController.create({currentStep: ''});
  146. beforeEach(function () {
  147. sinon.stub(reassignMasterController, 'saveComponentToReassign', Em.K);
  148. sinon.stub(reassignMasterController, 'setCurrentStep', Em.K);
  149. sinon.stub(App.router, 'transitionTo', Em.K);
  150. var mainServiceItemController = App.MainServiceItemController.create({});
  151. sinon.stub(App.HostComponent, 'find', function() {
  152. return test.host_components
  153. });
  154. sinon.stub(App.router, 'get', function(k) {
  155. if ('reassignMasterController' === k) return reassignMasterController;
  156. return Em.get(App.router, k);
  157. });
  158. mainServiceItemController.reassignMaster(test.componentName);
  159. });
  160. afterEach(function () {
  161. reassignMasterController.saveComponentToReassign.restore();
  162. reassignMasterController.setCurrentStep.restore();
  163. App.HostComponent.find.restore();
  164. App.router.transitionTo.restore();
  165. App.router.get.restore();
  166. });
  167. it('saveComponentToReassign is ' + (test.result ? '' : 'not') + ' called once', function () {
  168. expect(reassignMasterController.saveComponentToReassign.calledOnce).to.equal(test.result);
  169. });
  170. it('setCurrentStep is ' + (test.result ? '' : 'not') + ' called once', function () {
  171. expect(reassignMasterController.setCurrentStep.calledOnce).to.equal(test.result);
  172. });
  173. });
  174. }, this);
  175. });
  176. describe("#doAction", function () {
  177. var el = document.createElement("BUTTON");
  178. el.disabled = false;
  179. var tests = [
  180. {
  181. event: {
  182. target: el,
  183. context: {
  184. action: 'runSmokeTest'
  185. }
  186. },
  187. m: "run runSmokeTest"
  188. },
  189. {
  190. event: {
  191. target: el,
  192. context: {
  193. action: 'refreshConfigs'
  194. }
  195. },
  196. m: "run refreshConfigs"
  197. },
  198. {
  199. event: {
  200. target: el,
  201. context: {
  202. action: 'restartAllHostComponents'
  203. }
  204. },
  205. m: "run restartAllHostComponents"
  206. },
  207. {
  208. event: {
  209. target: el,
  210. context: {
  211. action: 'rollingRestart'
  212. }
  213. },
  214. m: "run rollingRestart"
  215. }
  216. ];
  217. tests.forEach(function (test) {
  218. var mainServiceItemController = App.MainServiceItemController.create({});
  219. mainServiceItemController.set(test.event.context.action, Em.K);
  220. beforeEach(function () {
  221. sinon.spy(mainServiceItemController, test.event.context.action);
  222. });
  223. afterEach(function () {
  224. mainServiceItemController[test.event.context.action].restore();
  225. });
  226. it(test.m, function () {
  227. mainServiceItemController.doAction(test.event);
  228. expect(mainServiceItemController[test.event.context.action].calledOnce).to.equal(!test.event.target.disabled);
  229. });
  230. });
  231. });
  232. describe("#startService , #stopService", function () {
  233. var mainServiceItemController = App.MainServiceItemController.create({startStopPopup: Em.K});
  234. beforeEach(function () {
  235. sinon.spy(mainServiceItemController, "startStopPopup");
  236. });
  237. afterEach(function () {
  238. mainServiceItemController.startStopPopup.restore();
  239. });
  240. it("start service", function () {
  241. mainServiceItemController.startService({});
  242. expect(mainServiceItemController.startStopPopup.calledWith({},App.HostComponentStatus.started)).to.equal(true);
  243. });
  244. it("stop service", function () {
  245. mainServiceItemController.stopService({});
  246. expect(mainServiceItemController.startStopPopup.calledWith({},App.HostComponentStatus.stopped)).to.equal(true);
  247. });
  248. });
  249. describe("#turnOnOffPassive", function () {
  250. var mainServiceItemController = App.MainServiceItemController.create({turnOnOffPassiveRequest: Em.K});
  251. beforeEach(function () {
  252. sinon.spy(batchUtils, "turnOnOffPassiveRequest");
  253. mainServiceItemController.set('content', {serviceName: ''});
  254. });
  255. afterEach(function () {
  256. batchUtils.turnOnOffPassiveRequest.restore();
  257. });
  258. it("turns on/off passive mode for service", function () {
  259. mainServiceItemController.turnOnOffPassive({}).onPrimary();
  260. expect(batchUtils.turnOnOffPassiveRequest.calledOnce).to.equal(true);
  261. });
  262. });
  263. describe("#runSmokeTest", function () {
  264. var tests = [
  265. {
  266. content: {
  267. id: "YARN",
  268. service_name: "YARN",
  269. work_status: "STARTED"
  270. },
  271. startSmoke: true,
  272. serviceName: "MAPREDUCE2",
  273. m: "don't run smoke test primary for MAPREDUCE2"
  274. },
  275. {
  276. content: {
  277. id: "YARN",
  278. service_name: "YARN",
  279. work_status: "STOPPED"
  280. },
  281. startSmoke: false,
  282. serviceName: "MAPREDUCE2",
  283. m: "run smoke test primary for MAPREDUCE2"
  284. },
  285. {
  286. m: "run smoke test primary for all services (not MAPREDUCE2)",
  287. startSmoke: true,
  288. default: true
  289. }
  290. ];
  291. tests.forEach(function (test) {
  292. var mainServiceItemController = test.default ? App.MainServiceItemController.create({runSmokeTestPrimary: Em.K}) :
  293. App.MainServiceItemController.create({content: {serviceName: test.serviceName}, runSmokeTestPrimary: Em.K});
  294. beforeEach(function () {
  295. sinon.spy(mainServiceItemController, "runSmokeTestPrimary");
  296. });
  297. afterEach(function () {
  298. mainServiceItemController.runSmokeTestPrimary.restore();
  299. });
  300. it(test.m, function () {
  301. if (!test.default) {
  302. App.store.load(App.Service, test.content);
  303. }
  304. mainServiceItemController.runSmokeTest({}).onPrimary();
  305. expect(mainServiceItemController.runSmokeTestPrimary.calledOnce).to.equal(test.startSmoke);
  306. });
  307. });
  308. });
  309. describe("#startStopPopup", function () {
  310. var el = document.createElement("BUTTON");
  311. el.disabled = false;
  312. var event = {
  313. target: el
  314. };
  315. var mainServiceItemController = App.MainServiceItemController.create({
  316. content: {
  317. serviceName: "HDFS",
  318. hostComponents: [ {
  319. componentName: 'NAMENODE',
  320. workStatus: 'INSTALLED'
  321. }]
  322. }
  323. });
  324. var mainServiceItemControllerHdfsStarted = App.MainServiceItemController.create({
  325. content: {
  326. serviceName: "HDFS",
  327. hostComponents: [ {
  328. componentName: 'NAMENODE',
  329. workStatus: 'STARTED'
  330. }]
  331. }
  332. });
  333. beforeEach(function () {
  334. sinon.spy(mainServiceItemController, "startStopPopupPrimary");
  335. sinon.spy(mainServiceItemControllerHdfsStarted, "startStopPopupPrimary");
  336. sinon.spy(Em.I18n, "t");
  337. sinon.stub(mainServiceItemControllerHdfsStarted, 'checkNnLastCheckpointTime', function(callback) {
  338. return callback;
  339. });
  340. });
  341. afterEach(function () {
  342. mainServiceItemController.startStopPopupPrimary.restore();
  343. mainServiceItemControllerHdfsStarted.startStopPopupPrimary.restore();
  344. mainServiceItemControllerHdfsStarted.checkNnLastCheckpointTime.restore();
  345. Em.I18n.t.restore();
  346. });
  347. it("start start/stop service popup", function () {
  348. mainServiceItemController.startStopPopup(event, "").onPrimary();
  349. expect(mainServiceItemController.startStopPopupPrimary.calledOnce).to.equal(true);
  350. });
  351. it ("should popup warning to check last checkpoint time if work status is STARTED", function() {
  352. mainServiceItemControllerHdfsStarted.startStopPopup(event, "INSTALLED");
  353. expect(mainServiceItemControllerHdfsStarted.checkNnLastCheckpointTime.calledOnce).to.equal(true);
  354. });
  355. describe("modal messages", function() {
  356. beforeEach(function () {
  357. sinon.stub(App.StackService, 'find').returns([
  358. Em.Object.create({
  359. serviceName: 'HDFS',
  360. displayName: 'HDFS',
  361. isInstalled: true,
  362. isSelected: true,
  363. requiredServices:["ZOOKEEPER"]
  364. }),
  365. Em.Object.create({
  366. serviceName: 'HIVE',
  367. displayName: 'Hive',
  368. isInstalled: true,
  369. isSelected: true
  370. }),
  371. Em.Object.create({
  372. serviceName: 'HBASE',
  373. displayName: 'HBase',
  374. isInstalled: true,
  375. isSelected: true,
  376. requiredServices:["HDFS", "ZOOKEEPER"]
  377. }),
  378. Em.Object.create({
  379. serviceName: 'YARN',
  380. displayName: 'YARN',
  381. isInstalled: true,
  382. isSelected: true,
  383. requiredServices:["HDFS"]
  384. }),
  385. Em.Object.create({
  386. serviceName: 'SPARK',
  387. displayName: 'Spark',
  388. isInstalled: true,
  389. isSelected: true,
  390. requiredServices:["HIVE"]
  391. })
  392. ]);
  393. });
  394. it ("should confirm stop if serviceHealth is INSTALLED", function() {
  395. mainServiceItemController.startStopPopup(event, "INSTALLED");
  396. expect(Em.I18n.t.calledWith('services.service.stop.confirmMsg')).to.be.ok;
  397. expect(Em.I18n.t.calledWith('services.service.stop.confirmButton')).to.be.ok;
  398. });
  399. it ("should confirm start if serviceHealth is not INSTALLED", function() {
  400. mainServiceItemController.startStopPopup(event, "");
  401. expect(Em.I18n.t.calledWith('services.service.start.confirmMsg')).to.be.ok;
  402. expect(Em.I18n.t.calledWith('services.service.start.confirmButton')).to.be.ok;
  403. });
  404. it ("should not display a dependent list if it is to start a service", function() {
  405. var _mainServiceItemController = App.MainServiceItemController.create(
  406. {content: {serviceName: "HDFS", passiveState:'OFF'}});
  407. _mainServiceItemController.startStopPopup(event, "");
  408. expect(Em.I18n.t.calledWith('services.service.stop.warningMsg.dependent.services')).to.not.be.ok;
  409. });
  410. describe ("should display dependent list if other services depend on the one to be stopped", function() {
  411. beforeEach(function () {
  412. var _mainServiceItemController = App.MainServiceItemController.create(
  413. {content: {
  414. serviceName: "HDFS",
  415. passiveState:'OFF',
  416. hostComponents: [{
  417. componentName: 'NAMENODE',
  418. workStatus: 'INSTALLED'
  419. }]
  420. }}
  421. );
  422. _mainServiceItemController.startStopPopup(event, "INSTALLED");
  423. this.dependencies = Em.I18n.t('services.service.stop.warningMsg.dependent.services').format("HDFS", "HBase,YARN");
  424. this.msg = Em.I18n.t('services.service.stop.warningMsg.turnOnMM').format("HDFS");
  425. this.fullMsg = _mainServiceItemController.addAdditionalWarningMessage("INSTALLED", this.msg, "HDFS");
  426. });
  427. it('turnOnMM message is shown', function () {
  428. expect(Em.I18n.t.calledWith('services.service.stop.warningMsg.turnOnMM')).to.be.ok;
  429. });
  430. it('message about dependent services is shown', function () {
  431. expect(Em.I18n.t.calledWith('services.service.stop.warningMsg.dependent.services')).to.be.ok;
  432. });
  433. it('full message is valid', function () {
  434. expect(this.fullMsg).to.be.equal(this.msg + " " + this.dependencies);
  435. });
  436. });
  437. describe("should display the dependent service if another service depends on the one to be stopped", function() {
  438. beforeEach(function () {
  439. var _mainServiceItemController = App.MainServiceItemController.create(
  440. {content: {serviceName: "HIVE", passiveState:'OFF'}});
  441. _mainServiceItemController.startStopPopup(event, "INSTALLED");
  442. this.dependencies = Em.I18n.t('services.service.stop.warningMsg.dependent.services').format("HIVE", "Spark");
  443. this.msg = Em.I18n.t('services.service.stop.warningMsg.turnOnMM').format("HIVE");
  444. this.fullMsg = _mainServiceItemController.addAdditionalWarningMessage("INSTALLED", this.msg, "HIVE");
  445. });
  446. it('message about dependent services is shown', function () {
  447. expect(Em.I18n.t.calledWith('services.service.stop.warningMsg.dependent.services')).to.be.ok;
  448. });
  449. it('full message is valid', function () {
  450. expect(this.fullMsg).to.be.equal(this.msg + " " + this.dependencies);
  451. });
  452. });
  453. afterEach(function () {
  454. App.StackService.find.restore();
  455. });
  456. });
  457. });
  458. describe("#restartAllHostComponents", function () {
  459. var temp = batchUtils.restartAllServiceHostComponents;
  460. var mainServiceItemController = App.MainServiceItemController.create({
  461. content: {
  462. serviceName: "HDFS",
  463. hostComponents: [{
  464. componentName: 'NAMENODE',
  465. workStatus: 'STARTED'
  466. }]
  467. }
  468. });
  469. beforeEach(function () {
  470. batchUtils.restartAllServiceHostComponents = Em.K;
  471. sinon.spy(batchUtils, "restartAllServiceHostComponents");
  472. sinon.stub(App.Service, 'find', function() {
  473. return Em.Object.create({serviceTypes: []});
  474. });
  475. sinon.stub(mainServiceItemController, 'checkNnLastCheckpointTime', function() {
  476. return true;
  477. });
  478. });
  479. afterEach(function () {
  480. batchUtils.restartAllServiceHostComponents.restore();
  481. batchUtils.restartAllServiceHostComponents = temp;
  482. App.Service.find.restore();
  483. mainServiceItemController.checkNnLastCheckpointTime.restore();
  484. });
  485. it("start restartAllHostComponents for service", function () {
  486. var controller = App.MainServiceItemController.create({
  487. content: {
  488. serviceName: "HDFS",
  489. hostComponents: [{
  490. componentName: 'NAMENODE',
  491. workStatus: 'INSTALLED'
  492. }]
  493. }
  494. });
  495. controller.restartAllHostComponents({}).onPrimary();
  496. expect(batchUtils.restartAllServiceHostComponents.calledOnce).to.equal(true);
  497. });
  498. it("check last checkpoint time for NameNode before start restartAllHostComponents for service", function () {
  499. mainServiceItemController.restartAllHostComponents({});
  500. expect(mainServiceItemController.checkNnLastCheckpointTime.calledOnce).to.equal(true);
  501. });
  502. });
  503. describe("#rollingRestart", function () {
  504. var temp = batchUtils.launchHostComponentRollingRestart;
  505. beforeEach(function () {
  506. batchUtils.launchHostComponentRollingRestart = Em.K;
  507. sinon.spy(batchUtils, "launchHostComponentRollingRestart");
  508. });
  509. afterEach(function () {
  510. batchUtils.launchHostComponentRollingRestart.restore();
  511. batchUtils.launchHostComponentRollingRestart = temp;
  512. });
  513. var mainServiceItemController = App.MainServiceItemController.create();
  514. it("start restartAllHostComponents for service", function () {
  515. mainServiceItemController.rollingRestart();
  516. expect(batchUtils.launchHostComponentRollingRestart.calledOnce).to.equal(true);
  517. });
  518. });
  519. describe("#parseNnCheckPointTime", function () {
  520. var tests = [
  521. {
  522. m: "NameNode has JMX data, the last checkpoint time is less than 12 hours ago",
  523. data:
  524. {"href" : "",
  525. "ServiceComponentInfo" : {
  526. "cluster_name" : "c123",
  527. "component_name" : "NAMENODE",
  528. "service_name" : "HDFS"
  529. },
  530. "host_components" : [
  531. {
  532. "href" : "",
  533. "HostRoles" : {
  534. "cluster_name" : "c123",
  535. "component_name" : "NAMENODE",
  536. "host_name" : "c6401.ambari.apache.org"
  537. },
  538. "metrics" : {
  539. "dfs" : {
  540. "FSNamesystem" : {
  541. "HAState" : "active",
  542. "LastCheckpointTime" : 1435775648000
  543. }
  544. }
  545. }
  546. }
  547. ]
  548. },
  549. result: false
  550. },
  551. {
  552. m: "NameNode has JMX data, the last checkpoint time is > 12 hours ago",
  553. data:
  554. {"href" : "",
  555. "ServiceComponentInfo" : {
  556. "cluster_name" : "c123",
  557. "component_name" : "NAMENODE",
  558. "service_name" : "HDFS"
  559. },
  560. "host_components" : [
  561. {
  562. "href" : "",
  563. "HostRoles" : {
  564. "cluster_name" : "c123",
  565. "component_name" : "NAMENODE",
  566. "host_name" : "c6401.ambari.apache.org"
  567. },
  568. "metrics" : {
  569. "dfs" : {
  570. "FSNamesystem" : {
  571. "HAState" : "active",
  572. "LastCheckpointTime" : 1435617248000
  573. }
  574. }
  575. }
  576. }
  577. ]
  578. },
  579. result: "c6401.ambari.apache.org"
  580. },
  581. {
  582. m: "NameNode has no JMX data available",
  583. data:
  584. {"href" : "",
  585. "ServiceComponentInfo" : {
  586. "cluster_name" : "c123",
  587. "component_name" : "NAMENODE",
  588. "service_name" : "HDFS"
  589. },
  590. "host_components" : [
  591. {
  592. "href" : "",
  593. "HostRoles" : {
  594. "cluster_name" : "c123",
  595. "component_name" : "NAMENODE",
  596. "host_name" : "c6401.ambari.apache.org"
  597. },
  598. "metrics" : {
  599. "dfs" : {
  600. "FSNamesystem" : {
  601. "HAState" : "active"
  602. }
  603. }
  604. }
  605. }
  606. ]
  607. },
  608. result: null
  609. },
  610. {
  611. m: "HA enabled, both active and standby NN has JMX data normally.",
  612. data:
  613. {"href" : "",
  614. "ServiceComponentInfo" : {
  615. "cluster_name" : "c123",
  616. "component_name" : "NAMENODE",
  617. "service_name" : "HDFS"
  618. },
  619. "host_components" : [
  620. {
  621. "href" : "",
  622. "HostRoles" : {
  623. "cluster_name" : "c123",
  624. "component_name" : "NAMENODE",
  625. "host_name" : "c6401.ambari.apache.org"
  626. },
  627. "metrics" : {
  628. "dfs" : {
  629. "FSNamesystem" : {
  630. "HAState" : "active",
  631. "LastCheckpointTime" : 1435775648000
  632. }
  633. }
  634. }
  635. },
  636. {
  637. "href" : "",
  638. "HostRoles" : {
  639. "cluster_name" : "c123",
  640. "component_name" : "NAMENODE",
  641. "host_name" : "c6402.ambari.apache.org"
  642. },
  643. "metrics" : {
  644. "dfs" : {
  645. "FSNamesystem" : {
  646. "HAState" : "standby",
  647. "LastCheckpointTime" : 1435775648000
  648. }
  649. }
  650. }
  651. }
  652. ]
  653. },
  654. result: false
  655. },
  656. {
  657. m: "HA enabled, both NamoNodes are standby NN",
  658. data:
  659. {"href" : "",
  660. "ServiceComponentInfo" : {
  661. "cluster_name" : "c123",
  662. "component_name" : "NAMENODE",
  663. "service_name" : "HDFS"
  664. },
  665. "host_components" : [
  666. {
  667. "href" : "",
  668. "HostRoles" : {
  669. "cluster_name" : "c123",
  670. "component_name" : "NAMENODE",
  671. "host_name" : "c6401.ambari.apache.org"
  672. },
  673. "metrics" : {
  674. "dfs" : {
  675. "FSNamesystem" : {
  676. "HAState" : "standby",
  677. "LastCheckpointTime" : 1435775648000
  678. }
  679. }
  680. }
  681. },
  682. {
  683. "href" : "",
  684. "HostRoles" : {
  685. "cluster_name" : "c123",
  686. "component_name" : "NAMENODE",
  687. "host_name" : "c6402.ambari.apache.org"
  688. },
  689. "metrics" : {
  690. "dfs" : {
  691. "FSNamesystem" : {
  692. "HAState" : "standby",
  693. "LastCheckpointTime" : 1435775648000
  694. }
  695. }
  696. }
  697. }
  698. ]
  699. },
  700. result: false
  701. },
  702. {
  703. m: "HA enabled, active NN has no JMX data, use the standby's data",
  704. data:
  705. {"href" : "",
  706. "ServiceComponentInfo" : {
  707. "cluster_name" : "c123",
  708. "component_name" : "NAMENODE",
  709. "service_name" : "HDFS"
  710. },
  711. "host_components" : [
  712. {
  713. "href" : "",
  714. "HostRoles" : {
  715. "cluster_name" : "c123",
  716. "component_name" : "NAMENODE",
  717. "host_name" : "c6401.ambari.apache.org"
  718. },
  719. "metrics" : {
  720. "dfs" : {
  721. "FSNamesystem" : {
  722. "HAState" : "active"
  723. }
  724. }
  725. }
  726. },
  727. {
  728. "href" : "",
  729. "HostRoles" : {
  730. "cluster_name" : "c123",
  731. "component_name" : "NAMENODE",
  732. "host_name" : "c6402.ambari.apache.org"
  733. },
  734. "metrics" : {
  735. "dfs" : {
  736. "FSNamesystem" : {
  737. "HAState" : "standby",
  738. "LastCheckpointTime" : 1435775648000
  739. }
  740. }
  741. }
  742. }
  743. ]
  744. },
  745. result: false
  746. },
  747. {
  748. m: "HA enabled, both NamoNodes no JMX data",
  749. data:
  750. {"href" : "",
  751. "ServiceComponentInfo" : {
  752. "cluster_name" : "c123",
  753. "component_name" : "NAMENODE",
  754. "service_name" : "HDFS"
  755. },
  756. "host_components" : [
  757. {
  758. "href" : "",
  759. "HostRoles" : {
  760. "cluster_name" : "c123",
  761. "component_name" : "NAMENODE",
  762. "host_name" : "c6401.ambari.apache.org"
  763. },
  764. "metrics" : {
  765. "dfs" : {
  766. "FSNamesystem" : {
  767. "HAState" : "active"
  768. }
  769. }
  770. }
  771. },
  772. {
  773. "href" : "",
  774. "HostRoles" : {
  775. "cluster_name" : "c123",
  776. "component_name" : "NAMENODE",
  777. "host_name" : "c6402.ambari.apache.org"
  778. },
  779. "metrics" : {
  780. "dfs" : {
  781. "FSNamesystem" : {
  782. "HAState" : "standby"
  783. }
  784. }
  785. }
  786. }
  787. ]
  788. },
  789. result: null
  790. }
  791. ];
  792. beforeEach(function () {
  793. sinon.stub(App, 'dateTime').returns(1435790048000);
  794. });
  795. afterEach(function () {
  796. App.dateTime.restore();
  797. });
  798. tests.forEach(function (test) {
  799. it(test.m, function () {
  800. var mainServiceItemController = App.MainServiceItemController.create({isNNCheckpointTooOld: null});
  801. mainServiceItemController.parseNnCheckPointTime(test.data);
  802. expect(mainServiceItemController.get('isNNCheckpointTooOld')).to.equal(test.result);
  803. });
  804. });
  805. });
  806. describe("#isStartDisabled", function () {
  807. var tests = [
  808. {
  809. content: {
  810. healthStatus: 'red'
  811. },
  812. isPending: true,
  813. disabled: true,
  814. m: "disabled because of pending"
  815. },
  816. {
  817. content: {
  818. healthStatus: 'green'
  819. },
  820. isPending: false,
  821. disabled: true,
  822. m: "disabled because healthStatus is not red"
  823. },
  824. {
  825. content: {
  826. healthStatus: 'red'
  827. },
  828. isPending: false,
  829. disabled: false,
  830. m: "enabled because healthStatus is red and pending is false"
  831. }
  832. ];
  833. tests.forEach(function (test) {
  834. it(test.m, function () {
  835. var mainServiceItemController = App.MainServiceItemController.create({content: {healthStatus: test.content.healthStatus}, isPending: test.isPending});
  836. expect(mainServiceItemController.get('isStartDisabled')).to.equal(test.disabled);
  837. });
  838. });
  839. });
  840. describe("#isStopDisabled", function () {
  841. var tests = [
  842. {
  843. content: {
  844. healthStatus: 'red'
  845. },
  846. isPending: true,
  847. disabled: true,
  848. m: "disabled because of pending"
  849. },
  850. {
  851. content: {
  852. healthStatus: 'green'
  853. },
  854. isPending: false,
  855. disabled: false,
  856. m: "enabled because healthStatus is green and pending is false"
  857. },
  858. {
  859. content: {
  860. healthStatus: 'red'
  861. },
  862. isPending: false,
  863. disabled: true,
  864. m: "disabled because healthStatus is not green"
  865. }
  866. ];
  867. tests.forEach(function (test) {
  868. it(test.m, function () {
  869. var mainServiceItemController = App.MainServiceItemController.create({content: test.content, isPending: test.isPending});
  870. expect(mainServiceItemController.get('isStopDisabled')).to.equal(test.disabled);
  871. });
  872. });
  873. });
  874. describe("#runRebalancer", function () {
  875. beforeEach(function () {
  876. sinon.stub(App.router, 'get', function(k) {
  877. if ('applicationController' === k) {
  878. return Em.Object.create({
  879. dataLoading: function() {
  880. return {done: Em.K}
  881. }
  882. });
  883. }
  884. return Em.get(App.router, k);
  885. });
  886. });
  887. afterEach(function () {
  888. App.router.get.restore();
  889. });
  890. it("run rebalancer", function () {
  891. var mainServiceItemController = App.MainServiceItemController.create({content: {runRebalancer: false}});
  892. mainServiceItemController.runRebalancer().onPrimary();
  893. expect(mainServiceItemController.get("content.runRebalancer")).to.equal(true);
  894. });
  895. });
  896. describe("#runCompaction", function () {
  897. beforeEach(function () {
  898. sinon.stub(App.router, 'get', function(k) {
  899. if ('applicationController' === k) {
  900. return Em.Object.create({
  901. dataLoading: function() {
  902. return {done: Em.K}
  903. }
  904. });
  905. }
  906. return Em.get(App.router, k);
  907. });
  908. });
  909. afterEach(function () {
  910. App.router.get.restore();
  911. });
  912. it("run compaction", function () {
  913. var mainServiceItemController = App.MainServiceItemController.create({content: {runCompaction: false}});
  914. mainServiceItemController.runCompaction().onPrimary();
  915. expect(mainServiceItemController.get("content.runCompaction")).to.equal(true);
  916. });
  917. });
  918. describe("#runSmokeTestPrimary", function () {
  919. beforeEach(function () {
  920. sinon.stub(App, 'get').withArgs('clusterName').returns('myCluster');
  921. sinon.spy($, 'ajax');
  922. });
  923. afterEach(function () {
  924. App.get.restore();
  925. $.ajax.restore();
  926. });
  927. var tests = [
  928. {
  929. data: {
  930. 'serviceName': "HDFS",
  931. 'displayName': "HDFS",
  932. 'query': "test"
  933. },
  934. "RequestInfo": {
  935. "context": "HDFS Service Check",
  936. "command" : "HDFS_SERVICE_CHECK"
  937. },
  938. "Requests/resource_filters": [{"service_name" : "HDFS"}]
  939. },
  940. {
  941. data: {
  942. 'serviceName': "KERBEROS",
  943. 'displayName': "Kerberos",
  944. 'query': "test"
  945. },
  946. "RequestInfo": {
  947. "context": "Kerberos Service Check",
  948. "command" : "KERBEROS_SERVICE_CHECK",
  949. "operation_level": {
  950. "level": "CLUSTER",
  951. "cluster_name": "myCluster"
  952. }
  953. },
  954. "Requests/resource_filters": [{"service_name" : "KERBEROS"}]
  955. }
  956. ];
  957. tests.forEach(function (test) {
  958. var mainServiceItemController = App.MainServiceItemController.create({content: {serviceName: test.data.serviceName,
  959. displayName: test.data.displayName}});
  960. describe('send request to run smoke test for ' + test.data.serviceName, function () {
  961. beforeEach(function () {
  962. mainServiceItemController.set("runSmokeTestErrorCallBack", Em.K);
  963. mainServiceItemController.set("runSmokeTestSuccessCallBack", Em.K);
  964. mainServiceItemController.runSmokeTestPrimary(test.data.query);
  965. this.data = JSON.parse($.ajax.args[0][0].data);
  966. });
  967. it('ajax request is sent', function () {
  968. expect($.ajax.calledOnce).to.equal(true);
  969. });
  970. it('RequestInfo.context is valid', function () {
  971. expect(this.data.RequestInfo.context).to.equal(test.RequestInfo.context);
  972. });
  973. it('RequestInfo.command is valid', function () {
  974. expect(this.data.RequestInfo.command).to.equal(test.RequestInfo.command);
  975. });
  976. it('Requests/resource_filter.0.serviceName is valid', function () {
  977. expect(this.data["Requests/resource_filters"][0].serviceName).to.equal(test["Requests/resource_filters"][0].serviceName);
  978. });
  979. it('RequestInfo.operation_level is valid', function () {
  980. expect(this.data.RequestInfo.operation_level).to.be.deep.equal(test.RequestInfo.operation_level);
  981. });
  982. });
  983. });
  984. });
  985. describe('#downloadClientConfigs()', function () {
  986. var mainServiceItemController = App.MainServiceItemController.create({
  987. content: {
  988. clientComponents: [
  989. Em.Object.create({
  990. totalCount: 1,
  991. componentName: 'C1',
  992. displayName: 'd1'
  993. })
  994. ],
  995. serviceName: 'S1'
  996. }
  997. });
  998. beforeEach(function () {
  999. sinon.stub(mainServiceItemController, 'downloadClientConfigsCall', Em.K);
  1000. });
  1001. afterEach(function () {
  1002. mainServiceItemController.downloadClientConfigsCall.restore();
  1003. });
  1004. it('should launch $.fileDownload method', function () {
  1005. mainServiceItemController.downloadClientConfigs();
  1006. expect(mainServiceItemController.downloadClientConfigsCall.calledWith({
  1007. serviceName: 'S1',
  1008. componentName: 'C1',
  1009. displayName: 'd1'
  1010. })).to.be.true;
  1011. });
  1012. it('should launch $.fileDownload method, event passed', function () {
  1013. var event = {
  1014. label: 'label1',
  1015. name: 'name1'
  1016. };
  1017. mainServiceItemController.downloadClientConfigs(event);
  1018. expect(mainServiceItemController.downloadClientConfigsCall.calledWith({
  1019. serviceName: 'S1',
  1020. componentName: 'name1',
  1021. displayName: 'label1'
  1022. })).to.be.true;
  1023. });
  1024. });
  1025. describe('#startLdapKnox() and #stopLdapKnox() should call startStopLdapKnox once: ', function () {
  1026. var mainServiceItemController = App.MainServiceItemController.create({content: {serviceName: 'KNOX',
  1027. displayName: 'Knox'}});
  1028. beforeEach(function () {
  1029. sinon.stub(mainServiceItemController, 'startStopLdapKnox', function(){
  1030. return true;
  1031. });
  1032. });
  1033. afterEach(function () {
  1034. mainServiceItemController.startStopLdapKnox.restore();
  1035. });
  1036. var tests = [
  1037. {
  1038. methodName: 'startLdapKnox',
  1039. callback: mainServiceItemController.startLdapKnox
  1040. },
  1041. {
  1042. methodName: 'stopLdapKnox',
  1043. callback: mainServiceItemController.stopLdapKnox
  1044. }
  1045. ];
  1046. tests.forEach(function(test){
  1047. it(test.methodName + ' should call startStopLdapKnox method', function () {
  1048. test.callback.call(mainServiceItemController);
  1049. expect(mainServiceItemController.startStopLdapKnox.calledOnce).to.be.true;
  1050. });
  1051. },this);
  1052. });
  1053. describe("#executeCustomCommand", function () {
  1054. var data = {
  1055. data: {
  1056. 'serviceName': "SAMPLESRV",
  1057. 'displayName': "SAMPLESRV",
  1058. 'query': "test"
  1059. },
  1060. "RequestInfo": {
  1061. "context": "Execute Custom Commands",
  1062. "command" : "SAMPLESRVCUSTOMCOMMANDS"
  1063. },
  1064. "Requests/resource_filters": [{"service_name" : "SAMPLESRV"}]
  1065. };
  1066. var context = {
  1067. label: 'Execute Custom Commands',
  1068. service: data.data.serviceName,
  1069. component: data.data.serviceName,
  1070. command: data.RequestInfo.command
  1071. };
  1072. var mainServiceItemController = App.MainServiceItemController.create({
  1073. content: {
  1074. serviceName: data.data.serviceName,
  1075. displayName: data.data.displayName
  1076. }
  1077. });
  1078. before(function () {
  1079. mainServiceItemController.set("executeCustomCommandErrorCallback", Em.K);
  1080. mainServiceItemController.set("executeCustomCommandSuccessCallback", Em.K);
  1081. sinon.spy(App, 'showConfirmationPopup');
  1082. });
  1083. after(function () {
  1084. App.showConfirmationPopup.restore();
  1085. });
  1086. it('shows a confirmation popup', function () {
  1087. mainServiceItemController.executeCustomCommand(context);
  1088. expect(App.showConfirmationPopup.calledOnce).to.equal(true);
  1089. });
  1090. });
  1091. describe("#deleteService()", function() {
  1092. var mainServiceItemController;
  1093. beforeEach(function() {
  1094. mainServiceItemController = App.MainServiceItemController.create({});
  1095. this.mockStackService = sinon.stub(App.StackService, 'find');
  1096. sinon.stub(mainServiceItemController, 'dependentServicesWarning');
  1097. this.mockService = sinon.stub(App.Service, 'find');
  1098. sinon.stub(App, 'showConfirmationPopup');
  1099. sinon.stub(App.ModalPopup, 'show');
  1100. sinon.stub(App.format, 'role', function(name) {return name});
  1101. });
  1102. afterEach(function() {
  1103. this.mockStackService.restore();
  1104. this.mockService.restore();
  1105. mainServiceItemController.dependentServicesWarning.restore();
  1106. App.showConfirmationPopup.restore();
  1107. App.ModalPopup.show.restore();
  1108. App.format.role.restore();
  1109. });
  1110. it("service has installed dependent services", function() {
  1111. this.mockStackService.returns(Em.Object.create({requiredServices: ['S2']}));
  1112. this.mockService.returns(Em.Object.create({workStatus: 'INSTALLED', isLoaded: true}));
  1113. mainServiceItemController.deleteService('S1');
  1114. expect(mainServiceItemController.dependentServicesWarning.calledWith('S1', ['S2'])).to.be.true;
  1115. });
  1116. it("service has not-installed dependent services, and stopped", function() {
  1117. this.mockStackService.returns(Em.Object.create({requiredServices: ['S2']}));
  1118. this.mockService.returns(Em.Object.create({workStatus: 'INSTALLED', isLoaded: false}));
  1119. mainServiceItemController.deleteService('S1');
  1120. expect(App.showConfirmationPopup.calledOnce).to.be.true;
  1121. });
  1122. it("service has not dependent services, and stopped", function() {
  1123. this.mockStackService.returns(Em.Object.create({requiredServices: []}));
  1124. this.mockService.returns(Em.Object.create({workStatus: 'INSTALLED', isLoaded: true}));
  1125. mainServiceItemController.deleteService('S1');
  1126. expect(App.showConfirmationPopup.calledOnce).to.be.true;
  1127. });
  1128. it("service has not dependent services, and not stopped", function() {
  1129. this.mockStackService.returns(Em.Object.create({requiredServices: []}));
  1130. this.mockService.returns(Em.Object.create({workStatus: 'STARTED', isLoaded: true}));
  1131. mainServiceItemController.deleteService('S1');
  1132. expect(App.ModalPopup.show.calledWith({
  1133. secondary: null,
  1134. header: Em.I18n.t('services.service.delete.popup.header'),
  1135. encodeBody: false,
  1136. body: Em.I18n.t('services.service.delete.popup.mustBeStopped').format('S1')
  1137. })).to.be.true;
  1138. });
  1139. });
  1140. describe("#dependentServicesWarning()", function() {
  1141. var mainServiceItemController;
  1142. beforeEach(function() {
  1143. mainServiceItemController = App.MainServiceItemController.create({});
  1144. sinon.stub(App.ModalPopup, 'show');
  1145. sinon.stub(App.format, 'role', function(name) {return name});
  1146. });
  1147. afterEach(function() {
  1148. App.ModalPopup.show.restore();
  1149. App.format.role.restore();
  1150. });
  1151. it("App.ModalPopup.show should be called", function() {
  1152. mainServiceItemController.dependentServicesWarning('S1', ['S2']);
  1153. expect(App.ModalPopup.show.calledOnce).to.be.true;
  1154. });
  1155. });
  1156. describe("#confirmDeleteService()", function() {
  1157. var mainServiceItemController;
  1158. beforeEach(function() {
  1159. mainServiceItemController = App.MainServiceItemController.create({});
  1160. sinon.stub(App.ModalPopup, 'show');
  1161. });
  1162. afterEach(function() {
  1163. App.ModalPopup.show.restore();
  1164. });
  1165. it("App.ModalPopup.show should be called", function() {
  1166. mainServiceItemController.confirmDeleteService();
  1167. expect(App.ModalPopup.show.calledOnce).to.be.true;
  1168. });
  1169. });
  1170. describe("#deleteServiceCall()", function() {
  1171. var mainServiceItemController;
  1172. beforeEach(function() {
  1173. mainServiceItemController = App.MainServiceItemController.create({});
  1174. sinon.stub(App.ajax, 'send');
  1175. });
  1176. afterEach(function() {
  1177. App.ajax.send.restore();
  1178. });
  1179. it("App.ajax.send should be called", function() {
  1180. mainServiceItemController.deleteServiceCall('S1');
  1181. expect(App.ajax.send.getCall(0).args[0]).to.eql({
  1182. name : 'service.item.delete',
  1183. sender: mainServiceItemController,
  1184. data : {
  1185. serviceName : 'S1'
  1186. },
  1187. success : 'deleteServiceCallSuccessCallback'
  1188. })
  1189. });
  1190. });
  1191. describe("#deleteServiceCallSuccessCallback()", function() {
  1192. var mainServiceItemController;
  1193. beforeEach(function() {
  1194. mainServiceItemController = App.MainServiceItemController.create({});
  1195. sinon.stub(window.location, 'reload');
  1196. });
  1197. afterEach(function() {
  1198. window.location.reload.restore();
  1199. });
  1200. it("window.location.reload should be called", function() {
  1201. mainServiceItemController.deleteServiceCallSuccessCallback();
  1202. expect(window.location.reload.calledOnce).to.be.true;
  1203. });
  1204. });
  1205. });