config_test.js 40 KB

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