/pcsd/test/test_config.rb

https://github.com/feist/pcs · Ruby · 919 lines · 867 code · 50 blank · 2 comment · 0 complexity · 87601365e063926cda26b6754a01633a MD5 · raw file

  1. require 'test/unit'
  2. require 'fileutils'
  3. require 'pcsd_test_utils.rb'
  4. require 'config.rb'
  5. require 'permissions.rb'
  6. class TestConfig < Test::Unit::TestCase
  7. def setup
  8. $logger = MockLogger.new
  9. FileUtils.cp(File.join(CURRENT_DIR, 'pcs_settings.conf'), CFG_PCSD_SETTINGS)
  10. end
  11. def fixture_nil_config()
  12. return (
  13. '{
  14. "format_version": 2,
  15. "data_version": 0,
  16. "clusters": [
  17. ],
  18. "permissions": {
  19. "local_cluster": [
  20. {
  21. "type": "group",
  22. "name": "haclient",
  23. "allow": [
  24. "grant",
  25. "read",
  26. "write"
  27. ]
  28. }
  29. ]
  30. }
  31. }')
  32. end
  33. def fixture_empty_config()
  34. return (
  35. '{
  36. "format_version": 2,
  37. "data_version": 0,
  38. "clusters": [
  39. ],
  40. "permissions": {
  41. "local_cluster": [
  42. ]
  43. }
  44. }')
  45. end
  46. def test_parse_nil()
  47. text = nil
  48. cfg = PCSConfig.new(text)
  49. assert_equal(0, cfg.clusters.length)
  50. assert_equal([], $logger.log)
  51. assert_equal(fixture_nil_config, cfg.text)
  52. end
  53. def test_parse_empty()
  54. text = ''
  55. cfg = PCSConfig.new(text)
  56. assert_equal(0, cfg.clusters.length)
  57. assert_equal([], $logger.log)
  58. assert_equal(fixture_empty_config, cfg.text)
  59. end
  60. def test_parse_whitespace()
  61. text = " \n "
  62. cfg = PCSConfig.new(text)
  63. assert_equal(0, cfg.clusters.length)
  64. assert_equal([], $logger.log)
  65. assert_equal(fixture_empty_config, cfg.text)
  66. end
  67. def test_parse_hash_empty()
  68. text = '{}'
  69. cfg = PCSConfig.new(text)
  70. assert_equal(
  71. [['error', 'Unable to parse pcs_settings file: invalid file format']],
  72. $logger.log
  73. )
  74. assert_equal(fixture_empty_config, cfg.text)
  75. end
  76. def test_parse_hash_no_version()
  77. text =
  78. '{
  79. "data_version": 9,
  80. "clusters": [
  81. {
  82. "name": "cluster71",
  83. "nodes": [
  84. "rh71-node1",
  85. "rh71-node2"
  86. ]
  87. }
  88. ]
  89. }'
  90. cfg = PCSConfig.new(text)
  91. assert_equal(
  92. [['error', 'Unable to parse pcs_settings file: invalid file format']],
  93. $logger.log
  94. )
  95. assert_equal(fixture_empty_config, cfg.text)
  96. end
  97. def test_parse_malformed()
  98. text =
  99. '{
  100. "data_version": 9,
  101. "clusters": [
  102. {
  103. "name": "cluster71",
  104. "nodes": [
  105. "rh71-node1"
  106. "rh71-node2"
  107. ]
  108. }
  109. ]
  110. }'
  111. cfg = PCSConfig.new(text)
  112. assert_equal(1, $logger.log.length)
  113. assert_equal('error', $logger.log[0][0])
  114. assert_match(
  115. # the number is based on JSON gem version
  116. /Unable to parse pcs_settings file: \d+: unexpected token/,
  117. $logger.log[0][1]
  118. )
  119. assert_equal(fixture_empty_config, cfg.text)
  120. end
  121. def test_parse_format1_empty()
  122. text = '[]'
  123. cfg = PCSConfig.new(text)
  124. assert_equal(0, cfg.clusters.length)
  125. assert_equal(
  126. '{
  127. "format_version": 2,
  128. "data_version": 0,
  129. "clusters": [
  130. ],
  131. "permissions": {
  132. "local_cluster": [
  133. {
  134. "type": "group",
  135. "name": "haclient",
  136. "allow": [
  137. "grant",
  138. "read",
  139. "write"
  140. ]
  141. }
  142. ]
  143. }
  144. }',
  145. cfg.text
  146. )
  147. end
  148. def test_parse_format1_one_cluster()
  149. text = '
  150. [
  151. {
  152. "name": "cluster71",
  153. "nodes": [
  154. "rh71-node1",
  155. "rh71-node2"
  156. ]
  157. }
  158. ]
  159. '
  160. cfg = PCSConfig.new(text)
  161. assert_equal(1, cfg.clusters.length)
  162. assert_equal("cluster71", cfg.clusters[0].name)
  163. assert_equal(["rh71-node1", "rh71-node2"], cfg.clusters[0].nodes)
  164. assert_equal(
  165. '{
  166. "format_version": 2,
  167. "data_version": 0,
  168. "clusters": [
  169. {
  170. "name": "cluster71",
  171. "nodes": [
  172. "rh71-node1",
  173. "rh71-node2"
  174. ]
  175. }
  176. ],
  177. "permissions": {
  178. "local_cluster": [
  179. {
  180. "type": "group",
  181. "name": "haclient",
  182. "allow": [
  183. "grant",
  184. "read",
  185. "write"
  186. ]
  187. }
  188. ]
  189. }
  190. }',
  191. cfg.text
  192. )
  193. end
  194. def test_parse_format2_empty()
  195. text = '
  196. {
  197. "format_version": 2
  198. }
  199. '
  200. cfg = PCSConfig.new(text)
  201. assert_equal(2, cfg.format_version)
  202. assert_equal(0, cfg.data_version)
  203. assert_equal(0, cfg.clusters.length)
  204. assert_equal(fixture_empty_config, cfg.text)
  205. end
  206. def test_parse_format2_one_cluster()
  207. text =
  208. '{
  209. "format_version": 2,
  210. "data_version": 9,
  211. "clusters": [
  212. {
  213. "name": "cluster71",
  214. "nodes": [
  215. "rh71-node1",
  216. "rh71-node2"
  217. ]
  218. }
  219. ],
  220. "permissions": {
  221. "local_cluster": [
  222. ]
  223. }
  224. }'
  225. cfg = PCSConfig.new(text)
  226. assert_equal(2, cfg.format_version)
  227. assert_equal(9, cfg.data_version)
  228. assert_equal(1, cfg.clusters.length)
  229. assert_equal("cluster71", cfg.clusters[0].name)
  230. assert_equal(["rh71-node1", "rh71-node2"], cfg.clusters[0].nodes)
  231. assert_equal(text, cfg.text)
  232. end
  233. def test_parse_format2_two_clusters()
  234. text =
  235. '{
  236. "format_version": 2,
  237. "data_version": 9,
  238. "clusters": [
  239. {
  240. "name": "cluster71",
  241. "nodes": [
  242. "rh71-node2",
  243. "rh71-node1",
  244. "rh71-node3",
  245. "rh71-node2"
  246. ]
  247. },
  248. {
  249. "name": "abcd",
  250. "nodes": [
  251. "abcd-node2",
  252. "abcd-node1",
  253. "abcd-node3",
  254. "abcd-node2"
  255. ]
  256. }
  257. ],
  258. "permissions": {
  259. "local_cluster": [
  260. ]
  261. }
  262. }'
  263. cfg = PCSConfig.new(text)
  264. assert_equal(2, cfg.format_version)
  265. assert_equal(9, cfg.data_version)
  266. assert_equal(2, cfg.clusters.length)
  267. assert_equal("cluster71", cfg.clusters[0].name)
  268. assert_equal(
  269. ["rh71-node1", "rh71-node2", "rh71-node3"],
  270. cfg.clusters[0].nodes
  271. )
  272. out_text =
  273. '{
  274. "format_version": 2,
  275. "data_version": 9,
  276. "clusters": [
  277. {
  278. "name": "cluster71",
  279. "nodes": [
  280. "rh71-node1",
  281. "rh71-node2",
  282. "rh71-node3"
  283. ]
  284. },
  285. {
  286. "name": "abcd",
  287. "nodes": [
  288. "abcd-node1",
  289. "abcd-node2",
  290. "abcd-node3"
  291. ]
  292. }
  293. ],
  294. "permissions": {
  295. "local_cluster": [
  296. ]
  297. }
  298. }'
  299. assert_equal(out_text, cfg.text)
  300. end
  301. def test_parse_format2_bad_cluster()
  302. text =
  303. '{
  304. "format_version": 2,
  305. "data_version": 9,
  306. "clusters": [
  307. {
  308. "name": "cluster71",
  309. "nodes": [
  310. "rh71-node2",
  311. "rh71-node1",
  312. [
  313. "xxx",
  314. "yyy"
  315. ],
  316. "rh71-node2"
  317. ]
  318. }
  319. ]
  320. }'
  321. cfg = PCSConfig.new(text)
  322. assert_equal(2, cfg.format_version)
  323. assert_equal(9, cfg.data_version)
  324. assert_equal(1, cfg.clusters.length)
  325. assert_equal("cluster71", cfg.clusters[0].name)
  326. assert_equal(["rh71-node1", "rh71-node2"], cfg.clusters[0].nodes)
  327. assert_equal(
  328. '{
  329. "format_version": 2,
  330. "data_version": 9,
  331. "clusters": [
  332. {
  333. "name": "cluster71",
  334. "nodes": [
  335. "rh71-node1",
  336. "rh71-node2"
  337. ]
  338. }
  339. ],
  340. "permissions": {
  341. "local_cluster": [
  342. ]
  343. }
  344. }',
  345. cfg.text
  346. )
  347. end
  348. def test_parse_format2_permissions()
  349. text =
  350. '{
  351. "format_version": 2,
  352. "data_version": 9,
  353. "clusters": [
  354. {
  355. "name": "cluster71",
  356. "nodes": [
  357. "rh71-node1",
  358. "rh71-node2"
  359. ]
  360. }
  361. ],
  362. "permissions": {
  363. "local_cluster": [
  364. {
  365. "type": "group",
  366. "name": "group2",
  367. "allow": [
  368. "read"
  369. ]
  370. },
  371. {
  372. "type": "user",
  373. "name": "user2",
  374. "allow": [
  375. ]
  376. },
  377. {
  378. "type": "group",
  379. "name": "group2",
  380. "allow": [
  381. "grant"
  382. ]
  383. },
  384. {
  385. "type": "group",
  386. "name": "group1",
  387. "allow": [
  388. "write", "full", "write"
  389. ]
  390. },
  391. {
  392. "type": "user",
  393. "name": "user1",
  394. "allow": [
  395. "grant", "write", "grant", "read"
  396. ]
  397. }
  398. ]
  399. }
  400. }'
  401. out_text =
  402. '{
  403. "format_version": 2,
  404. "data_version": 9,
  405. "clusters": [
  406. {
  407. "name": "cluster71",
  408. "nodes": [
  409. "rh71-node1",
  410. "rh71-node2"
  411. ]
  412. }
  413. ],
  414. "permissions": {
  415. "local_cluster": [
  416. {
  417. "type": "group",
  418. "name": "group1",
  419. "allow": [
  420. "full",
  421. "write"
  422. ]
  423. },
  424. {
  425. "type": "group",
  426. "name": "group2",
  427. "allow": [
  428. "grant",
  429. "read"
  430. ]
  431. },
  432. {
  433. "type": "user",
  434. "name": "user1",
  435. "allow": [
  436. "grant",
  437. "read",
  438. "write"
  439. ]
  440. },
  441. {
  442. "type": "user",
  443. "name": "user2",
  444. "allow": [
  445. ]
  446. }
  447. ]
  448. }
  449. }'
  450. cfg = PCSConfig.new(text)
  451. assert_equal(out_text, cfg.text)
  452. perms = cfg.permissions_local
  453. assert_equal(false, perms.allows?('user1', [], Permissions::FULL))
  454. assert_equal(true, perms.allows?('user1', [], Permissions::GRANT))
  455. assert_equal(true, perms.allows?('user1', [], Permissions::WRITE))
  456. assert_equal(true, perms.allows?('user1', [], Permissions::READ))
  457. assert_equal(true, perms.allows?('user1', ['group1'], Permissions::FULL))
  458. assert_equal(true, perms.allows?('user1', ['group1'], Permissions::GRANT))
  459. assert_equal(true, perms.allows?('user1', ['group1'], Permissions::WRITE))
  460. assert_equal(true, perms.allows?('user1', ['group1'], Permissions::READ))
  461. assert_equal(false, perms.allows?('user2', [], Permissions::FULL))
  462. assert_equal(false, perms.allows?('user2', [], Permissions::GRANT))
  463. assert_equal(false, perms.allows?('user2', [], Permissions::WRITE))
  464. assert_equal(false, perms.allows?('user2', [], Permissions::READ))
  465. assert_equal(false, perms.allows?('user2', ['group2'], Permissions::FULL))
  466. assert_equal(true, perms.allows?('user2', ['group2'], Permissions::GRANT))
  467. assert_equal(false, perms.allows?('user2', ['group2'], Permissions::WRITE))
  468. assert_equal(true, perms.allows?('user2', ['group2'], Permissions::READ))
  469. end
  470. def test_in_use()
  471. cfg = PCSConfig.new(File.open(CFG_PCSD_SETTINGS).read)
  472. assert(cfg.is_cluster_name_in_use('cluster71'))
  473. assert(cfg.is_cluster_name_in_use('cluster67'))
  474. assert(! cfg.is_cluster_name_in_use('nonexistent'))
  475. assert_equal(cfg.get_nodes_cluster('rh71-node1'), 'cluster71')
  476. assert_equal(cfg.get_nodes_cluster('rh67-node3'), 'cluster67')
  477. assert_equal(cfg.get_nodes_cluster('rh71-node3'), nil)
  478. assert_equal(
  479. ["rh71-node1", "rh71-node2"],
  480. cfg.get_nodes('cluster71')
  481. )
  482. assert_equal(
  483. ["rh67-node1", "rh67-node2", "rh67-node3"],
  484. cfg.get_nodes('cluster67')
  485. )
  486. assert_equal(
  487. nil,
  488. cfg.get_nodes('nonexistent')
  489. )
  490. end
  491. def test_update_cluster()
  492. cfg = PCSConfig.new(File.open(CFG_PCSD_SETTINGS).read)
  493. assert_equal(
  494. ["rh71-node1", "rh71-node2"],
  495. cfg.get_nodes('cluster71')
  496. )
  497. assert_equal(
  498. ["rh67-node1", "rh67-node2", "rh67-node3"],
  499. cfg.get_nodes('cluster67')
  500. )
  501. cfg.update_cluster('cluster71', ["rh71-node1", "rh71-node2", "rh71-node3"])
  502. assert_equal(
  503. ["rh71-node1", "rh71-node2", "rh71-node3"],
  504. cfg.get_nodes('cluster71')
  505. )
  506. assert_equal(
  507. ["rh67-node1", "rh67-node2", "rh67-node3"],
  508. cfg.get_nodes('cluster67')
  509. )
  510. cfg.update_cluster('cluster71', ["rh71-node1", "rh71-node2"])
  511. assert_equal(
  512. ["rh71-node1", "rh71-node2"],
  513. cfg.get_nodes('cluster71')
  514. )
  515. assert_equal(
  516. ["rh67-node1", "rh67-node2", "rh67-node3"],
  517. cfg.get_nodes('cluster67')
  518. )
  519. cfg.update_cluster('cluster71', [])
  520. assert(! cfg.is_cluster_name_in_use('cluster71'))
  521. assert_equal(
  522. ["rh67-node1", "rh67-node2", "rh67-node3"],
  523. cfg.get_nodes('cluster67')
  524. )
  525. cfg.update_cluster(
  526. 'cluster67',
  527. ['rh67-node3', [], 'rh67-node1', 'rh67-node2', ['xx'], 'rh67-node1']
  528. )
  529. assert_equal(
  530. ["rh67-node1", "rh67-node2", "rh67-node3"],
  531. cfg.get_nodes('cluster67')
  532. )
  533. end
  534. def test_remove_cluster()
  535. cfg = PCSConfig.new(File.open(CFG_PCSD_SETTINGS).read)
  536. assert_equal(
  537. ["rh71-node1", "rh71-node2"],
  538. cfg.get_nodes('cluster71')
  539. )
  540. assert_equal(
  541. ["rh67-node1", "rh67-node2", "rh67-node3"],
  542. cfg.get_nodes('cluster67')
  543. )
  544. cfg.remove_cluster('nonexistent')
  545. assert_equal(
  546. ["rh71-node1", "rh71-node2"],
  547. cfg.get_nodes('cluster71')
  548. )
  549. assert_equal(
  550. ["rh67-node1", "rh67-node2", "rh67-node3"],
  551. cfg.get_nodes('cluster67')
  552. )
  553. cfg.remove_cluster('cluster71')
  554. assert(! cfg.is_cluster_name_in_use('cluster71'))
  555. assert_equal(
  556. ["rh67-node1", "rh67-node2", "rh67-node3"],
  557. cfg.get_nodes('cluster67')
  558. )
  559. end
  560. def test_cluster_nodes_equal?()
  561. text =
  562. '{
  563. "format_version": 2,
  564. "data_version": 9,
  565. "clusters": [
  566. {
  567. "name": "cluster71",
  568. "nodes": [
  569. "rh71-node1",
  570. "rh71-node2"
  571. ]
  572. }
  573. ],
  574. "permissions": {
  575. "local_cluster": [
  576. ]
  577. }
  578. }'
  579. cfg = PCSConfig.new(text)
  580. assert_equal(
  581. true,
  582. cfg.cluster_nodes_equal?('cluster71', ['rh71-node1', 'rh71-node2'])
  583. )
  584. assert_equal(
  585. true,
  586. cfg.cluster_nodes_equal?('cluster71', ['rh71-node1', 'rh71-node2', 'rh71-node1'])
  587. )
  588. assert_equal(
  589. true,
  590. cfg.cluster_nodes_equal?('cluster71', ['rh71-node2', 'rh71-node1'])
  591. )
  592. assert_equal(
  593. false,
  594. cfg.cluster_nodes_equal?('cluster71', [])
  595. )
  596. assert_equal(
  597. false,
  598. cfg.cluster_nodes_equal?('cluster71', ['rh71-node1'])
  599. )
  600. assert_equal(
  601. false,
  602. cfg.cluster_nodes_equal?('cluster71', ['rh71-node3', 'rh71-node1'])
  603. )
  604. assert_equal(
  605. false,
  606. cfg.cluster_nodes_equal?('cluster71', ['rh71-node1', 'rh71-node2', 'rh71-node3'])
  607. )
  608. assert_equal(
  609. false,
  610. cfg.cluster_nodes_equal?('abcd', ['rh71-node3', 'rh71-node1'])
  611. )
  612. assert_equal(
  613. true,
  614. cfg.cluster_nodes_equal?('abcd', [])
  615. )
  616. end
  617. end
  618. class TestCfgKnownHosts < Test::Unit::TestCase
  619. def setup
  620. $logger = MockLogger.new
  621. end
  622. def fixture_empty_config()
  623. return(
  624. '{
  625. "format_version": 1,
  626. "data_version": 0,
  627. "known_hosts": {
  628. }
  629. }'
  630. )
  631. end
  632. def assert_empty_data(cfg)
  633. assert_equal(1, cfg.format_version)
  634. assert_equal(0, cfg.data_version)
  635. assert_equal(0, cfg.known_hosts.length)
  636. assert_equal(fixture_empty_config(), cfg.text)
  637. end
  638. def assert_known_host(host, name, token, dest_list)
  639. assert_equal(name, host.name)
  640. assert_equal(token, host.token)
  641. assert_equal(dest_list, host.dest_list)
  642. end
  643. def test_parse_nil()
  644. cfg = CfgKnownHosts.new(nil)
  645. assert_equal([], $logger.log)
  646. assert_empty_data(cfg)
  647. end
  648. def test_parse_empty()
  649. cfg = CfgKnownHosts.new('')
  650. assert_equal([], $logger.log)
  651. assert_empty_data(cfg)
  652. end
  653. def test_parse_whitespace()
  654. cfg = CfgKnownHosts.new(" \n ")
  655. assert_equal([], $logger.log)
  656. assert_empty_data(cfg)
  657. end
  658. def test_parse_malformed()
  659. text =
  660. '{
  661. "format_version": 1,
  662. "data_version": 0,
  663. "known_hosts": {
  664. }'
  665. cfg = CfgKnownHosts.new(text)
  666. assert_equal(1, $logger.log.length)
  667. assert_equal('error', $logger.log[0][0])
  668. assert_match(
  669. # the number is based on JSON gem version
  670. /Unable to parse known-hosts file: \d+: unexpected token/,
  671. $logger.log[0][1]
  672. )
  673. assert_empty_data(cfg)
  674. end
  675. def test_parse_format1_empty()
  676. cfg = CfgKnownHosts.new(fixture_empty_config())
  677. assert_equal([], $logger.log)
  678. assert_empty_data(cfg)
  679. end
  680. def test_parse_format1_simple()
  681. text =
  682. '{
  683. "format_version": 1,
  684. "data_version": 2,
  685. "known_hosts": {
  686. "node1": {
  687. "dest_list": [
  688. {
  689. "addr": "10.0.1.1",
  690. "port": 2224
  691. }
  692. ],
  693. "token": "abcde"
  694. }
  695. }
  696. }'
  697. cfg = CfgKnownHosts.new(text)
  698. assert_equal([], $logger.log)
  699. assert_equal(1, cfg.format_version)
  700. assert_equal(2, cfg.data_version)
  701. assert_equal(1, cfg.known_hosts.length)
  702. assert_equal('node1', cfg.known_hosts['node1'].name)
  703. assert_equal('abcde', cfg.known_hosts['node1'].token)
  704. assert_equal(
  705. [
  706. {'addr' => '10.0.1.1', 'port' => 2224}
  707. ],
  708. cfg.known_hosts['node1'].dest_list
  709. )
  710. assert_equal(text, cfg.text)
  711. end
  712. def test_parse_format1_complex()
  713. text =
  714. '{
  715. "format_version": 1,
  716. "data_version": 2,
  717. "known_hosts": {
  718. "node1": {
  719. "dest_list": [
  720. {
  721. "addr": "10.0.1.1",
  722. "port": 2224
  723. },
  724. {
  725. "addr": "10.0.2.1",
  726. "port": 2225
  727. }
  728. ],
  729. "token": "abcde"
  730. },
  731. "node2": {
  732. "dest_list": [
  733. {
  734. "addr": "10.0.1.2",
  735. "port": 2234
  736. },
  737. {
  738. "addr": "10.0.2.2",
  739. "port": 2235
  740. }
  741. ],
  742. "token": "fghij"
  743. }
  744. }
  745. }'
  746. cfg = CfgKnownHosts.new(text)
  747. assert_equal([], $logger.log)
  748. assert_equal(1, cfg.format_version)
  749. assert_equal(2, cfg.data_version)
  750. assert_equal(2, cfg.known_hosts.length)
  751. assert_known_host(
  752. cfg.known_hosts['node1'],
  753. 'node1',
  754. 'abcde',
  755. [
  756. {'addr' => '10.0.1.1', 'port' => 2224},
  757. {'addr' => '10.0.2.1', 'port' => 2225}
  758. ]
  759. )
  760. assert_known_host(
  761. cfg.known_hosts['node2'],
  762. 'node2',
  763. 'fghij',
  764. [
  765. {'addr' => '10.0.1.2', 'port' => 2234},
  766. {'addr' => '10.0.2.2', 'port' => 2235}
  767. ]
  768. )
  769. assert_equal(text, cfg.text)
  770. end
  771. def test_parse_format1_error()
  772. text =
  773. '{
  774. "format_version": 1,
  775. "data_version": 2,
  776. "known_hosts": {
  777. "node1": {
  778. "token": "abcde"
  779. }
  780. }
  781. }'
  782. cfg = CfgKnownHosts.new(text)
  783. assert_equal(1, $logger.log.length)
  784. assert_equal('error', $logger.log[0][0])
  785. assert_match(
  786. 'Unable to parse known-hosts file: key not found: "dest_list"',
  787. $logger.log[0][1]
  788. )
  789. assert_equal(1, cfg.format_version)
  790. assert_equal(2, cfg.data_version)
  791. assert_equal(0, cfg.known_hosts.length)
  792. end
  793. def test_update()
  794. text =
  795. '{
  796. "format_version": 1,
  797. "data_version": 2,
  798. "known_hosts": {
  799. "node1": {
  800. "dest_list": [
  801. {
  802. "addr": "10.0.1.1",
  803. "port": 2224
  804. }
  805. ],
  806. "token": "abcde"
  807. },
  808. "node2": {
  809. "dest_list": [
  810. {
  811. "addr": "10.0.1.2",
  812. "port": 2234
  813. }
  814. ],
  815. "token": "fghij"
  816. }
  817. }
  818. }'
  819. cfg = CfgKnownHosts.new(text)
  820. assert_equal([], $logger.log)
  821. cfg.data_version += 1
  822. cfg.known_hosts.delete('node2')
  823. cfg.known_hosts['node3'] = PcsKnownHost.new(
  824. 'node3',
  825. 'klmno',
  826. [
  827. {'addr' => '10.0.1.3', 'port' => 2224}
  828. ]
  829. )
  830. assert_equal(
  831. cfg.text,
  832. '{
  833. "format_version": 1,
  834. "data_version": 3,
  835. "known_hosts": {
  836. "node1": {
  837. "dest_list": [
  838. {
  839. "addr": "10.0.1.1",
  840. "port": 2224
  841. }
  842. ],
  843. "token": "abcde"
  844. },
  845. "node3": {
  846. "dest_list": [
  847. {
  848. "addr": "10.0.1.3",
  849. "port": 2224
  850. }
  851. ],
  852. "token": "klmno"
  853. }
  854. }
  855. }'
  856. )
  857. end
  858. end