config_test.js 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158
  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('config');
  20. require('utils/config');
  21. require('models/service/hdfs');
  22. var setups = require('test/init_model_test');
  23. var modelSetup = setups.configs;
  24. describe('App.config', function () {
  25. describe('#fileConfigsIntoTextarea', function () {
  26. var filename = 'capacity-scheduler.xml';
  27. var configs = [
  28. {
  29. name: 'config1',
  30. value: 'value1',
  31. recommendedValue: 'value1',
  32. filename: 'capacity-scheduler.xml'
  33. },
  34. {
  35. name: 'config2',
  36. value: 'value2',
  37. recommendedValue: 'value2',
  38. filename: 'capacity-scheduler.xml'
  39. }
  40. ];
  41. it('two configs into textarea', function () {
  42. var result = App.config.fileConfigsIntoTextarea.call(App.config, configs, filename);
  43. expect(result.length).to.equal(1);
  44. expect(result[0].value).to.equal('config1=value1\nconfig2=value2\n');
  45. expect(result[0].recommendedValue).to.equal('config1=value1\nconfig2=value2\n');
  46. });
  47. it('three config into textarea', function () {
  48. configs.push({
  49. name: 'config3',
  50. value: 'value3',
  51. recommendedValue: 'value3',
  52. filename: 'capacity-scheduler.xml'
  53. });
  54. var result = App.config.fileConfigsIntoTextarea.call(App.config, configs, filename);
  55. expect(result.length).to.equal(1);
  56. expect(result[0].value).to.equal('config1=value1\nconfig2=value2\nconfig3=value3\n');
  57. expect(result[0].recommendedValue).to.equal('config1=value1\nconfig2=value2\nconfig3=value3\n');
  58. });
  59. it('one of three configs has different filename', function () {
  60. configs[1].filename = 'another filename';
  61. var result = App.config.fileConfigsIntoTextarea.call(App.config, configs, filename);
  62. //result contains two configs: one with different filename and one textarea config
  63. expect(result.length).to.equal(2);
  64. expect(result[1].value).to.equal('config1=value1\nconfig3=value3\n');
  65. expect(result[1].recommendedValue).to.equal('config1=value1\nconfig3=value3\n');
  66. });
  67. it('none configs into empty textarea', function () {
  68. filename = 'capacity-scheduler.xml';
  69. configs.clear();
  70. var result = App.config.fileConfigsIntoTextarea.call(App.config, configs, filename);
  71. expect(result.length).to.equal(1);
  72. expect(result[0].value).to.equal('');
  73. expect(Em.isNone(result[0].recommendedValue)).to.be.true;
  74. expect(Em.isNone(result[0].savedValue)).to.be.true;
  75. });
  76. it("filename has configs that shouldn't be included in textarea", function () {
  77. var configs = [
  78. {
  79. name: 'config1',
  80. value: 'value1',
  81. recommendedValue: 'value1',
  82. filename: filename
  83. },
  84. {
  85. name: 'config2',
  86. value: 'value2',
  87. recommendedValue: 'value2',
  88. filename: filename
  89. }
  90. ];
  91. var cfg = {
  92. name: 'config3',
  93. value: 'value3',
  94. recommendedValue: 'value3',
  95. filename: filename
  96. };
  97. configs.push(cfg);
  98. var result = App.config.fileConfigsIntoTextarea.call(App.config, configs, filename, [cfg]);
  99. expect(result.length).to.equal(2);
  100. expect(result[1].value).to.equal('config1=value1\nconfig2=value2\n');
  101. expect(result[1].recommendedValue).to.equal('config1=value1\nconfig2=value2\n');
  102. expect(configs.findProperty('name', 'config3')).to.eql(cfg);
  103. });
  104. });
  105. describe('#textareaIntoFileConfigs', function () {
  106. var filename = 'capacity-scheduler.xml';
  107. var testData = [
  108. {
  109. configs: [Em.Object.create({
  110. "name": "capacity-scheduler",
  111. "value": "config1=value1",
  112. "filename": "capacity-scheduler.xml",
  113. "isRequiredByAgent": true
  114. })]
  115. },
  116. {
  117. configs: [Em.Object.create({
  118. "name": "capacity-scheduler",
  119. "value": "config1=value1\nconfig2=value2\n",
  120. "filename": "capacity-scheduler.xml",
  121. "isRequiredByAgent": false
  122. })]
  123. },
  124. {
  125. configs: [Em.Object.create({
  126. "name": "capacity-scheduler",
  127. "value": "config1=value1,value2\n",
  128. "filename": "capacity-scheduler.xml",
  129. "isRequiredByAgent": true
  130. })]
  131. },
  132. {
  133. configs: [Em.Object.create({
  134. "name": "capacity-scheduler",
  135. "value": "config1=value1 config2=value2\n",
  136. "filename": "capacity-scheduler.xml",
  137. "isRequiredByAgent": false
  138. })]
  139. }
  140. ];
  141. it('config1=value1 to one config', function () {
  142. var result = App.config.textareaIntoFileConfigs.call(App.config, testData[0].configs, filename);
  143. expect(result.length).to.equal(1);
  144. expect(result[0].value).to.equal('value1');
  145. expect(result[0].name).to.equal('config1');
  146. expect(result[0].isRequiredByAgent).to.be.true;
  147. });
  148. it('config1=value1\\nconfig2=value2\\n to two configs', function () {
  149. var result = App.config.textareaIntoFileConfigs.call(App.config, testData[1].configs, filename);
  150. expect(result.length).to.equal(2);
  151. expect(result[0].value).to.equal('value1');
  152. expect(result[0].name).to.equal('config1');
  153. expect(result[1].value).to.equal('value2');
  154. expect(result[1].name).to.equal('config2');
  155. expect(result[0].isRequiredByAgent).to.be.false;
  156. expect(result[1].isRequiredByAgent).to.be.false;
  157. });
  158. it('config1=value1,value2\n to one config', function () {
  159. var result = App.config.textareaIntoFileConfigs.call(App.config, testData[2].configs, filename);
  160. expect(result.length).to.equal(1);
  161. expect(result[0].value).to.equal('value1,value2');
  162. expect(result[0].name).to.equal('config1');
  163. expect(result[0].isRequiredByAgent).to.be.true;
  164. });
  165. it('config1=value1 config2=value2 to two configs', function () {
  166. var result = App.config.textareaIntoFileConfigs.call(App.config, testData[3].configs, filename);
  167. expect(result.length).to.equal(1);
  168. expect(result[0].isRequiredByAgent).to.be.false;
  169. });
  170. });
  171. describe('#trimProperty',function() {
  172. var testMessage = 'displayType `{0}`, value `{1}`{3} should return `{2}`';
  173. var tests = [
  174. {
  175. config: {
  176. displayType: 'directory',
  177. value: ' /a /b /c'
  178. },
  179. e: '/a,/b,/c'
  180. },
  181. {
  182. config: {
  183. displayType: 'directories',
  184. value: ' /a /b '
  185. },
  186. e: '/a,/b'
  187. },
  188. {
  189. config: {
  190. displayType: 'directories',
  191. name: 'dfs.datanode.data.dir',
  192. value: ' [DISK]/a [SSD]/b '
  193. },
  194. e: '[DISK]/a,[SSD]/b'
  195. },
  196. {
  197. config: {
  198. displayType: 'directories',
  199. name: 'dfs.datanode.data.dir',
  200. value: '/a,/b, /c\n/d,\n/e /f'
  201. },
  202. e: '/a,/b,/c,/d,/e,/f'
  203. },
  204. {
  205. config: {
  206. displayType: 'host',
  207. value: ' localhost '
  208. },
  209. e: 'localhost'
  210. },
  211. {
  212. config: {
  213. displayType: 'password',
  214. value: ' passw ord '
  215. },
  216. e: ' passw ord '
  217. },
  218. {
  219. config: {
  220. displayType: 'string',
  221. value: ' value'
  222. },
  223. e: ' value'
  224. },
  225. {
  226. config: {
  227. displayType: 'string',
  228. value: ' value'
  229. },
  230. e: ' value'
  231. },
  232. {
  233. config: {
  234. displayType: 'string',
  235. value: 'http://localhost ',
  236. name: 'javax.jdo.option.ConnectionURL'
  237. },
  238. e: 'http://localhost'
  239. },
  240. {
  241. config: {
  242. displayType: 'string',
  243. value: 'http://localhost ',
  244. name: 'oozie.service.JPAService.jdbc.url'
  245. },
  246. e: 'http://localhost'
  247. },
  248. {
  249. config: {
  250. displayType: 'custom',
  251. value: ' custom value '
  252. },
  253. e: ' custom value'
  254. },
  255. {
  256. config: {
  257. displayType: 'componentHosts',
  258. value: ['host1.com', 'host2.com']
  259. },
  260. e: ['host1.com', 'host2.com']
  261. }
  262. ];
  263. tests.forEach(function(test) {
  264. it(testMessage.format(test.config.displayType, test.config.value, test.e, !!test.config.name ? ', name `' + test.config.name + '`' : ''), function() {
  265. expect(App.config.trimProperty(test.config)).to.eql(test.e);
  266. expect(App.config.trimProperty(Em.Object.create(test.config), true)).to.eql(test.e);
  267. });
  268. });
  269. });
  270. describe('#preDefinedConfigFile', function() {
  271. before(function() {
  272. setups.setupStackVersion(this, 'BIGTOP-0.8');
  273. });
  274. it('bigtop site properties should be ok.', function() {
  275. var bigtopSiteProperties = App.config.preDefinedConfigFile('BIGTOP', 'site_properties');
  276. expect(bigtopSiteProperties).to.be.ok;
  277. });
  278. it('a non-existing file should not be ok.', function () {
  279. var notExistingSiteProperty = App.config.preDefinedConfigFile('notExisting');
  280. expect(notExistingSiteProperty).to.not.be.ok;
  281. });
  282. after(function() {
  283. setups.restoreStackVersion(this);
  284. });
  285. });
  286. describe('#preDefinedSiteProperties-bigtop', function () {
  287. before(function() {
  288. setups.setupStackVersion(this, 'BIGTOP-0.8');
  289. });
  290. it('bigtop should use New PostgreSQL Database as its default hive metastore database', function () {
  291. App.StackService.createRecord({serviceName: 'HIVE'});
  292. expect(App.config.get('preDefinedSiteProperties').findProperty('recommendedValue', 'New PostgreSQL Database')).to.be.ok;
  293. });
  294. after(function() {
  295. setups.restoreStackVersion(this);
  296. });
  297. });
  298. describe('#generateConfigPropertiesByName', function() {
  299. var tests = [
  300. {
  301. names: ['property_1', 'property_2'],
  302. properties: undefined,
  303. e: {
  304. keys: ['name']
  305. },
  306. m: 'Should generate base property object without additional fields'
  307. },
  308. {
  309. names: ['property_1', 'property_2'],
  310. properties: { category: 'SomeCat', serviceName: 'SERVICE_NAME' },
  311. e: {
  312. keys: ['name', 'category', 'serviceName']
  313. },
  314. m: 'Should generate base property object without additional fields'
  315. }
  316. ];
  317. tests.forEach(function(test) {
  318. it(test.m, function() {
  319. expect(App.config.generateConfigPropertiesByName(test.names, test.properties).length).to.eql(test.names.length);
  320. expect(App.config.generateConfigPropertiesByName(test.names, test.properties).map(function(property) {
  321. return Em.keys(property);
  322. }).reduce(function(p, c) {
  323. return p.concat(c);
  324. }).uniq()).to.eql(test.e.keys);
  325. });
  326. });
  327. });
  328. describe('#setPreDefinedServiceConfigs', function() {
  329. beforeEach(function() {
  330. sinon.stub(App.StackService, 'find', function() {
  331. return [
  332. Em.Object.create({
  333. id: 'HDFS',
  334. serviceName: 'HDFS',
  335. configTypes: {
  336. 'hadoop-env': {},
  337. 'hdfs-site': {}
  338. }
  339. }),
  340. Em.Object.create({
  341. id: 'OOZIE',
  342. serviceName: 'OOZIE',
  343. configTypes: {
  344. 'oozie-env': {},
  345. 'oozie-site': {}
  346. }
  347. })
  348. ];
  349. });
  350. App.config.setPreDefinedServiceConfigs(true);
  351. });
  352. afterEach(function() {
  353. App.StackService.find.restore();
  354. });
  355. it('should include service MISC', function() {
  356. expect(App.config.get('preDefinedServiceConfigs').findProperty('serviceName', 'MISC')).to.be.ok;
  357. });
  358. it('should include -env config types according to stack services', function() {
  359. var miscCategory = App.config.get('preDefinedServiceConfigs').findProperty('serviceName', 'MISC');
  360. expect(Em.keys(miscCategory.get('configTypes'))).to.eql(['cluster-env', 'hadoop-env', 'oozie-env']);
  361. });
  362. it('should not load configs for missed config types', function() {
  363. var hdfsService = App.config.get('preDefinedServiceConfigs').findProperty('serviceName', 'HDFS');
  364. var rangerRelatedConfigs = hdfsService.get('configs').filterProperty('filename', 'ranger-hdfs-plugin-properties.xml');
  365. expect(rangerRelatedConfigs.length).to.be.eql(0);
  366. expect(hdfsService.get('configs.length') > 0).to.be.true;
  367. });
  368. });
  369. describe('#isManagedMySQLForHiveAllowed', function () {
  370. var cases = [
  371. {
  372. osFamily: 'redhat5',
  373. expected: false
  374. },
  375. {
  376. osFamily: 'redhat6',
  377. expected: true
  378. },
  379. {
  380. osFamily: 'suse11',
  381. expected: false
  382. }
  383. ],
  384. title = 'should be {0} for {1}';
  385. cases.forEach(function (item) {
  386. it(title.format(item.expected, item.osFamily), function () {
  387. expect(App.config.isManagedMySQLForHiveAllowed(item.osFamily)).to.equal(item.expected);
  388. });
  389. });
  390. });
  391. describe('#advancedConfigIdentityData', function () {
  392. var configs = [
  393. {
  394. input: {
  395. property_type: ['USER'],
  396. property_name: 'hdfs_user'
  397. },
  398. output: {
  399. category: 'Users and Groups',
  400. isVisible: true,
  401. serviceName: 'MISC',
  402. displayType: 'user',
  403. index: 30
  404. },
  405. title: 'user, no service name specified, default display name behaviour'
  406. },
  407. {
  408. input: {
  409. property_type: ['GROUP'],
  410. property_name: 'knox_group',
  411. service_name: 'KNOX'
  412. },
  413. output: {
  414. category: 'Users and Groups',
  415. isVisible: true,
  416. serviceName: 'MISC',
  417. displayType: 'user',
  418. index: 0
  419. },
  420. title: 'group, service_name = KNOX, default display name behaviour'
  421. },
  422. {
  423. input: {
  424. property_type: ['USER']
  425. },
  426. output: {
  427. isVisible: false
  428. },
  429. isHDPWIN: true,
  430. title: 'HDPWIN stack'
  431. },
  432. {
  433. input: {
  434. property_type: ['USER'],
  435. property_name: 'smokeuser',
  436. service_name: 'MISC'
  437. },
  438. output: {
  439. serviceName: 'MISC',
  440. belongsToService: ['MISC'],
  441. index: 30
  442. },
  443. title: 'smokeuser, service_name = MISC'
  444. },
  445. {
  446. input: {
  447. property_type: ['USER'],
  448. property_name: 'ignore_groupsusers_create'
  449. },
  450. output: {
  451. displayType: 'boolean'
  452. },
  453. title: 'ignore_groupsusers_create'
  454. },
  455. {
  456. input: {
  457. property_type: ['GROUP'],
  458. property_name: 'proxyuser_group'
  459. },
  460. output: {
  461. belongsToService: ['HIVE', 'OOZIE', 'FALCON']
  462. },
  463. title: 'proxyuser_group'
  464. },
  465. {
  466. input: {
  467. property_type: ['PASSWORD'],
  468. property_name: 'javax.jdo.option.ConnectionPassword'
  469. },
  470. output: {
  471. displayType: 'password'
  472. },
  473. title: 'password'
  474. }
  475. ];
  476. before(function () {
  477. sinon.stub(App.StackService, 'find').returns([
  478. {
  479. serviceName: 'KNOX'
  480. }
  481. ]);
  482. });
  483. afterEach(function () {
  484. App.get.restore();
  485. });
  486. after(function () {
  487. App.StackService.find.restore();
  488. });
  489. configs.forEach(function (item) {
  490. it(item.title, function () {
  491. sinon.stub(App, 'get').withArgs('isHadoopWindowsStack').returns(Boolean(item.isHDPWIN));
  492. var propertyData = App.config.advancedConfigIdentityData(item.input);
  493. Em.keys(item.output).forEach(function (key) {
  494. expect(propertyData[key]).to.eql(item.output[key]);
  495. });
  496. });
  497. });
  498. });
  499. describe('#shouldSupportFinal', function () {
  500. var cases = [
  501. {
  502. shouldSupportFinal: false,
  503. title: 'no service name specified'
  504. },
  505. {
  506. serviceName: 's0',
  507. shouldSupportFinal: false,
  508. title: 'no filename specified'
  509. },
  510. {
  511. serviceName: 'MISC',
  512. shouldSupportFinal: false,
  513. title: 'MISC'
  514. },
  515. {
  516. serviceName: 's0',
  517. filename: 's0-site',
  518. shouldSupportFinal: true,
  519. title: 'final attribute supported'
  520. },
  521. {
  522. serviceName: 's0',
  523. filename: 's0-env',
  524. shouldSupportFinal: false,
  525. title: 'final attribute not supported'
  526. },
  527. {
  528. serviceName: 'Cluster',
  529. filename: 'krb5-conf.xml',
  530. shouldSupportFinal: false,
  531. title: 'kerberos descriptor identities don\'t support final'
  532. }
  533. ];
  534. beforeEach(function () {
  535. sinon.stub(App.StackService, 'find').returns([
  536. {
  537. serviceName: 's0'
  538. }
  539. ]);
  540. sinon.stub(App.config, 'getConfigTypesInfoFromService').returns({
  541. supportsFinal: ['s0-site']
  542. });
  543. });
  544. afterEach(function () {
  545. App.StackService.find.restore();
  546. App.config.getConfigTypesInfoFromService.restore();
  547. });
  548. cases.forEach(function (item) {
  549. it(item.title, function () {
  550. expect(App.config.shouldSupportFinal(item.serviceName, item.filename)).to.equal(item.shouldSupportFinal);
  551. });
  552. });
  553. });
  554. describe('#removeRangerConfigs', function () {
  555. it('should remove ranger configs and categories', function () {
  556. var configs = [
  557. Em.Object.create({
  558. configs: [
  559. Em.Object.create({filename: 'filename'}),
  560. Em.Object.create({filename: 'ranger-filename'})
  561. ],
  562. configCategories: [
  563. Em.Object.create({name: 'ranger-name'}),
  564. Em.Object.create({name: 'name'}),
  565. Em.Object.create({name: 'also-ranger-name'})
  566. ]
  567. })
  568. ];
  569. App.config.removeRangerConfigs(configs);
  570. expect(configs).eql(
  571. [
  572. Em.Object.create({
  573. configs: [
  574. Em.Object.create({filename: 'filename'})
  575. ],
  576. configCategories: [
  577. Em.Object.create({name: 'name'})
  578. ]
  579. })
  580. ]
  581. );
  582. });
  583. });
  584. describe("#createOverride", function() {
  585. var template = {
  586. name: "p1",
  587. filename: "f1",
  588. value: "v1",
  589. recommendedValue: "rv1",
  590. savedValue: "sv1",
  591. isFinal: true,
  592. recommendedIsFinal: false,
  593. savedIsFinal: true
  594. };
  595. var configProperty = App.ServiceConfigProperty.create(template);
  596. var group = Em.Object.create({name: "group1"});
  597. it('creates override with save properties as original config', function() {
  598. var override = App.config.createOverride(configProperty, {}, group);
  599. for (var key in template) {
  600. expect(override.get(key)).to.eql(template[key]);
  601. }
  602. });
  603. it('overrides some values that should be different for override', function() {
  604. var override = App.config.createOverride(configProperty, {}, group);
  605. expect(override.get('isOriginalSCP')).to.be.false;
  606. expect(override.get('overrides')).to.be.null;
  607. expect(override.get('group')).to.eql(group);
  608. expect(override.get('parentSCP')).to.eql(configProperty);
  609. });
  610. it('overrides some specific values', function() {
  611. var overridenTemplate = {
  612. value: "v2",
  613. recommendedValue: "rv2",
  614. savedValue: "sv2",
  615. isFinal: true,
  616. recommendedIsFinal: false,
  617. savedIsFinal: true
  618. };
  619. var override = App.config.createOverride(configProperty, overridenTemplate, group);
  620. for (var key in overridenTemplate) {
  621. expect(override.get(key)).to.eql(overridenTemplate[key]);
  622. }
  623. });
  624. it('throws error due to undefined configGroup', function() {
  625. expect(App.config.createOverride.bind(App.config, configProperty, {}, null)).to.throw(Error, 'configGroup can\' be null');
  626. });
  627. it('throws error due to undefined originalSCP', function() {
  628. expect(App.config.createOverride.bind(App.config, null, {}, group)).to.throw(Error, 'serviceConfigProperty can\' be null');
  629. });
  630. it('updates originalSCP object ', function() {
  631. configProperty.set('overrides', null);
  632. configProperty.set('overrideValues', []);
  633. configProperty.set('overrideIsFinalValues', []);
  634. var overridenTemplate2 = {
  635. value: "v12",
  636. recommendedValue: "rv12",
  637. savedValue: "sv12",
  638. isFinal: true,
  639. recommendedIsFinal: false,
  640. savedIsFinal: false
  641. };
  642. var override = App.config.createOverride(configProperty, overridenTemplate2, group);
  643. expect(configProperty.get('overrides')[0]).to.be.eql(override);
  644. expect(configProperty.get('overrideValues')).to.be.eql([overridenTemplate2.value]);
  645. expect(configProperty.get('overrideIsFinalValues')).to.be.eql([overridenTemplate2.isFinal]);
  646. });
  647. });
  648. describe('#getIsEditable', function() {
  649. [{
  650. isDefaultGroup: true,
  651. isReconfigurable: true,
  652. canEdit: true,
  653. res: true,
  654. m: "isEditable is true"
  655. },
  656. {
  657. isDefaultGroup: false,
  658. isReconfigurable: true,
  659. canEdit: true,
  660. res: false,
  661. m: "isEditable is false; config group is not default"
  662. },
  663. {
  664. isDefaultGroup: true,
  665. isReconfigurable: false,
  666. canEdit: true,
  667. res: false,
  668. m: "isEditable is true; config is not reconfigurable"
  669. },
  670. {
  671. isDefaultGroup: true,
  672. isReconfigurable: true,
  673. canEdit: false,
  674. res: false,
  675. m: "isEditable is true; edition restricted by controller state"
  676. }].forEach(function(t) {
  677. it(t.m, function() {
  678. var configProperty = Ember.Object.create({isReconfigurable: t.isReconfigurable});
  679. var configGroup = Ember.Object.create({isDefault: t.isDefaultGroup});
  680. var isEditable = App.config.getIsEditable(configProperty, configGroup, t.canEdit);
  681. expect(isEditable).to.equal(t.res);
  682. })
  683. });
  684. });
  685. describe('#getIsSecure', function() {
  686. var secureConfigs = App.config.get('secureConfigs');
  687. before(function() {
  688. App.config.set('secureConfigs', [{name: 'secureConfig'}]);
  689. });
  690. after(function() {
  691. App.config.set('secureConfigs', secureConfigs);
  692. });
  693. it('config is secure', function() {
  694. expect(App.config.getIsSecure('secureConfig')).to.equal(true);
  695. });
  696. it('config is not secure', function() {
  697. expect(App.config.getIsSecure('NotSecureConfig')).to.equal(false);
  698. });
  699. });
  700. describe('#getDefaultCategory', function() {
  701. it('returns custom category', function() {
  702. expect(App.config.getDefaultCategory(null, 'filename.xml')).to.equal('Custom filename');
  703. });
  704. it('returns advanced category', function() {
  705. expect(App.config.getDefaultCategory(Em.Object.create, 'filename.xml')).to.equal('Advanced filename');
  706. });
  707. });
  708. describe('#getDefaultDisplayType', function() {
  709. it('returns content displayType', function() {
  710. sinon.stub(App.config, 'isContentProperty', function () {return true});
  711. expect(App.config.getDefaultDisplayType('content','f1','anything')).to.equal('content');
  712. App.config.isContentProperty.restore();
  713. });
  714. it('returns singleLine displayType', function() {
  715. sinon.stub(App.config, 'isContentProperty', function () {return false});
  716. expect(App.config.getDefaultDisplayType('n1','f1','v1')).to.equal('string');
  717. App.config.isContentProperty.restore();
  718. });
  719. it('returns multiLine displayType', function() {
  720. sinon.stub(App.config, 'isContentProperty', function () {return false});
  721. expect(App.config.getDefaultDisplayType('n2', 'f2', 'v1\nv2')).to.equal('multiLine');
  722. App.config.isContentProperty.restore();
  723. });
  724. it('returns custom displayType for FALCON oozie-site properties', function() {
  725. sinon.stub(App.config, 'isContentProperty', function () {return false});
  726. expect(App.config.getDefaultDisplayType('n2', 'oozie-site.xml', 'v1\nv2', 'FALCON')).to.equal('custom');
  727. App.config.isContentProperty.restore();
  728. });
  729. });
  730. describe('#getDefaultDisplayName', function() {
  731. beforeEach(function() {
  732. sinon.stub(App.config, 'getConfigTagFromFileName', function(fName) {return fName} );
  733. });
  734. afterEach(function() {
  735. App.config.getConfigTagFromFileName.restore();
  736. });
  737. it('returns name', function() {
  738. sinon.stub(App.config, 'isContentProperty', function() {return false} );
  739. expect(App.config.getDefaultDisplayName('name')).to.equal('name');
  740. App.config.isContentProperty.restore();
  741. });
  742. it('returns name for env content', function() {
  743. sinon.stub(App.config, 'isContentProperty', function() {return true} );
  744. expect(App.config.getDefaultDisplayName('name', 'fileName')).to.equal('fileName template');
  745. App.config.isContentProperty.restore();
  746. });
  747. });
  748. describe('#isContentProperty', function() {
  749. beforeEach(function() {
  750. sinon.stub(App.config, 'getConfigTagFromFileName', function(fName) {return fName} );
  751. });
  752. afterEach(function() {
  753. App.config.getConfigTagFromFileName.restore();
  754. });
  755. var tests = [
  756. {
  757. name: 'content',
  758. fileName: 'something-env',
  759. tagEnds: null,
  760. res: true,
  761. m: 'returns true as it\'s content property'
  762. },
  763. {
  764. name: 'content',
  765. fileName: 'something-any-end',
  766. tagEnds: ['-any-end'],
  767. res: true,
  768. m: 'returns true as it\'s content property with specific fileName ending'
  769. },
  770. {
  771. name: 'notContent',
  772. fileName: 'something-env',
  773. tagEnds: ['-env'],
  774. res: false,
  775. m: 'returns false as name is not content'
  776. },
  777. {
  778. name: 'content',
  779. fileName: 'something-env1',
  780. tagEnds: ['-env'],
  781. res: false,
  782. m: 'returns false as fileName is not correct'
  783. }
  784. ].forEach(function(t) {
  785. it(t.m, function() {
  786. expect(App.config.isContentProperty(t.name, t.fileName, t.tagEnds)).to.equal(t.res);
  787. });
  788. });
  789. });
  790. describe('#formatValue', function() {
  791. it('formatValue for componentHosts', function () {
  792. var serviceConfigProperty = Em.Object.create({'displayType': 'componentHosts', value: "['h1','h2']"});
  793. expect(App.config.formatPropertyValue(serviceConfigProperty)).to.eql(['h1','h2']);
  794. });
  795. it('formatValue for int', function () {
  796. var serviceConfigProperty = Em.Object.create({'displayType': 'int', value: '4.0'});
  797. expect(App.config.formatPropertyValue(serviceConfigProperty)).to.equal('4');
  798. });
  799. it('formatValue for int with m', function () {
  800. var serviceConfigProperty = Em.Object.create({'displayType': 'int', value: '4m'});
  801. expect(App.config.formatPropertyValue(serviceConfigProperty)).to.equal('4');
  802. });
  803. it('formatValue for float', function () {
  804. var serviceConfigProperty = Em.Object.create({'displayType': 'float', value: '0.40'});
  805. expect(App.config.formatPropertyValue(serviceConfigProperty)).to.equal('0.4');
  806. });
  807. it('formatValue for kdc_type', function () {
  808. var serviceConfigProperty = Em.Object.create({'name': 'kdc_type', value: 'mit-kdc'});
  809. expect(App.config.formatPropertyValue(serviceConfigProperty)).to.equal(Em.I18n.t('admin.kerberos.wizard.step1.option.kdc'));
  810. });
  811. it('don\'t format value', function () {
  812. var serviceConfigProperty = Em.Object.create({'name': 'any', displayType: 'any', value: 'any'});
  813. expect(App.config.formatPropertyValue(serviceConfigProperty)).to.equal('any');
  814. });
  815. });
  816. describe('#getPropertyIfExists', function() {
  817. [
  818. {
  819. propertyName: 'someProperty',
  820. defaultValue: 'default',
  821. firstObject: { someProperty: '1' },
  822. secondObject: { someProperty: '2' },
  823. res: '1',
  824. m: 'use value from first object'
  825. },
  826. {
  827. propertyName: 'someProperty',
  828. defaultValue: 'default',
  829. firstObject: { someOtherProperty: '1' },
  830. secondObject: { someProperty: '2' },
  831. res: '2',
  832. m: 'use value from second object'
  833. },
  834. {
  835. propertyName: 'someProperty',
  836. defaultValue: 'default',
  837. firstObject: { someOtherProperty: '1' },
  838. secondObject: { someOtherProperty: '2' },
  839. res: 'default',
  840. m: 'use default value'
  841. },
  842. {
  843. propertyName: 'someProperty',
  844. defaultValue: 'default',
  845. res: 'default',
  846. m: 'use default value'
  847. },
  848. {
  849. propertyName: 'someProperty',
  850. defaultValue: true,
  851. firstObject: { someProperty: false },
  852. secondObject: { someProperty: true },
  853. res: false,
  854. m: 'use value from first object, check booleans'
  855. },
  856. {
  857. propertyName: 'someProperty',
  858. defaultValue: true,
  859. firstObject: { someProperty: 0 },
  860. secondObject: { someProperty: 1 },
  861. res: 0,
  862. m: 'use value from first object, check 0'
  863. },
  864. {
  865. propertyName: 'someProperty',
  866. defaultValue: true,
  867. firstObject: { someProperty: '' },
  868. secondObject: { someProperty: '1' },
  869. res: '',
  870. m: 'use value from first object, check empty string'
  871. }
  872. ].forEach(function (t) {
  873. it(t.m, function () {
  874. expect(App.config.getPropertyIfExists(t.propertyName, t.defaultValue, t.firstObject, t.secondObject)).to.equal(t.res);
  875. })
  876. });
  877. });
  878. describe('#createDefaultConfig', function() {
  879. before(function() {
  880. sinon.stub(App.config, 'getDefaultDisplayName', function() {
  881. return 'pDisplayName';
  882. });
  883. sinon.stub(App.config, 'getDefaultDisplayType', function() {
  884. return 'pDisplayType';
  885. });
  886. sinon.stub(App.config, 'getDefaultCategory', function() {
  887. return 'pCategory';
  888. });
  889. sinon.stub(App.config, 'getIsSecure', function() {
  890. return false;
  891. });
  892. sinon.stub(App.config, 'shouldSupportFinal', function() {
  893. return true;
  894. });
  895. });
  896. after(function() {
  897. App.config.getDefaultDisplayName.restore();
  898. App.config.getDefaultDisplayType.restore();
  899. App.config.getDefaultCategory.restore();
  900. App.config.getIsSecure.restore();
  901. App.config.shouldSupportFinal.restore();
  902. });
  903. var res = {
  904. /** core properties **/
  905. name: 'pName',
  906. filename: 'pFileName',
  907. value: '',
  908. savedValue: null,
  909. isFinal: false,
  910. savedIsFinal: null,
  911. /** UI and Stack properties **/
  912. recommendedValue: null,
  913. recommendedIsFinal: null,
  914. supportsFinal: true,
  915. serviceName: 'pServiceName',
  916. displayName: 'pDisplayName',
  917. displayType: 'pDisplayType',
  918. description: null,
  919. category: 'pCategory',
  920. isSecureConfig: false,
  921. showLabel: true,
  922. isVisible: true,
  923. isUserProperty: false,
  924. isRequired: true,
  925. group: null,
  926. isRequiredByAgent: true,
  927. isReconfigurable: true,
  928. unit: null,
  929. hasInitialValue: false,
  930. isOverridable: true,
  931. index: Infinity,
  932. dependentConfigPattern: null,
  933. options: null,
  934. radioName: null,
  935. belongsToService: [],
  936. widgetType: null
  937. };
  938. it('create default config object', function () {
  939. expect(App.config.createDefaultConfig('pName', 'pServiceName', 'pFileName', true)).to.eql(res);
  940. });
  941. it('runs proper methods', function() {
  942. expect(App.config.getDefaultDisplayName.calledWith('pName','pFileName')).to.be.true;
  943. expect(App.config.getDefaultDisplayType.calledWith('pName', 'pFileName', '')).to.be.true;
  944. expect(App.config.getDefaultCategory.calledWith(true, 'pFileName')).to.be.true;
  945. expect(App.config.getIsSecure.calledWith('pName')).to.be.true;
  946. expect(App.config.shouldSupportFinal.calledWith('pServiceName', 'pFileName')).to.be.true;
  947. });
  948. });
  949. describe('#mergeStackConfigsWithUI', function() {
  950. beforeEach(function() {
  951. sinon.stub(App.config, 'getPropertyIfExists', function(key, value) {return 'res_' + value});
  952. });
  953. afterEach(function() {
  954. App.config.getPropertyIfExists.restore();
  955. });
  956. var template = {
  957. name: 'pName',
  958. filename: 'pFileName',
  959. value: 'pValue',
  960. savedValue: 'pValue',
  961. isFinal: true,
  962. savedIsFinal: true,
  963. serviceName: 'pServiceName',
  964. displayName: 'pDisplayName',
  965. displayType: 'pDisplayType',
  966. category: 'pCategory'
  967. };
  968. var result = {
  969. name: 'pName',
  970. filename: 'pFileName',
  971. value: 'pValue',
  972. savedValue: 'pValue',
  973. isFinal: true,
  974. savedIsFinal: true,
  975. serviceName: 'res_pServiceName',
  976. displayName: 'res_pDisplayName',
  977. displayType: 'res_pDisplayType',
  978. category: 'res_pCategory'
  979. };
  980. it('called generate property object', function () {
  981. expect(App.config.mergeStaticProperties(template, {}, {})).to.eql(result);
  982. });
  983. });
  984. describe('#updateHostsListValue', function() {
  985. var tests = [
  986. {
  987. siteConfigs: {
  988. 'hadoop.registry.zk.quorum': 'host1,host2'
  989. },
  990. propertyName: 'hadoop.registry.zk.quorum',
  991. hostsList: 'host1',
  992. e: 'host1'
  993. },
  994. {
  995. siteConfigs: {
  996. 'hadoop.registry.zk.quorum': 'host1:10,host2:10'
  997. },
  998. propertyName: 'hadoop.registry.zk.quorum',
  999. hostsList: 'host2:10,host1:10',
  1000. e: 'host1:10,host2:10'
  1001. },
  1002. {
  1003. siteConfigs: {
  1004. 'hadoop.registry.zk.quorum': 'host1:10,host2:10,host3:10'
  1005. },
  1006. propertyName: 'hadoop.registry.zk.quorum',
  1007. hostsList: 'host2:10,host1:10',
  1008. e: 'host2:10,host1:10'
  1009. },
  1010. {
  1011. siteConfigs: {
  1012. 'hadoop.registry.zk.quorum': 'host1:10,host2:10,host3:10'
  1013. },
  1014. propertyName: 'hadoop.registry.zk.quorum',
  1015. hostsList: 'host2:10,host1:10,host3:10,host4:11',
  1016. e: 'host2:10,host1:10,host3:10,host4:11'
  1017. },
  1018. {
  1019. siteConfigs: {
  1020. 'hive.zookeeper.quorum': 'host1'
  1021. },
  1022. propertyName: 'some.new.property',
  1023. hostsList: 'host2,host1:10',
  1024. e: 'host2,host1:10'
  1025. }
  1026. ];
  1027. tests.forEach(function(test) {
  1028. it('ZK located on {0}, current prop value is "{1}" "{2}" value should be "{3}"'.format(test.hostsList, ''+test.siteConfigs[test.propertyName], test.propertyName, test.e), function() {
  1029. var result = App.config.updateHostsListValue(test.siteConfigs, test.propertyName, test.hostsList);
  1030. expect(result).to.be.eql(test.e);
  1031. expect(test.siteConfigs[test.propertyName]).to.be.eql(test.e);
  1032. });
  1033. });
  1034. });
  1035. describe('#createHostNameProperty', function() {
  1036. it('create host property', function() {
  1037. expect(App.config.createHostNameProperty('service1', 'component1', ['host1'], Em.Object.create({
  1038. isMultipleAllowed: false,
  1039. displayName: 'display name'
  1040. }))).to.eql({
  1041. "name": 'component1_host',
  1042. "displayName": 'display name host',
  1043. "value": ['host1'],
  1044. "recommendedValue": ['host1'],
  1045. "description": "The host that has been assigned to run display name",
  1046. "displayType": "componentHost",
  1047. "isOverridable": false,
  1048. "isRequiredByAgent": false,
  1049. "serviceName": 'service1',
  1050. "filename": "service1-site.xml",
  1051. "category": 'component1',
  1052. "index": 0
  1053. })
  1054. });
  1055. it('create hosts property', function() {
  1056. expect(App.config.createHostNameProperty('service1', 'component1', ['host1'], Em.Object.create({
  1057. isMultipleAllowed: true,
  1058. displayName: 'display name'
  1059. }))).to.eql({
  1060. "name": 'component1_hosts',
  1061. "displayName": 'display name host',
  1062. "value": ['host1'],
  1063. "recommendedValue": ['host1'],
  1064. "description": "The hosts that has been assigned to run display name",
  1065. "displayType": "componentHosts",
  1066. "isOverridable": false,
  1067. "isRequiredByAgent": false,
  1068. "serviceName": 'service1',
  1069. "filename": "service1-site.xml",
  1070. "category": 'component1',
  1071. "index": 0
  1072. })
  1073. });
  1074. })
  1075. });