blueprint_test.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455
  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 blueprintUtils = require('utils/blueprint');
  19. describe('utils/blueprint', function() {
  20. var masterBlueprint = {
  21. blueprint: {
  22. host_groups: [
  23. {
  24. name: "host-group-1",
  25. components: [
  26. { name: "ZOOKEEPER_SERVER" },
  27. { name: "NAMENODE" },
  28. { name: "HBASE_MASTER" }
  29. ]
  30. },
  31. {
  32. name: "host-group-2",
  33. components: [
  34. { name: "SECONDARY_NAMENODE" }
  35. ]
  36. }
  37. ]
  38. },
  39. blueprint_cluster_binding: {
  40. host_groups: [
  41. {
  42. name: "host-group-1",
  43. hosts: [
  44. { fqdn: "host1" },
  45. { fqdn: "host2" }
  46. ]
  47. },
  48. {
  49. name: "host-group-2",
  50. hosts: [
  51. { fqdn: "host3" }
  52. ]
  53. }
  54. ]
  55. }
  56. };
  57. var slaveBlueprint = {
  58. blueprint: {
  59. host_groups: [
  60. {
  61. name: "host-group-1",
  62. components: [
  63. { name: "DATANODE" }
  64. ]
  65. },
  66. {
  67. name: "host-group-2",
  68. components: [
  69. { name: "DATANODE" },
  70. { name: "HDFS_CLIENT" },
  71. { name: "ZOOKEEPER_CLIENT" }
  72. ]
  73. }
  74. ]
  75. },
  76. blueprint_cluster_binding: {
  77. host_groups: [
  78. {
  79. name: "host-group-1",
  80. hosts: [
  81. { fqdn: "host3" }
  82. ]
  83. },
  84. {
  85. name: "host-group-2",
  86. hosts: [
  87. { fqdn: "host4" },
  88. { fqdn: "host5" }
  89. ]
  90. }
  91. ]
  92. }
  93. };
  94. describe('#matchGroups', function() {
  95. it('should compose same host group into pairs', function() {
  96. expect(blueprintUtils.matchGroups(masterBlueprint, slaveBlueprint)).to.deep.equal([
  97. { g1: "host-group-1" },
  98. { g1: "host-group-2", g2: "host-group-1" },
  99. { g2: "host-group-2" }
  100. ]);
  101. });
  102. });
  103. describe('#filterByComponents', function() {
  104. it('should remove all components except', function() {
  105. expect(blueprintUtils.filterByComponents(masterBlueprint, ["NAMENODE"])).to.deep.equal({
  106. blueprint: {
  107. host_groups: [
  108. {
  109. name: "host-group-1",
  110. components: [
  111. { name: "NAMENODE" }
  112. ]
  113. }
  114. ]
  115. },
  116. blueprint_cluster_binding: {
  117. host_groups: [
  118. {
  119. name: "host-group-1",
  120. hosts: [
  121. { fqdn: "host1" },
  122. { fqdn: "host2" }
  123. ]
  124. }
  125. ]
  126. }
  127. });
  128. });
  129. });
  130. describe('#addComponentsToBlueprint', function() {
  131. it('should add components to blueprint', function() {
  132. var components = ["FLUME_HANDLER", "HCAT"];
  133. expect(blueprintUtils.addComponentsToBlueprint(masterBlueprint, components)).to.deep.equal({
  134. blueprint: {
  135. host_groups: [
  136. {
  137. name: "host-group-1",
  138. components: [
  139. { name: "ZOOKEEPER_SERVER" },
  140. { name: "NAMENODE" },
  141. { name: "HBASE_MASTER" },
  142. { name: "FLUME_HANDLER" },
  143. { name: "HCAT" }
  144. ]
  145. },
  146. {
  147. name: "host-group-2",
  148. components: [
  149. { name: "SECONDARY_NAMENODE" },
  150. { name: "FLUME_HANDLER" },
  151. { name: "HCAT" }
  152. ]
  153. }
  154. ]
  155. },
  156. blueprint_cluster_binding: {
  157. host_groups: [
  158. {
  159. name: "host-group-1",
  160. hosts: [
  161. { fqdn: "host1" },
  162. { fqdn: "host2" }
  163. ]
  164. },
  165. {
  166. name: "host-group-2",
  167. hosts: [
  168. { fqdn: "host3" }
  169. ]
  170. }
  171. ]
  172. }
  173. });
  174. });
  175. });
  176. describe('#mergeBlueprints', function() {
  177. it('should merge components', function() {
  178. expect(blueprintUtils.mergeBlueprints(masterBlueprint, slaveBlueprint)).to.deep.equal(
  179. {
  180. blueprint: {
  181. host_groups: [
  182. {
  183. name: "host-group-1",
  184. components: [
  185. { name: "ZOOKEEPER_SERVER" },
  186. { name: "NAMENODE" },
  187. { name: "HBASE_MASTER" }
  188. ]
  189. },
  190. {
  191. name: "host-group-2",
  192. components: [
  193. { name: "SECONDARY_NAMENODE" },
  194. { name: "DATANODE" }
  195. ]
  196. },
  197. {
  198. name: "host-group-3",
  199. components: [
  200. { name: "DATANODE" },
  201. { name: "HDFS_CLIENT" },
  202. { name: "ZOOKEEPER_CLIENT" }
  203. ]
  204. }
  205. ]
  206. },
  207. blueprint_cluster_binding: {
  208. host_groups: [
  209. {
  210. name: "host-group-1",
  211. hosts: [
  212. { fqdn: "host1" },
  213. { fqdn: "host2" }
  214. ]
  215. },
  216. {
  217. name: "host-group-2",
  218. hosts: [
  219. { fqdn: "host3" }
  220. ]
  221. },
  222. {
  223. name: "host-group-3",
  224. hosts: [
  225. { fqdn: "host4" },
  226. { fqdn: "host5" }
  227. ]
  228. }
  229. ]
  230. }
  231. }
  232. );
  233. });
  234. });
  235. describe('#buildConfigsJSON', function () {
  236. var tests = [
  237. {
  238. "stepConfigs": [
  239. Em.Object.create({
  240. serviceName: "YARN",
  241. configs: [
  242. Em.Object.create({
  243. name: "p1",
  244. value: "v1",
  245. filename: "yarn-site.xml",
  246. isRequiredByAgent: true
  247. }),
  248. Em.Object.create({
  249. name: "p2",
  250. value: "v2",
  251. filename: "yarn-site.xml",
  252. isRequiredByAgent: true
  253. }),
  254. Em.Object.create({
  255. name: "p3",
  256. value: "v3",
  257. filename: "yarn-env.xml",
  258. isRequiredByAgent: true
  259. })
  260. ]
  261. }),
  262. Em.Object.create({
  263. serviceName: "MISC",
  264. configs: [
  265. Em.Object.create({
  266. name: "user",
  267. value: "yarn",
  268. filename: "yarn-env.xml",
  269. isRequiredByAgent: true
  270. })
  271. ]
  272. })
  273. ],
  274. "configurations": {
  275. "yarn-site": {
  276. "properties": {
  277. "p1": "v1",
  278. "p2": "v2"
  279. }
  280. },
  281. "yarn-env": {
  282. "properties": {
  283. "p3": "v3",
  284. "user": "yarn"
  285. }
  286. }
  287. }
  288. }
  289. ];
  290. tests.forEach(function (test) {
  291. it("generate configs for request (use in validation)", function () {
  292. expect(blueprintUtils.buildConfigsJSON(test.stepConfigs)).to.eql(test.configurations);
  293. });
  294. });
  295. });
  296. describe('#generateHostGroups()', function () {
  297. beforeEach(function() {
  298. sinon.stub(blueprintUtils, 'getComponentForHosts').returns({
  299. "host1": ["C1", "C2"],
  300. "host2": ["C1", "C3"]
  301. });
  302. });
  303. afterEach(function() {
  304. blueprintUtils.getComponentForHosts.restore();
  305. });
  306. var tests = [
  307. {
  308. "hostNames": ["host1", "host2"],
  309. "hostComponents": [
  310. Em.Object.create({
  311. componentName: "C1",
  312. hostName: "host1"
  313. }),
  314. Em.Object.create({
  315. componentName: "C2",
  316. hostName: "host1"
  317. }),
  318. Em.Object.create({
  319. componentName: "C1",
  320. hostName: "host2"
  321. }),
  322. Em.Object.create({
  323. componentName: "C3",
  324. hostName: "host2"
  325. })
  326. ],
  327. result: {
  328. blueprint: {
  329. host_groups: [
  330. {
  331. name: "host-group-1",
  332. "components": [
  333. {
  334. "name": "C1"
  335. },
  336. {
  337. "name": "C2"
  338. }
  339. ]
  340. },
  341. {
  342. name: "host-group-2",
  343. "components": [
  344. {
  345. "name": "C1"
  346. },
  347. {
  348. "name": "C3"
  349. }
  350. ]
  351. }
  352. ]
  353. },
  354. blueprint_cluster_binding: {
  355. host_groups: [
  356. {
  357. "name": "host-group-1",
  358. "hosts": [
  359. {
  360. "fqdn": "host1"
  361. }
  362. ]
  363. },
  364. {
  365. "name": "host-group-2",
  366. "hosts": [
  367. {
  368. "fqdn": "host2"
  369. }
  370. ]
  371. }
  372. ]
  373. }
  374. }
  375. }
  376. ];
  377. tests.forEach(function (test) {
  378. it("generate host groups", function () {
  379. expect(blueprintUtils.generateHostGroups(test.hostNames)).to.eql(test.result);
  380. });
  381. });
  382. });
  383. describe("#getComponentForHosts()", function() {
  384. var res;
  385. beforeEach(function() {
  386. sinon.stub(App.ClientComponent, 'find').returns([
  387. Em.Object.create({
  388. componentName: "C1",
  389. hostNames: ["host1", "host2"]
  390. })
  391. ]);
  392. sinon.stub(App.SlaveComponent, 'find').returns([
  393. Em.Object.create({
  394. componentName: "C2",
  395. hostNames: ["host2", "host3"]
  396. })
  397. ]);
  398. sinon.stub(App.MasterComponent, 'find').returns([
  399. Em.Object.create({
  400. componentName: "C3",
  401. hostNames: ["host3"]
  402. })
  403. ]);
  404. res = blueprintUtils.getComponentForHosts();
  405. });
  406. afterEach(function() {
  407. App.ClientComponent.find.restore();
  408. App.SlaveComponent.find.restore();
  409. App.MasterComponent.find.restore();
  410. });
  411. it('map for 3 items is created', function () {
  412. expect(Object.keys(res)).to.have.property('length').equal(3);
  413. });
  414. it("host1 map is valid", function() {
  415. expect(res.host1.toArray()).to.eql(['C1']);
  416. });
  417. it("host2 map is valid", function() {
  418. expect(res.host2.toArray()).to.eql(['C1', 'C2']);
  419. });
  420. it("host3 map is valid", function() {
  421. expect(res.host3.toArray()).to.eql(['C2', 'C3']);
  422. });
  423. });
  424. describe('#_generateHostMap', function() {
  425. it('generate map', function() {
  426. var map = blueprintUtils._generateHostMap({}, ['h1','h2', 'h1'],'c1');
  427. expect(map['h1'][0]).to.eql('c1');
  428. expect(map['h2'][0]).to.eql('c1');
  429. });
  430. it('skip generations as hosts is empty', function() {
  431. expect(blueprintUtils._generateHostMap({}, [],'c1')).to.eql({});
  432. });
  433. it('skip throws error when data is wrong (should assert error if no data returned from server)', function() {
  434. expect(function () {
  435. blueprintUtils._generateHostMap();
  436. }).to.throw(Error);
  437. });
  438. });
  439. });