test_glusterfs.py 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  1. # -*- coding: utf-8 -*-
  2. '''
  3. :codeauthor: Jayesh Kariya <jayeshk@saltstack.com>
  4. '''
  5. # Import Python libs
  6. from __future__ import absolute_import, unicode_literals, print_function
  7. # Import Salt Testing Libs
  8. from tests.support.mixins import LoaderModuleMockMixin
  9. from tests.support.unit import TestCase
  10. from tests.support.mock import (
  11. MagicMock,
  12. patch)
  13. # Import Salt Libs
  14. import salt.states.glusterfs as glusterfs
  15. import salt.utils.cloud
  16. import salt.utils.network
  17. import salt.modules.glusterfs as mod_glusterfs
  18. class GlusterfsTestCase(TestCase, LoaderModuleMockMixin):
  19. '''
  20. Test cases for salt.states.glusterfs
  21. '''
  22. def setup_loader_modules(self):
  23. return {
  24. glusterfs: {
  25. '__salt__': {'glusterfs.peer': mod_glusterfs.peer}
  26. }
  27. }
  28. # 'peered' function tests: 1
  29. def test_peered(self):
  30. '''
  31. Test to verify if node is peered.
  32. '''
  33. name = 'server1'
  34. ret = {'name': name,
  35. 'result': True,
  36. 'comment': '',
  37. 'changes': {}}
  38. mock_ip = MagicMock(return_value=['1.2.3.4', '1.2.3.5'])
  39. mock_ip6 = MagicMock(return_value=['2001:db8::1'])
  40. mock_host_ips = MagicMock(return_value=['1.2.3.5'])
  41. mock_peer = MagicMock(return_value=True)
  42. mock_status = MagicMock(return_value={'uuid1': {'hostnames': [name]}})
  43. with patch.dict(glusterfs.__salt__, {'glusterfs.peer_status': mock_status,
  44. 'glusterfs.peer': mock_peer}):
  45. with patch.object(salt.utils.network, 'ip_addrs', mock_ip), \
  46. patch.object(salt.utils.network, 'ip_addrs6', mock_ip6), \
  47. patch.object(salt.utils.network, 'host_to_ips', mock_host_ips):
  48. comt = 'Peering with localhost is not needed'
  49. ret.update({'comment': comt})
  50. self.assertDictEqual(glusterfs.peered(name), ret)
  51. mock_host_ips.return_value = ['2001:db8::1']
  52. self.assertDictEqual(glusterfs.peered(name), ret)
  53. mock_host_ips.return_value = ['1.2.3.42']
  54. comt = ('Host {0} already peered'.format(name))
  55. ret.update({'comment': comt})
  56. self.assertDictEqual(glusterfs.peered(name), ret)
  57. with patch.dict(glusterfs.__opts__, {'test': False}):
  58. old = {'uuid1': {'hostnames': ['other1']}}
  59. new = {'uuid1': {'hostnames': ['other1']},
  60. 'uuid2': {'hostnames': ['someAlias', name]}}
  61. mock_status.side_effect = [old, new]
  62. comt = 'Host {0} successfully peered'.format(name)
  63. ret.update({'comment': comt,
  64. 'changes': {'old': old, 'new': new}})
  65. self.assertDictEqual(glusterfs.peered(name), ret)
  66. mock_status.side_effect = None
  67. mock_status.return_value = {
  68. 'uuid1': {'hostnames': ['other']}
  69. }
  70. mock_peer.return_value = False
  71. ret.update({'result': False})
  72. comt = ('Failed to peer with {0},'
  73. + ' please check logs for errors').format(name)
  74. ret.update({'comment': comt, 'changes': {}})
  75. self.assertDictEqual(glusterfs.peered(name), ret)
  76. comt = ('Invalid characters in peer name.')
  77. ret.update({'comment': comt, 'name': ':/'})
  78. self.assertDictEqual(glusterfs.peered(':/'), ret)
  79. ret.update({'name': name})
  80. with patch.dict(glusterfs.__opts__, {'test': True}):
  81. comt = ('Peer {0} will be added.'.format(name))
  82. ret.update({'comment': comt, 'result': None})
  83. self.assertDictEqual(glusterfs.peered(name), ret)
  84. # 'volume_present' function tests: 1
  85. def test_volume_present(self):
  86. '''
  87. Test to ensure that a volume exists
  88. '''
  89. name = 'salt'
  90. bricks = ['host1:/brick1']
  91. ret = {'name': name,
  92. 'result': True,
  93. 'comment': '',
  94. 'changes': {}}
  95. started_info = {name: {'status': '1'}}
  96. stopped_info = {name: {'status': '0'}}
  97. mock_info = MagicMock()
  98. mock_list = MagicMock()
  99. mock_create = MagicMock()
  100. mock_start = MagicMock(return_value=True)
  101. with patch.dict(glusterfs.__salt__, {
  102. 'glusterfs.info': mock_info,
  103. 'glusterfs.list_volumes': mock_list,
  104. 'glusterfs.create_volume': mock_create,
  105. 'glusterfs.start_volume': mock_start}):
  106. with patch.dict(glusterfs.__opts__, {'test': False}):
  107. mock_list.return_value = [name]
  108. mock_info.return_value = started_info
  109. comt = ('Volume {0} already exists and is started'.format(name))
  110. ret.update({'comment': comt})
  111. self.assertDictEqual(glusterfs.volume_present(name, bricks,
  112. start=True), ret)
  113. mock_info.return_value = stopped_info
  114. comt = ('Volume {0} already exists and is now started'.format(name))
  115. ret.update({'comment': comt,
  116. 'changes': {'old': 'stopped', 'new': 'started'}})
  117. self.assertDictEqual(glusterfs.volume_present(name, bricks,
  118. start=True), ret)
  119. comt = ('Volume {0} already exists'.format(name))
  120. ret.update({'comment': comt, 'changes': {}})
  121. self.assertDictEqual(glusterfs.volume_present(name, bricks,
  122. start=False), ret)
  123. with patch.dict(glusterfs.__opts__, {'test': True}):
  124. comt = ('Volume {0} already exists'.format(name))
  125. ret.update({'comment': comt, 'result': None})
  126. self.assertDictEqual(glusterfs.volume_present(name, bricks,
  127. start=False), ret)
  128. comt = ('Volume {0} already exists'
  129. + ' and will be started').format(name)
  130. ret.update({'comment': comt, 'result': None})
  131. self.assertDictEqual(glusterfs.volume_present(name, bricks,
  132. start=True), ret)
  133. mock_list.return_value = []
  134. comt = ('Volume {0} will be created'.format(name))
  135. ret.update({'comment': comt, 'result': None})
  136. self.assertDictEqual(glusterfs.volume_present(name, bricks,
  137. start=False), ret)
  138. comt = ('Volume {0} will be created'
  139. + ' and started').format(name)
  140. ret.update({'comment': comt, 'result': None})
  141. self.assertDictEqual(glusterfs.volume_present(name, bricks,
  142. start=True), ret)
  143. with patch.dict(glusterfs.__opts__, {'test': False}):
  144. mock_list.side_effect = [[], [name]]
  145. comt = ('Volume {0} is created'.format(name))
  146. ret.update({'comment': comt,
  147. 'result': True,
  148. 'changes': {'old': [], 'new': [name]}})
  149. self.assertDictEqual(glusterfs.volume_present(name, bricks,
  150. start=False), ret)
  151. mock_list.side_effect = [[], [name]]
  152. comt = ('Volume {0} is created and is now started'.format(name))
  153. ret.update({'comment': comt, 'result': True})
  154. self.assertDictEqual(glusterfs.volume_present(name, bricks,
  155. start=True), ret)
  156. mock_list.side_effect = None
  157. mock_list.return_value = []
  158. mock_create.return_value = False
  159. comt = 'Creation of volume {0} failed'.format(name)
  160. ret.update({'comment': comt, 'result': False, 'changes': {}})
  161. self.assertDictEqual(glusterfs.volume_present(name, bricks),
  162. ret)
  163. with patch.object(salt.utils.cloud, 'check_name',
  164. MagicMock(return_value=True)):
  165. comt = ('Invalid characters in volume name.')
  166. ret.update({'comment': comt, 'result': False})
  167. self.assertDictEqual(glusterfs.volume_present(name, bricks),
  168. ret)
  169. # 'started' function tests: 1
  170. def test_started(self):
  171. '''
  172. Test to check if volume has been started
  173. '''
  174. name = 'salt'
  175. ret = {'name': name,
  176. 'result': False,
  177. 'comment': '',
  178. 'changes': {}}
  179. started_info = {name: {'status': '1'}}
  180. stopped_info = {name: {'status': '0'}}
  181. mock_info = MagicMock(return_value={})
  182. mock_start = MagicMock(return_value=True)
  183. with patch.dict(glusterfs.__salt__,
  184. {'glusterfs.info': mock_info,
  185. 'glusterfs.start_volume': mock_start}):
  186. comt = ('Volume {0} does not exist'.format(name))
  187. ret.update({'comment': comt})
  188. self.assertDictEqual(glusterfs.started(name), ret)
  189. mock_info.return_value = started_info
  190. comt = ('Volume {0} is already started'.format(name))
  191. ret.update({'comment': comt, 'result': True})
  192. self.assertDictEqual(glusterfs.started(name), ret)
  193. with patch.dict(glusterfs.__opts__, {'test': True}):
  194. mock_info.return_value = stopped_info
  195. comt = ('Volume {0} will be started'.format(name))
  196. ret.update({'comment': comt, 'result': None})
  197. self.assertDictEqual(glusterfs.started(name), ret)
  198. with patch.dict(glusterfs.__opts__, {'test': False}):
  199. comt = 'Volume {0} is started'.format(name)
  200. ret.update({'comment': comt, 'result': True,
  201. 'change': {'new': 'started', 'old': 'stopped'}})
  202. self.assertDictEqual(glusterfs.started(name), ret)
  203. # 'add_volume_bricks' function tests: 1
  204. def test_add_volume_bricks(self):
  205. '''
  206. Test to add brick(s) to an existing volume
  207. '''
  208. name = 'salt'
  209. bricks = ['host1:/drive1']
  210. old_bricks = ['host1:/drive2']
  211. ret = {'name': name,
  212. 'result': False,
  213. 'comment': '',
  214. 'changes': {}}
  215. stopped_volinfo = {'salt': {'status': '0'}}
  216. volinfo = {
  217. 'salt': {
  218. 'status': '1',
  219. 'bricks': {'brick1': {'path': old_bricks[0]}}
  220. }
  221. }
  222. new_volinfo = {
  223. 'salt': {
  224. 'status': '1',
  225. 'bricks': {
  226. 'brick1': {'path': old_bricks[0]},
  227. 'brick2': {'path': bricks[0]}
  228. }
  229. }
  230. }
  231. mock_info = MagicMock(return_value={})
  232. mock_add = MagicMock(side_effect=[False, True])
  233. with patch.dict(glusterfs.__salt__,
  234. {'glusterfs.info': mock_info,
  235. 'glusterfs.add_volume_bricks': mock_add}):
  236. ret.update({'comment': 'Volume salt does not exist'})
  237. self.assertDictEqual(glusterfs.add_volume_bricks(name, bricks), ret)
  238. mock_info.return_value = stopped_volinfo
  239. ret.update({'comment': 'Volume salt is not started'})
  240. self.assertDictEqual(glusterfs.add_volume_bricks(name, bricks), ret)
  241. mock_info.return_value = volinfo
  242. ret.update({'comment': 'Adding bricks to volume salt failed'})
  243. self.assertDictEqual(glusterfs.add_volume_bricks(name, bricks), ret)
  244. ret.update({'result': True})
  245. ret.update({'comment': 'Bricks already added in volume salt'})
  246. self.assertDictEqual(glusterfs.add_volume_bricks(name, old_bricks),
  247. ret)
  248. mock_info.side_effect = [volinfo, new_volinfo]
  249. ret.update({'comment': 'Bricks successfully added to volume salt',
  250. 'changes': {'new': bricks + old_bricks,
  251. 'old': old_bricks}})
  252. # Let's sort ourselves because the test under python 3 sometimes fails
  253. # just because of the new changes list order
  254. result = glusterfs.add_volume_bricks(name, bricks)
  255. ret['changes']['new'] = sorted(ret['changes']['new'])
  256. result['changes']['new'] = sorted(result['changes']['new'])
  257. self.assertDictEqual(result, ret)
  258. # 'op_version' function tests: 1
  259. def test_op_version(self):
  260. '''
  261. Test setting the Glusterfs op-version
  262. '''
  263. name = 'salt'
  264. current = 30707
  265. new = 31200
  266. ret = {'name': name,
  267. 'result': False,
  268. 'comment': '',
  269. 'changes': {}}
  270. mock_get_version = MagicMock(return_value={})
  271. mock_set_version = MagicMock(return_value={})
  272. with patch.dict(glusterfs.__salt__,
  273. {'glusterfs.get_op_version': mock_get_version,
  274. 'glusterfs.set_op_version': mock_set_version}):
  275. mock_get_version.return_value = [False, 'some error message']
  276. ret.update({'result': False})
  277. ret.update({'comment': 'some error message'})
  278. self.assertDictEqual(glusterfs.op_version(name, current), ret)
  279. mock_get_version.return_value = current
  280. ret.update({'result': True})
  281. ret.update({'comment': 'Glusterfs cluster.op-version for {0} already set to {1}'.format(name, current)})
  282. self.assertDictEqual(glusterfs.op_version(name, current), ret)
  283. with patch.dict(glusterfs.__opts__, {'test': True}):
  284. mock_set_version.return_value = [False, 'Failed to set version']
  285. ret.update({'result': None})
  286. ret.update({'comment': 'An attempt would be made to set the cluster.op-version for {0} to {1}.'.
  287. format(name, new)})
  288. self.assertDictEqual(glusterfs.op_version(name, new), ret)
  289. with patch.dict(glusterfs.__opts__, {'test': False}):
  290. mock_set_version.return_value = [False, 'Failed to set version']
  291. ret.update({'result': False})
  292. ret.update({'comment': 'Failed to set version'})
  293. self.assertDictEqual(glusterfs.op_version(name, new), ret)
  294. mock_set_version.return_value = 'some success message'
  295. ret.update({'comment': 'some success message'})
  296. ret.update({'changes': {'old': current, 'new': new}})
  297. ret.update({'result': True})
  298. self.assertDictEqual(glusterfs.op_version(name, new), ret)
  299. # 'max_op_version' function tests: 1
  300. def test_max_op_version(self):
  301. '''
  302. Test setting the Glusterfs to its self reported max-op-version
  303. '''
  304. name = 'salt'
  305. current = 30707
  306. new = 31200
  307. ret = {'name': name,
  308. 'result': False,
  309. 'comment': '',
  310. 'changes': {}}
  311. mock_get_version = MagicMock(return_value={})
  312. mock_get_max_op_version = MagicMock(return_value={})
  313. mock_set_version = MagicMock(return_value={})
  314. with patch.dict(glusterfs.__salt__,
  315. {'glusterfs.get_op_version': mock_get_version,
  316. 'glusterfs.set_op_version': mock_set_version,
  317. 'glusterfs.get_max_op_version': mock_get_max_op_version}):
  318. mock_get_version.return_value = [False, 'some error message']
  319. ret.update({'result': False})
  320. ret.update({'comment': 'some error message'})
  321. self.assertDictEqual(glusterfs.max_op_version(name), ret)
  322. mock_get_version.return_value = current
  323. mock_get_max_op_version.return_value = [False, 'some error message']
  324. ret.update({'result': False})
  325. ret.update({'comment': 'some error message'})
  326. self.assertDictEqual(glusterfs.max_op_version(name), ret)
  327. mock_get_version.return_value = current
  328. mock_get_max_op_version.return_value = current
  329. ret.update({'result': True})
  330. ret.update({'comment': 'The cluster.op-version is already set to the cluster.max-op-version of {0}'.
  331. format(current)})
  332. self.assertDictEqual(glusterfs.max_op_version(name), ret)
  333. with patch.dict(glusterfs.__opts__, {'test': True}):
  334. mock_get_max_op_version.return_value = new
  335. ret.update({'result': None})
  336. ret.update({'comment': 'An attempt would be made to set the cluster.op-version to {0}.'.
  337. format(new)})
  338. self.assertDictEqual(glusterfs.max_op_version(name), ret)
  339. with patch.dict(glusterfs.__opts__, {'test': False}):
  340. mock_set_version.return_value = [False, 'Failed to set version']
  341. ret.update({'result': False})
  342. ret.update({'comment': 'Failed to set version'})
  343. self.assertDictEqual(glusterfs.max_op_version(name), ret)
  344. mock_set_version.return_value = 'some success message'
  345. ret.update({'comment': 'some success message'})
  346. ret.update({'changes': {'old': current, 'new': new}})
  347. ret.update({'result': True})
  348. self.assertDictEqual(glusterfs.max_op_version(name), ret)