service_test.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439
  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/service');
  20. var mainServiceController;
  21. function getController() {
  22. return App.MainServiceController.create({});
  23. }
  24. describe('App.MainServiceController', function () {
  25. var tests = Em.A([
  26. {
  27. isStartStopAllClicked: true,
  28. content: Em.A([
  29. Em.Object.create({
  30. healthStatus: 'red',
  31. serviceName: 'HIVE',
  32. isClientsOnly: false
  33. }),
  34. Em.Object.create({
  35. healthStatus: 'red',
  36. serviceName: 'HDFS',
  37. isClientsOnly: false
  38. }),
  39. Em.Object.create({
  40. healthStatus: 'red',
  41. serviceName: 'TEZ',
  42. isClientsOnly: true
  43. })
  44. ]),
  45. eStart: true,
  46. eStop: true,
  47. mStart: 'mainServiceController StartAll is Disabled 2',
  48. mStop: 'mainServiceController StopAll is Disabled 2'
  49. },
  50. {
  51. isStartStopAllClicked: false,
  52. content: Em.A([
  53. Em.Object.create({
  54. healthStatus: 'green',
  55. serviceName: 'HIVE',
  56. isClientsOnly: false
  57. }),
  58. Em.Object.create({
  59. healthStatus: 'red',
  60. serviceName: 'HDFS',
  61. isClientsOnly: false
  62. }),
  63. Em.Object.create({
  64. healthStatus: 'red',
  65. serviceName: 'TEZ',
  66. isClientsOnly: true
  67. })
  68. ]),
  69. eStart: false,
  70. eStop: false,
  71. mStart: 'mainServiceController StartAll is Enabled 3',
  72. mStop: 'mainServiceController StopAll is Enabled 3'
  73. }
  74. ]);
  75. beforeEach(function() {
  76. mainServiceController = getController();
  77. });
  78. App.TestAliases.testAsComputedNotEqual(getController(), 'isStartStopAllClicked', 'App.router.backgroundOperationsController.allOperationsCount', 0);
  79. describe('#isStartAllDisabled', function () {
  80. tests.forEach(function (test) {
  81. it(test.mStart, function () {
  82. mainServiceController = App.MainServiceController.create({
  83. content: test.content,
  84. isStartStopAllClicked: test.isStartStopAllClicked
  85. });
  86. expect(mainServiceController.get('isStartAllDisabled')).to.equals(test.eStart);
  87. });
  88. });
  89. });
  90. describe('#isStopAllDisabled', function () {
  91. tests.forEach(function (test) {
  92. it(test.mStop, function () {
  93. mainServiceController = App.MainServiceController.create({
  94. content: test.content,
  95. isStartStopAllClicked: test.isStartStopAllClicked
  96. });
  97. expect(mainServiceController.get('isStopAllDisabled')).to.equals(test.eStop);
  98. });
  99. });
  100. });
  101. describe('#cluster', function() {
  102. var tests = Em.A([
  103. {
  104. isLoaded: true,
  105. cluster: [],
  106. m: 'cluster is loaded',
  107. e: {name: 'c1'}
  108. },
  109. {
  110. isLoaded: false,
  111. cluster: [],
  112. m: 'cluster is not loaded',
  113. e: null
  114. }
  115. ]).forEach(function(test) {
  116. describe(test.m, function() {
  117. beforeEach(function () {
  118. sinon.stub(App.router, 'get', function(k) {
  119. if ('clusterController.isClusterDataLoaded' === k) return test.isLoaded;
  120. return Em.get(App.router, k);
  121. });
  122. sinon.stub(App.Cluster, 'find', function() {
  123. return [test.e];
  124. });
  125. });
  126. afterEach(function () {
  127. App.router.get.restore();
  128. App.Cluster.find.restore();
  129. });
  130. it('cluster is valid', function () {
  131. var c = mainServiceController.get('cluster');
  132. expect(c).to.eql(test.e);
  133. });
  134. });
  135. });
  136. });
  137. describe('#startAllService', function() {
  138. beforeEach(function() {
  139. sinon.stub(mainServiceController, 'allServicesCall', Em.K);
  140. });
  141. afterEach(function() {
  142. mainServiceController.allServicesCall.restore();
  143. });
  144. it('target is disabled', function() {
  145. var event = {target: {className: 'disabled', nodeType: 1}};
  146. var r = mainServiceController.startAllService(event);
  147. expect(r).to.be.null;
  148. });
  149. it('parent is disabled', function() {
  150. var event = {target: {parentElement: {className: 'disabled', nodeType: 1}}};
  151. var r = mainServiceController.startAllService(event);
  152. expect(r).to.be.null;
  153. });
  154. it('nothing disabled', function() {
  155. var event = {target: {}}, query = 'query';
  156. mainServiceController.startAllService(event).onPrimary(query);
  157. expect(mainServiceController.allServicesCall.calledWith('STARTED', query));
  158. });
  159. });
  160. describe('#stopAllService', function() {
  161. beforeEach(function() {
  162. sinon.stub(mainServiceController, 'allServicesCall', Em.K);
  163. });
  164. afterEach(function() {
  165. mainServiceController.allServicesCall.restore();
  166. });
  167. it('target is disabled', function() {
  168. var event = {target: {className: 'disabled', nodeType: 1}};
  169. var r = mainServiceController.stopAllService(event);
  170. expect(r).to.be.null;
  171. });
  172. it('parent is disabled', function() {
  173. var event = {target: {parentElement: {className: 'disabled', nodeType: 1}}};
  174. var r = mainServiceController.stopAllService(event);
  175. expect(r).to.be.null;
  176. });
  177. it('nothing disabled', function() {
  178. var event = {target: {}}, query = 'query';
  179. mainServiceController.stopAllService(event).onPrimary(query);
  180. expect(mainServiceController.allServicesCall.calledWith('STARTED', query));
  181. });
  182. });
  183. describe('#startStopAllService', function() {
  184. var event = { target: document.createElement("BUTTON") };
  185. beforeEach(function() {
  186. sinon.stub(mainServiceController, 'allServicesCall', Em.K);
  187. sinon.spy(Em.I18n, "t");
  188. });
  189. afterEach(function() {
  190. mainServiceController.allServicesCall.restore();
  191. Em.I18n.t.restore();
  192. });
  193. it ("should confirm stop if state is INSTALLED", function() {
  194. mainServiceController.startStopAllService(event, "INSTALLED");
  195. expect(Em.I18n.t.calledWith('services.service.stopAll.confirmMsg')).to.be.ok;
  196. expect(Em.I18n.t.calledWith('services.service.stop.confirmButton')).to.be.ok;
  197. });
  198. describe("should check last checkpoint for NN before confirming stop", function() {
  199. var mainServiceItemController;
  200. beforeEach(function() {
  201. mainServiceItemController = App.MainServiceItemController.create({});
  202. sinon.stub(mainServiceItemController, 'checkNnLastCheckpointTime', function() {
  203. return true;
  204. });
  205. sinon.stub(App.router, 'get', function(k) {
  206. if ('mainServiceItemController' === k) {
  207. return mainServiceItemController;
  208. }
  209. return Em.get(App.router, k);
  210. });
  211. sinon.stub(App.Service, 'find', function() {
  212. return [{
  213. serviceName: "HDFS",
  214. workStatus: "STARTED"
  215. }];
  216. });
  217. });
  218. afterEach(function () {
  219. mainServiceItemController.checkNnLastCheckpointTime.restore();
  220. App.router.get.restore();
  221. App.Service.find.restore();
  222. });
  223. it('checkNnLastCheckpointTime is called once', function () {
  224. mainServiceController.startStopAllService(event, "INSTALLED");
  225. expect(mainServiceItemController.checkNnLastCheckpointTime.calledOnce).to.equal(true);
  226. });
  227. });
  228. it ("should confirm start if state is not INSTALLED", function() {
  229. mainServiceController.startStopAllService(event, "STARTED");
  230. expect(Em.I18n.t.calledWith('services.service.startAll.confirmMsg')).to.be.ok;
  231. expect(Em.I18n.t.calledWith('services.service.start.confirmButton')).to.be.ok;
  232. });
  233. });
  234. describe('#allServicesCall', function() {
  235. var state = 'STARTED',
  236. query = 'some query';
  237. beforeEach(function() {
  238. sinon.stub($, 'ajax', Em.K);
  239. sinon.stub(App, 'get', function(k) {
  240. if ('testMode' === k) return false;
  241. if ('clusterName' === k) return 'tdk';
  242. return Em.get(App, k);
  243. });
  244. mainServiceController.allServicesCall(state, query);
  245. this.params = $.ajax.args[0][0];
  246. this.data = JSON.parse(this.params.data);
  247. });
  248. afterEach(function() {
  249. $.ajax.restore();
  250. App.get.restore();
  251. });
  252. it('PUT request is sent', function() {
  253. expect(this.params.type).to.equal('PUT');
  254. });
  255. it('request is sent to `/services`', function() {
  256. expect(this.params.url.contains('/clusters/tdk/services?')).to.be.true;
  257. });
  258. it('Body.ServiceInfo.state is ' + state, function() {
  259. expect(this.data.Body.ServiceInfo.state).to.equal(state);
  260. });
  261. it('RequestInfo.context is ' + query, function() {
  262. expect(this.data.RequestInfo.context).to.equal(App.BackgroundOperationsController.CommandContexts.START_ALL_SERVICES);
  263. });
  264. });
  265. describe('#allServicesCallErrorCallback', function() {
  266. it('should set status to FAIL', function() {
  267. var params = {query: Em.Object.create({status: ''})};
  268. mainServiceController.allServicesCallErrorCallback({}, {}, '', {}, params);
  269. expect(params.query.get('status')).to.equal('FAIL');
  270. });
  271. });
  272. describe('#gotoAddService', function() {
  273. beforeEach(function() {
  274. sinon.stub(App.router, 'transitionTo', Em.K);
  275. });
  276. afterEach(function() {
  277. App.router.transitionTo.restore();
  278. });
  279. it('should not go to wizard', function() {
  280. mainServiceController.reopen({isAllServicesInstalled: true});
  281. mainServiceController.gotoAddService();
  282. expect(App.router.transitionTo.called).to.be.false;
  283. });
  284. it('should go to wizard', function() {
  285. mainServiceController.reopen({isAllServicesInstalled: false});
  286. mainServiceController.gotoAddService();
  287. expect(App.router.transitionTo.calledWith('main.serviceAdd')).to.be.true;
  288. });
  289. });
  290. App.TestAliases.testAsComputedEveryBy(getController(), 'isRestartAllRequiredDisabled', 'content', 'isRestartRequired', false);
  291. describe('#restartAllRequired', function () {
  292. beforeEach(function () {
  293. sinon.spy(App, 'showConfirmationPopup');
  294. sinon.spy(mainServiceController, 'restartHostComponents');
  295. sinon.stub(App.HostComponent, 'find', function() {
  296. return [
  297. Em.Object.create({
  298. componentName: 'componentName1',
  299. hostName: 'hostName1',
  300. service: {
  301. serviceName: 'serviceName1',
  302. displayName: 'displayName1'
  303. },
  304. staleConfigs: true
  305. }),
  306. Em.Object.create({
  307. componentName: 'componentName2',
  308. hostName: 'hostName2',
  309. service: {
  310. serviceName: 'serviceName2',
  311. displayName: 'displayName2'
  312. },
  313. staleConfigs: true
  314. }),
  315. Em.Object.create({
  316. componentName: 'componentName3',
  317. hostName: 'hostName3',
  318. service: {
  319. serviceName: 'serviceName3',
  320. displayName: 'displayName3'
  321. },
  322. staleConfigs: false
  323. })
  324. ];
  325. });
  326. });
  327. afterEach(function () {
  328. App.HostComponent.find.restore();
  329. App.showConfirmationPopup.restore();
  330. mainServiceController.restartHostComponents.restore();
  331. });
  332. it('should show confirmation popup with list of services and call restartHostComponents after confirmation', function () {
  333. var popup;
  334. mainServiceController.reopen({
  335. isRestartAllRequiredDisabled: false
  336. });
  337. popup = mainServiceController.restartAllRequired();
  338. popup.onPrimary();
  339. expect(App.showConfirmationPopup.args[0][1]).to.equal(Em.I18n.t('services.service.refreshAll.confirmMsg').format('displayName1, displayName2'));
  340. expect(mainServiceController.restartHostComponents.calledWith([
  341. {
  342. component_name: 'componentName1',
  343. service_name: 'serviceName1',
  344. hosts: 'hostName1'
  345. },
  346. {
  347. component_name: 'componentName2',
  348. service_name: 'serviceName2',
  349. hosts: 'hostName2'
  350. }
  351. ])).to.be.true;
  352. });
  353. it('should not open popup if isRestartAllRequiredDisabled is true', function(){
  354. mainServiceController.reopen({
  355. isRestartAllRequiredDisabled: true
  356. });
  357. expect(mainServiceController.restartAllRequired()).to.be.null;
  358. });
  359. });
  360. describe('#restartHostComponents', function () {
  361. beforeEach(function () {
  362. sinon.stub(App.ajax, 'send', Em.K);
  363. });
  364. afterEach(function () {
  365. App.ajax.send.restore();
  366. });
  367. it('should send ajax request', function () {
  368. mainServiceController.restartHostComponents();
  369. expect(App.ajax.send.calledOnce).to.be.true;
  370. });
  371. });
  372. });