config_test.js 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302
  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. var loadServiceSpecificConfigs = function(context, serviceName) {
  26. context.configGroups = modelSetup.setupConfigGroupsObject(serviceName);
  27. context.advancedConfigs = modelSetup.setupAdvancedConfigsObject();
  28. context.tags = modelSetup.setupServiceConfigTagsObject(serviceName);
  29. context.result = App.config.mergePreDefinedWithLoaded(context.configGroups, context.advancedConfigs, context.tags, App.Service.find().findProperty('id', serviceName).get('serviceName'));
  30. };
  31. var loadAllServicesConfigs = function(context, serviceNames) {
  32. context.configGroups = modelSetup.setupConfigGroupsObject();
  33. };
  34. var loadServiceModelsData = function(serviceNames) {
  35. serviceNames.forEach(function(serviceName) {
  36. App.store.load(App.Service, {
  37. id: serviceName,
  38. service_name: serviceName
  39. });
  40. });
  41. };
  42. var setupContentForMergeWithStored = function(context) {
  43. loadServiceModelsData(context.installedServiceNames);
  44. loadAllServicesConfigs(context);
  45. setups.setupStackVersion(this, 'HDP-2.1');
  46. context.result = App.config.mergePreDefinedWithStored(context.storedConfigs, modelSetup.setupAdvancedConfigsObject(), context.installedServiceNames);
  47. };
  48. var removeServiceModelData = function(serviceIds) {
  49. serviceIds.forEach(function(serviceId) {
  50. var record = App.Service.find(serviceId);
  51. record.deleteRecord();
  52. record.get('stateManager').transitionTo('loading');
  53. });
  54. };
  55. describe('#handleSpecialProperties', function () {
  56. var config = {};
  57. it('value should be transformed to "1024" from "1024m"', function () {
  58. config = {
  59. displayType: 'int',
  60. value: '1024m',
  61. savedValue: '1024m'
  62. };
  63. App.config.handleSpecialProperties(config);
  64. expect(config.value).to.equal('1024');
  65. expect(config.savedValue).to.equal('1024');
  66. });
  67. });
  68. describe('#fileConfigsIntoTextarea', function () {
  69. var filename = 'capacity-scheduler.xml';
  70. var configs = [
  71. {
  72. name: 'config1',
  73. value: 'value1',
  74. recommendedValue: 'value1',
  75. filename: 'capacity-scheduler.xml'
  76. },
  77. {
  78. name: 'config2',
  79. value: 'value2',
  80. recommendedValue: 'value2',
  81. filename: 'capacity-scheduler.xml'
  82. }
  83. ];
  84. it('two configs into textarea', function () {
  85. var result = App.config.fileConfigsIntoTextarea.call(App.config, configs, filename);
  86. expect(result.length).to.equal(1);
  87. expect(result[0].value).to.equal('config1=value1\nconfig2=value2\n');
  88. expect(result[0].recommendedValue).to.equal('config1=value1\nconfig2=value2\n');
  89. });
  90. it('three config into textarea', function () {
  91. configs.push({
  92. name: 'config3',
  93. value: 'value3',
  94. recommendedValue: 'value3',
  95. filename: 'capacity-scheduler.xml'
  96. });
  97. var result = App.config.fileConfigsIntoTextarea.call(App.config, configs, filename);
  98. expect(result.length).to.equal(1);
  99. expect(result[0].value).to.equal('config1=value1\nconfig2=value2\nconfig3=value3\n');
  100. expect(result[0].recommendedValue).to.equal('config1=value1\nconfig2=value2\nconfig3=value3\n');
  101. });
  102. it('one of three configs has different filename', function () {
  103. configs[1].filename = 'another filename';
  104. var result = App.config.fileConfigsIntoTextarea.call(App.config, configs, filename);
  105. //result contains two configs: one with different filename and one textarea config
  106. expect(result.length).to.equal(2);
  107. expect(result[1].value).to.equal('config1=value1\nconfig3=value3\n');
  108. expect(result[1].recommendedValue).to.equal('config1=value1\nconfig3=value3\n');
  109. });
  110. it('none configs into empty textarea', function () {
  111. filename = 'capacity-scheduler.xml';
  112. configs.clear();
  113. var result = App.config.fileConfigsIntoTextarea.call(App.config, configs, filename);
  114. expect(result.length).to.equal(1);
  115. expect(result[0].value).to.equal('');
  116. expect(result[0].recommendedValue).to.equal('');
  117. });
  118. it("filename has configs that shouldn't be included in textarea", function () {
  119. var configs = [
  120. {
  121. name: 'config1',
  122. value: 'value1',
  123. recommendedValue: 'value1',
  124. filename: filename
  125. },
  126. {
  127. name: 'config2',
  128. value: 'value2',
  129. recommendedValue: 'value2',
  130. filename: filename
  131. }
  132. ];
  133. var cfg = {
  134. name: 'config3',
  135. value: 'value3',
  136. recommendedValue: 'value3',
  137. filename: filename
  138. };
  139. configs.push(cfg);
  140. var result = App.config.fileConfigsIntoTextarea.call(App.config, configs, filename, [cfg]);
  141. expect(result.length).to.equal(2);
  142. expect(result[1].value).to.equal('config1=value1\nconfig2=value2\n');
  143. expect(result[1].recommendedValue).to.equal('config1=value1\nconfig2=value2\n');
  144. expect(configs.findProperty('name', 'config3')).to.eql(cfg);
  145. });
  146. });
  147. describe('#textareaIntoFileConfigs', function () {
  148. var filename = 'capacity-scheduler.xml';
  149. var testData = [
  150. {
  151. configs: [Em.Object.create({
  152. "name": "capacity-scheduler",
  153. "value": "config1=value1",
  154. "filename": "capacity-scheduler.xml",
  155. "isRequiredByAgent": true
  156. })]
  157. },
  158. {
  159. configs: [Em.Object.create({
  160. "name": "capacity-scheduler",
  161. "value": "config1=value1\nconfig2=value2\n",
  162. "filename": "capacity-scheduler.xml",
  163. "isRequiredByAgent": false
  164. })]
  165. },
  166. {
  167. configs: [Em.Object.create({
  168. "name": "capacity-scheduler",
  169. "value": "config1=value1,value2\n",
  170. "filename": "capacity-scheduler.xml",
  171. "isRequiredByAgent": true
  172. })]
  173. },
  174. {
  175. configs: [Em.Object.create({
  176. "name": "capacity-scheduler",
  177. "value": "config1=value1 config2=value2\n",
  178. "filename": "capacity-scheduler.xml",
  179. "isRequiredByAgent": false
  180. })]
  181. }
  182. ];
  183. it('config1=value1 to one config', function () {
  184. var result = App.config.textareaIntoFileConfigs.call(App.config, testData[0].configs, filename);
  185. expect(result.length).to.equal(1);
  186. expect(result[0].value).to.equal('value1');
  187. expect(result[0].name).to.equal('config1');
  188. expect(result[0].isRequiredByAgent).to.be.true;
  189. });
  190. it('config1=value1\\nconfig2=value2\\n to two configs', function () {
  191. var result = App.config.textareaIntoFileConfigs.call(App.config, testData[1].configs, filename);
  192. expect(result.length).to.equal(2);
  193. expect(result[0].value).to.equal('value1');
  194. expect(result[0].name).to.equal('config1');
  195. expect(result[1].value).to.equal('value2');
  196. expect(result[1].name).to.equal('config2');
  197. expect(result[0].isRequiredByAgent).to.be.false;
  198. expect(result[1].isRequiredByAgent).to.be.false;
  199. });
  200. it('config1=value1,value2\n to one config', function () {
  201. var result = App.config.textareaIntoFileConfigs.call(App.config, testData[2].configs, filename);
  202. expect(result.length).to.equal(1);
  203. expect(result[0].value).to.equal('value1,value2');
  204. expect(result[0].name).to.equal('config1');
  205. expect(result[0].isRequiredByAgent).to.be.true;
  206. });
  207. it('config1=value1 config2=value2 to two configs', function () {
  208. var result = App.config.textareaIntoFileConfigs.call(App.config, testData[3].configs, filename);
  209. expect(result.length).to.equal(1);
  210. expect(result[0].isRequiredByAgent).to.be.false;
  211. });
  212. });
  213. describe('#addAvancedConfigs()', function() {
  214. beforeEach(function() {
  215. this.storedConfigs = modelSetup.setupStoredConfigsObject();
  216. });
  217. it('`custom.zoo.cfg` absent in stored configs', function() {
  218. expect(this.storedConfigs.findProperty('name', 'custom.zoo.cfg')).to.be.undefined;
  219. });
  220. it('`custom.zoo.cfg.` from advanced configs should be added to stored configs', function() {
  221. App.config.addAdvancedConfigs(this.storedConfigs, modelSetup.setupAdvancedConfigsObject(), 'ZOOKEEPER');
  222. var property = this.storedConfigs.findProperty('name', 'custom.zoo.cfg');
  223. expect(property).to.be.ok;
  224. expect(property.category).to.eql('Advanced zoo.cfg');
  225. });
  226. it('`capacity-scheduler.xml` property with name `content` should have `displayType` `multiLine`', function() {
  227. App.config.addAdvancedConfigs(this.storedConfigs, modelSetup.setupAdvancedConfigsObject(), 'YARN');
  228. expect(this.storedConfigs.filterProperty('filename', 'capacity-scheduler.xml').findProperty('name','content').displayType).to.eql('multiLine');
  229. });
  230. it('storing different configs with the same name', function () {
  231. App.config.addAdvancedConfigs(this.storedConfigs, modelSetup.setupAdvancedConfigsObject(), 'HBASE');
  232. var properties = this.storedConfigs.filterProperty('name', 'hbase_log_dir');
  233. var hbaseProperty = properties.findProperty('filename', 'hbase-env.xml');
  234. var amsProperty = properties.findProperty('filename', 'ams-hbase-env.xml');
  235. expect(properties).to.have.length(2);
  236. expect(hbaseProperty.serviceName).to.equal('HBASE');
  237. expect(hbaseProperty.value).to.equal('/hadoop/hbase');
  238. expect(amsProperty.serviceName).to.equal('AMBARI_METRICS');
  239. expect(amsProperty.value).to.equal('/hadoop/ams-hbase');
  240. });
  241. });
  242. describe('#trimProperty',function() {
  243. var testMessage = 'displayType `{0}`, value `{1}`{3} should return `{2}`';
  244. var tests = [
  245. {
  246. config: {
  247. displayType: 'directory',
  248. value: ' /a /b /c'
  249. },
  250. e: '/a,/b,/c'
  251. },
  252. {
  253. config: {
  254. displayType: 'directories',
  255. value: ' /a /b '
  256. },
  257. e: '/a,/b'
  258. },
  259. {
  260. config: {
  261. displayType: 'datanodedirs',
  262. value: ' [DISK]/a [SSD]/b '
  263. },
  264. e: '[DISK]/a,[SSD]/b'
  265. },
  266. {
  267. config: {
  268. displayType: 'datanodedirs',
  269. value: '/a,/b, /c\n/d,\n/e /f'
  270. },
  271. e: '/a,/b,/c,/d,/e,/f'
  272. },
  273. {
  274. config: {
  275. displayType: 'host',
  276. value: ' localhost '
  277. },
  278. e: 'localhost'
  279. },
  280. {
  281. config: {
  282. displayType: 'password',
  283. value: ' passw ord '
  284. },
  285. e: ' passw ord '
  286. },
  287. {
  288. config: {
  289. displayType: 'advanced',
  290. value: ' value'
  291. },
  292. e: ' value'
  293. },
  294. {
  295. config: {
  296. displayType: 'advanced',
  297. value: ' value'
  298. },
  299. e: ' value'
  300. },
  301. {
  302. config: {
  303. displayType: 'advanced',
  304. value: 'http://localhost ',
  305. name: 'javax.jdo.option.ConnectionURL'
  306. },
  307. e: 'http://localhost'
  308. },
  309. {
  310. config: {
  311. displayType: 'advanced',
  312. value: 'http://localhost ',
  313. name: 'oozie.service.JPAService.jdbc.url'
  314. },
  315. e: 'http://localhost'
  316. },
  317. {
  318. config: {
  319. displayType: 'custom',
  320. value: ' custom value '
  321. },
  322. e: ' custom value'
  323. },
  324. {
  325. config: {
  326. displayType: 'masterHosts',
  327. value: ['host1.com', 'host2.com']
  328. },
  329. e: ['host1.com', 'host2.com']
  330. }
  331. ];
  332. tests.forEach(function(test) {
  333. it(testMessage.format(test.config.displayType, test.config.value, test.e, !!test.config.name ? ', name `' + test.config.name + '`' : ''), function() {
  334. expect(App.config.trimProperty(test.config)).to.eql(test.e);
  335. expect(App.config.trimProperty(Em.Object.create(test.config), true)).to.eql(test.e);
  336. });
  337. });
  338. });
  339. describe('#preDefinedConfigFile', function() {
  340. before(function() {
  341. setups.setupStackVersion(this, 'BIGTOP-0.8');
  342. });
  343. it('bigtop site properties should be ok.', function() {
  344. var bigtopSiteProperties = App.config.preDefinedConfigFile('site_properties');
  345. expect(bigtopSiteProperties).to.be.ok;
  346. });
  347. it('a non-existing file should not be ok.', function () {
  348. var notExistingSiteProperty = App.config.preDefinedConfigFile('notExisting');
  349. expect(notExistingSiteProperty).to.not.be.ok;
  350. });
  351. after(function() {
  352. setups.restoreStackVersion(this);
  353. });
  354. });
  355. describe('#preDefinedSiteProperties-bigtop', function () {
  356. before(function() {
  357. setups.setupStackVersion(this, 'BIGTOP-0.8');
  358. });
  359. it('bigtop should use New PostgreSQL Database as its default hive metastore database', function () {
  360. expect(App.config.get('preDefinedSiteProperties').findProperty('recommendedValue', 'New PostgreSQL Database')).to.be.ok;
  361. });
  362. after(function() {
  363. setups.restoreStackVersion(this);
  364. });
  365. });
  366. describe('#preDefinedSiteProperties-hdp2', function () {
  367. before(function() {
  368. setups.setupStackVersion(this, 'HDP-2.0');
  369. });
  370. it('HDP2 should use New MySQL Database as its default hive metastore database', function () {
  371. expect(App.config.get('preDefinedSiteProperties').findProperty('recommendedValue', 'New MySQL Database')).to.be.ok;
  372. });
  373. after(function() {
  374. setups.restoreStackVersion(this);
  375. });
  376. });
  377. describe('#generateConfigPropertiesByName', function() {
  378. var tests = [
  379. {
  380. names: ['property_1', 'property_2'],
  381. properties: undefined,
  382. e: {
  383. keys: ['name', 'displayName', 'isVisible', 'isReconfigurable']
  384. },
  385. m: 'Should generate base property object without additional fields'
  386. },
  387. {
  388. names: ['property_1', 'property_2'],
  389. properties: { category: 'SomeCat', serviceName: 'SERVICE_NAME' },
  390. e: {
  391. keys: ['name', 'displayName', 'isVisible', 'isReconfigurable', 'category', 'serviceName']
  392. },
  393. m: 'Should generate base property object without additional fields'
  394. }
  395. ];
  396. tests.forEach(function(test) {
  397. it(test.m, function() {
  398. expect(App.config.generateConfigPropertiesByName(test.names, test.properties).length).to.eql(test.names.length);
  399. expect(App.config.generateConfigPropertiesByName(test.names, test.properties).map(function(property) {
  400. return Em.keys(property);
  401. }).reduce(function(p, c) {
  402. return p.concat(c);
  403. }).uniq()).to.eql(test.e.keys);
  404. });
  405. });
  406. });
  407. describe('#setPreDefinedServiceConfigs', function() {
  408. beforeEach(function() {
  409. sinon.stub(App.StackService, 'find', function() {
  410. return [
  411. Em.Object.create({
  412. id: 'HDFS',
  413. serviceName: 'HDFS',
  414. configTypes: {
  415. 'hadoop-env': {},
  416. 'hdfs-site': {}
  417. }
  418. }),
  419. Em.Object.create({
  420. id: 'OOZIE',
  421. serviceName: 'OOZIE',
  422. configTypes: {
  423. 'oozie-env': {},
  424. 'oozie-site': {}
  425. }
  426. })
  427. ];
  428. });
  429. App.config.setPreDefinedServiceConfigs(true);
  430. });
  431. afterEach(function() {
  432. App.StackService.find.restore();
  433. });
  434. it('should include service MISC', function() {
  435. expect(App.config.get('preDefinedServiceConfigs').findProperty('serviceName', 'MISC')).to.be.ok;
  436. });
  437. it('should include -env config types according to stack services', function() {
  438. var miscCategory = App.config.get('preDefinedServiceConfigs').findProperty('serviceName', 'MISC');
  439. expect(Em.keys(miscCategory.get('configTypes'))).to.eql(['cluster-env', 'hadoop-env', 'oozie-env']);
  440. });
  441. it('should not load configs for missed config types', function() {
  442. var hdfsService = App.config.get('preDefinedServiceConfigs').findProperty('serviceName', 'HDFS');
  443. var rangerRelatedConfigs = hdfsService.get('configs').filterProperty('filename', 'ranger-hdfs-plugin-properties.xml');
  444. expect(rangerRelatedConfigs.length).to.be.eql(0);
  445. expect(hdfsService.get('configs.length') > 0).to.be.true;
  446. });
  447. });
  448. describe('#isManagedMySQLForHiveAllowed', function () {
  449. var cases = [
  450. {
  451. osFamily: 'redhat5',
  452. expected: false
  453. },
  454. {
  455. osFamily: 'redhat6',
  456. expected: true
  457. },
  458. {
  459. osFamily: 'suse11',
  460. expected: false
  461. }
  462. ],
  463. title = 'should be {0} for {1}';
  464. cases.forEach(function (item) {
  465. it(title.format(item.expected, item.osFamily), function () {
  466. expect(App.config.isManagedMySQLForHiveAllowed(item.osFamily)).to.equal(item.expected);
  467. });
  468. });
  469. });
  470. describe('#createAdvancedPropertyObject', function() {
  471. var tests = [
  472. {
  473. name: 'proxyuser_group',
  474. cases: [
  475. {
  476. key: 'displayType',
  477. e: 'user'
  478. },
  479. {
  480. key: 'serviceName',
  481. e: 'MISC'
  482. },
  483. {
  484. key: 'belongsToService',
  485. e: ['HIVE', 'OOZIE', 'FALCON']
  486. }
  487. ]
  488. },
  489. {
  490. name: 'oozie.service.JPAService.jdbc.password',
  491. cases: [
  492. {
  493. key: 'displayType',
  494. e: 'password'
  495. },
  496. {
  497. key: 'isVisible',
  498. e: true
  499. }
  500. ]
  501. },
  502. {
  503. name: 'ignore_groupsusers_create',
  504. cases: [
  505. {
  506. key: 'isVisible',
  507. e: false
  508. }
  509. ]
  510. },
  511. {
  512. name: 'user_group',
  513. cases: [
  514. {
  515. key: 'isVisible',
  516. e: true
  517. },
  518. {
  519. key: 'index',
  520. e: 30
  521. },
  522. {
  523. key: 'displayName',
  524. e: 'Hadoop Group'
  525. }
  526. ]
  527. },
  528. {
  529. name: 'zk_user',
  530. cases: [
  531. {
  532. key: 'displayName',
  533. e: 'ZooKeeper User'
  534. }
  535. ]
  536. },
  537. {
  538. name: 'mapred_user',
  539. cases: [
  540. {
  541. key: 'displayName',
  542. e: 'MapReduce User'
  543. }
  544. ]
  545. },
  546. {
  547. name: 'smokeuser',
  548. cases: [
  549. {
  550. key: 'displayName',
  551. e: 'Smoke Test User'
  552. }
  553. ]
  554. }
  555. ];
  556. var properties = [];
  557. modelSetup.advancedConfigs.items.forEach(function(item) {
  558. properties.push(App.config.createAdvancedPropertyObject(item.StackConfigurations));
  559. });
  560. App.config.loadClusterConfigSuccess(modelSetup.advancedClusterConfigs, {url: '/cluster/configurations'}, {callback: function (items) {properties = properties.concat(items)}});
  561. beforeEach(function () {
  562. sinon.stub(App, 'get').withArgs('isHadoopWindowsStack').returns(false);
  563. });
  564. afterEach(function () {
  565. App.get.restore();
  566. });
  567. tests.forEach(function(test) {
  568. test.cases.forEach(function(testCase) {
  569. it('config property `{0}` `{1}` key should be`{2}`'.format(test.name, testCase.key, testCase.e), function() {
  570. var property = properties.findProperty('name', test.name);
  571. expect(Em.get(property, testCase.key)).to.eql(testCase.e);
  572. });
  573. });
  574. });
  575. });
  576. describe('#mergePreDefinedWithLoaded', function() {
  577. var result;
  578. before(function() {
  579. sinon.stub(App.config, 'parseValue', function(value) {return value});
  580. sinon.stub(App.config, 'getConfigTypesInfoFromService').returns({
  581. supportsFinal: ['hdfs-site']
  582. });
  583. setups.setupStackVersion(this, 'HDP-2.2');
  584. loadServiceModelsData(['HDFS', 'STORM']);
  585. App.config.loadAdvancedConfigSuccess(modelSetup.advancedConfigs, { url: '/serviceName/configurations'}, {
  586. callback: function(advancedConfigs) {
  587. App.config.loadClusterConfigSuccess(modelSetup.advancedClusterConfigs, { url: '/cluster/configurations'}, {
  588. callback: function(clusterConfigs) {
  589. var configCategories = modelSetup.setupConfigGroupsObject();
  590. var tags = [
  591. {newTagName: null, tagName: 'version1', siteName: 'hadoop-env'},
  592. {newTagName: null, tagName: 'version1', siteName: 'hdfs-site'},
  593. {newTagName: null, tagName: 'version1', siteName: 'cluster-env'},
  594. {newTagName: null, tagName: 'version1', siteName: 'storm-env'}
  595. ];
  596. var serviceName = 'STORM';
  597. result = App.config.mergePreDefinedWithLoaded(configCategories, advancedConfigs.concat(clusterConfigs), tags, serviceName);
  598. }
  599. });
  600. }
  601. });
  602. });
  603. after(function() {
  604. App.config.parseValue.restore();
  605. App.config.getConfigTypesInfoFromService.restore();
  606. setups.restoreStackVersion(this);
  607. removeServiceModelData(['HDFS', 'STORM']);
  608. });
  609. var propertyTests = [
  610. {
  611. name: 'hdfs_user',
  612. cases: [
  613. {
  614. key: 'displayType',
  615. e: 'user'
  616. },
  617. {
  618. key: 'isVisible',
  619. e: true
  620. },
  621. {
  622. key: 'serviceName',
  623. e: 'MISC'
  624. },
  625. {
  626. key: 'category',
  627. e: 'Users and Groups'
  628. }
  629. ]
  630. }
  631. ];
  632. propertyTests.forEach(function(test) {
  633. test.cases.forEach(function(testCase) {
  634. it('config property `{0}` `{1}` key should be`{2}`'.format(test.name, testCase.key, testCase.e), function() {
  635. var property = result.configs.findProperty('name', test.name);
  636. expect(Em.get(property, testCase.key)).to.equal(testCase.e);
  637. });
  638. });
  639. });
  640. });
  641. describe('#replaceConfigValues', function () {
  642. var cases = [
  643. {
  644. name: 'name',
  645. express: '<templateName[0]>',
  646. value: '<templateName[0]>',
  647. globValue: 'v',
  648. expected: 'v',
  649. title: 'default case'
  650. },
  651. {
  652. name: 'templeton.hive.properties',
  653. express: '<templateName[0]>',
  654. value: 'hive.matestore.uris=<templateName[0]>',
  655. globValue: 'thrift://h0:9933,thrift://h1:9933,thrift://h2:9933',
  656. expected: 'hive.matestore.uris=thrift://h0:9933\\,thrift://h1:9933\\,thrift://h2:9933',
  657. title: 'should escape commas for templeton.hive.properties'
  658. }
  659. ];
  660. cases.forEach(function (item) {
  661. it(item.title, function () {
  662. expect(App.config.replaceConfigValues(item.name, item.express, item.value, item.globValue)).to.equal(item.expected);
  663. });
  664. });
  665. });
  666. describe('#advancedConfigIdentityData', function () {
  667. var configs = [
  668. {
  669. input: {
  670. property_type: ['USER'],
  671. property_name: 'hdfs_user'
  672. },
  673. output: {
  674. id: 'puppet var',
  675. category: 'Users and Groups',
  676. isVisible: true,
  677. serviceName: 'MISC',
  678. isOverridable: false,
  679. isReconfigurable: false,
  680. displayName: 'HDFS User',
  681. displayType: 'user',
  682. index: 30
  683. },
  684. title: 'user, no service name specified, default display name behaviour'
  685. },
  686. {
  687. input: {
  688. property_type: ['GROUP'],
  689. property_name: 'knox_group',
  690. service_name: 'KNOX'
  691. },
  692. output: {
  693. id: 'puppet var',
  694. category: 'Users and Groups',
  695. isVisible: true,
  696. serviceName: 'MISC',
  697. isOverridable: false,
  698. isReconfigurable: false,
  699. displayName: 'Knox Group',
  700. displayType: 'user',
  701. index: 0
  702. },
  703. title: 'group, service_name = KNOX, default display name behaviour'
  704. },
  705. {
  706. input: {
  707. property_type: ['USER']
  708. },
  709. output: {
  710. isVisible: false
  711. },
  712. isHDPWIN: true,
  713. title: 'HDPWIN stack'
  714. },
  715. {
  716. input: {
  717. property_type: ['USER'],
  718. property_name: 'smokeuser',
  719. service_name: 'MISC'
  720. },
  721. output: {
  722. displayName: 'Smoke Test User',
  723. serviceName: 'MISC',
  724. belongsToService: ['MISC'],
  725. index: 30
  726. },
  727. title: 'smokeuser, service_name = MISC'
  728. },
  729. {
  730. input: {
  731. property_type: ['GROUP'],
  732. property_name: 'user_group'
  733. },
  734. output: {
  735. displayName: 'Hadoop Group'
  736. },
  737. title: 'user_group'
  738. },
  739. {
  740. input: {
  741. property_type: ['USER'],
  742. property_name: 'mapred_user'
  743. },
  744. output: {
  745. displayName: 'MapReduce User'
  746. },
  747. title: 'mapred_user'
  748. },
  749. {
  750. input: {
  751. property_type: ['USER'],
  752. property_name: 'zk_user'
  753. },
  754. output: {
  755. displayName: 'ZooKeeper User'
  756. },
  757. title: 'zk_user'
  758. },
  759. {
  760. input: {
  761. property_type: ['USER'],
  762. property_name: 'ignore_groupsusers_create'
  763. },
  764. output: {
  765. displayName: 'Skip group modifications during install',
  766. displayType: 'checkbox'
  767. },
  768. title: 'ignore_groupsusers_create'
  769. },
  770. {
  771. input: {
  772. property_type: ['GROUP'],
  773. property_name: 'proxyuser_group'
  774. },
  775. output: {
  776. belongsToService: ['HIVE', 'OOZIE', 'FALCON']
  777. },
  778. title: 'proxyuser_group'
  779. },
  780. {
  781. input: {
  782. property_type: ['PASSWORD'],
  783. property_name: 'javax.jdo.option.ConnectionPassword'
  784. },
  785. output: {
  786. displayType: 'password'
  787. },
  788. title: 'password'
  789. }
  790. ];
  791. before(function () {
  792. sinon.stub(App.StackService, 'find').returns([
  793. {
  794. serviceName: 'KNOX'
  795. }
  796. ]);
  797. });
  798. afterEach(function () {
  799. App.get.restore();
  800. });
  801. after(function () {
  802. App.StackService.find.restore();
  803. });
  804. configs.forEach(function (item) {
  805. it(item.title, function () {
  806. sinon.stub(App, 'get').withArgs('isHadoopWindowsStack').returns(Boolean(item.isHDPWIN));
  807. var propertyData = App.config.advancedConfigIdentityData(item.input);
  808. Em.keys(item.output).forEach(function (key) {
  809. expect(propertyData[key]).to.eql(item.output[key]);
  810. });
  811. });
  812. });
  813. });
  814. describe('#addUserProperty', function () {
  815. var cases = [
  816. {
  817. stored: {
  818. id: 0,
  819. name: 'prop_name0',
  820. serviceName: 's0',
  821. value: 'v0',
  822. savedValue: 'dv0',
  823. filename: 'fn0.xml',
  824. overrides: null,
  825. isVisible: false,
  826. isFinal: true,
  827. savedIsFinal: false,
  828. supportsFinal: true,
  829. category: 'c0'
  830. },
  831. expected: {
  832. id: 0,
  833. name: 'prop_name0',
  834. displayName: 'Prop Name0',
  835. serviceName: 's0',
  836. value: 'v0',
  837. savedValue: 'dv0',
  838. displayType: 'advanced',
  839. filename: 'fn0.xml',
  840. isUserProperty: false,
  841. hasInitialValue: false,
  842. isOverridable: true,
  843. overrides: null,
  844. isRequired: false,
  845. isVisible: false,
  846. isFinal: true,
  847. savedIsFinal: false,
  848. supportsFinal: true,
  849. showLabel: true,
  850. category: 'c0'
  851. },
  852. title: 'default case'
  853. },
  854. {
  855. stored: {
  856. name: 'n1',
  857. value: 'multi\nline',
  858. filename: 'fn1.xml',
  859. isUserProperty: true,
  860. hasInitialValue: true,
  861. showLabel: false
  862. },
  863. expected: {
  864. displayType: 'multiLine',
  865. isUserProperty: true,
  866. hasInitialValue: true,
  867. showLabel: false
  868. },
  869. title: 'multiline user property with initial value, label not to be shown'
  870. },
  871. {
  872. stored: {
  873. name: 'n2',
  874. filename: 'fn2.xml'
  875. },
  876. expected: {
  877. isUserProperty: false,
  878. showLabel: true
  879. },
  880. title: 'isUserProperty and showLabel not set'
  881. },
  882. {
  883. stored: {
  884. name: 'ignore_groupsusers_create',
  885. category: 'Users and Groups',
  886. filename: 'fn3.xml'
  887. },
  888. expected: {
  889. displayName: 'dn0',
  890. displayType: 'checkbox',
  891. index: 0
  892. }
  893. },
  894. {
  895. stored: {
  896. name: 'smokeuser',
  897. category: 'Users and Groups',
  898. filename: 'fn4.xml'
  899. },
  900. expected: {
  901. displayName: 'dn1',
  902. index: 1
  903. }
  904. },
  905. {
  906. stored: {
  907. name: 'user_group',
  908. category: 'Users and Groups',
  909. filename: 'fn5.xml'
  910. },
  911. expected: {
  912. displayName: 'dn1',
  913. index: 2
  914. }
  915. },
  916. {
  917. stored: {
  918. name: 'mapred_user',
  919. category: 'Users and Groups',
  920. filename: 'fn6.xml'
  921. },
  922. expected: {
  923. displayName: 'dn1',
  924. index: 3
  925. }
  926. },
  927. {
  928. stored: {
  929. name: 'zk_user',
  930. category: 'Users and Groups',
  931. filename: 'fn7.xml'
  932. },
  933. expected: {
  934. displayName: 'dn1',
  935. index: 4
  936. }
  937. }
  938. ],
  939. advancedConfigs = [
  940. {
  941. name: 'ignore_groupsusers_create',
  942. displayName: 'dn0',
  943. displayType: 'checkbox',
  944. index: 0
  945. },
  946. {
  947. name: 'smokeuser',
  948. displayName: 'dn1',
  949. index: 1
  950. },
  951. {
  952. name: 'user_group',
  953. displayName: 'dn1',
  954. index: 2
  955. },
  956. {
  957. name: 'mapred_user',
  958. displayName: 'dn1',
  959. index: 3
  960. },
  961. {
  962. name: 'zk_user',
  963. displayName: 'dn1',
  964. index: 4
  965. }
  966. ];
  967. cases.forEach(function (item) {
  968. it(item.title || item.stored.name, function () {
  969. var configData = App.config.addUserProperty(item.stored, true, advancedConfigs);
  970. Em.keys(item.expected).forEach(function (key) {
  971. expect(configData[key]).to.equal(item.expected[key]);
  972. });
  973. });
  974. });
  975. });
  976. describe('#getOriginalConfigAttribute', function () {
  977. var stored = {
  978. name: 'p',
  979. displayName: 'dn'
  980. },
  981. cases = [
  982. {
  983. advancedConfigs: [
  984. {
  985. name: 'p',
  986. displayName: 'dn0'
  987. }
  988. ],
  989. expected: 'dn0',
  990. title: 'should take attribute from advancedConfigs'
  991. },
  992. {
  993. advancedConfigs: [],
  994. expected: 'dn',
  995. title: 'property is absent in advancedConfigs'
  996. }
  997. ];
  998. cases.forEach(function (item) {
  999. it(item.title, function () {
  1000. expect(App.config.getOriginalConfigAttribute(stored, 'displayName', item.advancedConfigs)).to.equal(item.expected);
  1001. });
  1002. });
  1003. });
  1004. describe('#setConfigValue', function () {
  1005. Em.A([
  1006. {
  1007. mappedConfigs: [
  1008. {
  1009. name: 'falcon_user',
  1010. value: 'fu'
  1011. }
  1012. ],
  1013. allConfigs: [],
  1014. m: 'in mapped, value used',
  1015. e: {
  1016. _name: 'hadoop.proxyuser.fu.groups',
  1017. value: 'fu',
  1018. noMatchSoSkipThisConfig: false
  1019. }
  1020. },
  1021. {
  1022. mappedConfigs: [],
  1023. allConfigs: [
  1024. {
  1025. name: 'falcon_user',
  1026. value: 'fu'
  1027. }
  1028. ],
  1029. m: 'in all, value used',
  1030. e: {
  1031. _name: 'hadoop.proxyuser.fu.groups',
  1032. value: 'fu',
  1033. noMatchSoSkipThisConfig: false
  1034. }
  1035. },
  1036. {
  1037. mappedConfigs: [],
  1038. allConfigs: [
  1039. {
  1040. name: 'falcon_user',
  1041. value: '',
  1042. recommendedValue: 'fu'
  1043. }
  1044. ],
  1045. m: 'in all, default value used',
  1046. e: {
  1047. _name: 'hadoop.proxyuser.fu.groups',
  1048. value: 'fu',
  1049. noMatchSoSkipThisConfig: false
  1050. }
  1051. },
  1052. {
  1053. mappedConfigs: [],
  1054. allConfigs: [],
  1055. m: 'not found',
  1056. e: {
  1057. _name: 'hadoop.proxyuser.<foreignKey[0]>.groups',
  1058. value: '<foreignKey[0]>',
  1059. noMatchSoSkipThisConfig: true
  1060. }
  1061. }
  1062. ]).forEach(function (test) {
  1063. it(test.m, function () {
  1064. var config = {
  1065. name: "hadoop.proxyuser.<foreignKey[0]>.groups",
  1066. templateName: ["proxyuser_group"],
  1067. foreignKey: ["falcon_user"],
  1068. noMatchSoSkipThisConfig: false,
  1069. value: "<foreignKey[0]>"
  1070. };
  1071. App.config.setConfigValue(test.mappedConfigs, test.allConfigs, config);
  1072. expect(config.value).to.equal(test.e.value);
  1073. if(test.e.noMatchSoSkipThisConfig) {
  1074. expect(Em.isNone(config._name)).to.be.true;
  1075. }
  1076. else {
  1077. expect(config._name).to.equal(test.e._name);
  1078. }
  1079. expect(config.noMatchSoSkipThisConfig).to.equal(test.e.noMatchSoSkipThisConfig);
  1080. });
  1081. Em.A([
  1082. {
  1083. mappedConfigs: [],
  1084. allConfigs: [
  1085. {
  1086. name: 'falcon_user',
  1087. value: 'fu'
  1088. },
  1089. {
  1090. name: 'proxyuser_group',
  1091. value: 'pg'
  1092. }
  1093. ],
  1094. m: 'in all, template in all',
  1095. e: {
  1096. _name: 'hadoop.proxyuser.fu.groups',
  1097. value: 'fupg'
  1098. }
  1099. },
  1100. {
  1101. mappedConfigs: [
  1102. {
  1103. name: 'falcon_user',
  1104. value: 'fu'
  1105. },
  1106. {
  1107. name: 'proxyuser_group',
  1108. value: 'pg'
  1109. }
  1110. ],
  1111. allConfigs: [],
  1112. m: 'in mapped, template in mapped',
  1113. e: {
  1114. _name: 'hadoop.proxyuser.fu.groups',
  1115. value: 'fupg'
  1116. }
  1117. },
  1118. {
  1119. mappedConfigs: [],
  1120. allConfigs: [],
  1121. m: 'not found (template not found too)',
  1122. e: {
  1123. _name: 'hadoop.proxyuser.<foreignKey[0]>.groups',
  1124. value: null
  1125. }
  1126. }
  1127. ]).forEach(function (test) {
  1128. it(test.m, function () {
  1129. var config = {
  1130. name: "hadoop.proxyuser.<foreignKey[0]>.groups",
  1131. templateName: ["proxyuser_group"],
  1132. foreignKey: ["falcon_user"],
  1133. noMatchSoSkipThisConfig: false,
  1134. value: "<foreignKey[0]><templateName[0]>"
  1135. };
  1136. App.config.setConfigValue(test.mappedConfigs, test.allConfigs, config);
  1137. });
  1138. });
  1139. });
  1140. });
  1141. describe('#shouldSupportFinal', function () {
  1142. var cases = [
  1143. {
  1144. shouldSupportFinal: false,
  1145. title: 'no service name specified'
  1146. },
  1147. {
  1148. serviceName: 's0',
  1149. shouldSupportFinal: false,
  1150. title: 'no filename specified'
  1151. },
  1152. {
  1153. serviceName: 'MISC',
  1154. shouldSupportFinal: false,
  1155. title: 'MISC'
  1156. },
  1157. {
  1158. serviceName: 's0',
  1159. filename: 's0-site',
  1160. shouldSupportFinal: true,
  1161. title: 'final attribute supported'
  1162. },
  1163. {
  1164. serviceName: 's0',
  1165. filename: 's0-env',
  1166. shouldSupportFinal: false,
  1167. title: 'final attribute not supported'
  1168. }
  1169. ];
  1170. beforeEach(function () {
  1171. sinon.stub(App.StackService, 'find').returns([
  1172. {
  1173. serviceName: 's0'
  1174. }
  1175. ]);
  1176. sinon.stub(App.config, 'getConfigTypesInfoFromService').returns({
  1177. supportsFinal: ['s0-site']
  1178. });
  1179. });
  1180. afterEach(function () {
  1181. App.StackService.find.restore();
  1182. App.config.getConfigTypesInfoFromService.restore();
  1183. });
  1184. cases.forEach(function (item) {
  1185. it(item.title, function () {
  1186. expect(App.config.shouldSupportFinal(item.serviceName, item.filename)).to.equal(item.shouldSupportFinal);
  1187. });
  1188. });
  1189. });
  1190. describe('#removeRangerConfigs', function () {
  1191. it('should remove ranger configs and categories', function () {
  1192. var configs = [
  1193. Em.Object.create({
  1194. configs: [
  1195. Em.Object.create({filename: 'filename'}),
  1196. Em.Object.create({filename: 'ranger-filename'})
  1197. ],
  1198. configCategories: [
  1199. Em.Object.create({name: 'ranger-name'}),
  1200. Em.Object.create({name: 'name'}),
  1201. Em.Object.create({name: 'also-ranger-name'})
  1202. ]
  1203. })
  1204. ];
  1205. App.config.removeRangerConfigs(configs);
  1206. expect(configs).eql(
  1207. [
  1208. Em.Object.create({
  1209. configs: [
  1210. Em.Object.create({filename: 'filename'})
  1211. ],
  1212. configCategories: [
  1213. Em.Object.create({name: 'name'})
  1214. ]
  1215. })
  1216. ]
  1217. );
  1218. });
  1219. });
  1220. });