test_test.py 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  1. # -*- coding: utf-8 -*-
  2. '''
  3. :codeauthor: Rahul Handay <rahulha@saltstack.com>
  4. '''
  5. # Import Python Libs
  6. from __future__ import absolute_import, print_function, unicode_literals
  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. patch,
  12. MagicMock,
  13. )
  14. # Import Salt Libs
  15. from salt.exceptions import SaltInvocationError
  16. import salt.states.test as test
  17. from salt.utils.odict import OrderedDict
  18. from salt.ext import six
  19. class TestTestCase(TestCase, LoaderModuleMockMixin):
  20. '''
  21. Validate the test state
  22. '''
  23. def setup_loader_modules(self):
  24. return {test: {'__low__': {'__reqs__': {'watch': ''}}}}
  25. def test_succeed_without_changes(self):
  26. '''
  27. Test to returns successful.
  28. '''
  29. ret = {'name': 'salt',
  30. 'changes': {},
  31. 'result': True,
  32. 'comment': ''}
  33. with patch.dict(test.__opts__, {"test": False}):
  34. ret.update({'comment': 'Success!'})
  35. self.assertDictEqual(test.succeed_without_changes('salt'), ret)
  36. def test_fail_without_changes(self):
  37. '''
  38. Test to returns failure.
  39. '''
  40. ret = {'name': 'salt',
  41. 'changes': {},
  42. 'result': False,
  43. 'comment': ''}
  44. with patch.dict(test.__opts__, {"test": False}):
  45. ret.update({'comment': 'Failure!'})
  46. self.assertDictEqual(test.fail_without_changes('salt'), ret)
  47. def test_succeed_with_changes(self):
  48. '''
  49. Test to returns successful and changes is not empty
  50. '''
  51. ret = {'name': 'salt',
  52. 'changes': {},
  53. 'result': False,
  54. 'comment': ''}
  55. with patch.dict(test.__opts__, {"test": False}):
  56. ret.update({'changes': {'testing': {'new': 'Something pretended'
  57. ' to change',
  58. 'old': 'Unchanged'}},
  59. 'comment': 'Success!', 'result': True})
  60. self.assertDictEqual(test.succeed_with_changes('salt'), ret)
  61. def test_fail_with_changes(self):
  62. '''
  63. Test to returns failure and changes is not empty.
  64. '''
  65. ret = {'name': 'salt',
  66. 'changes': {},
  67. 'result': False,
  68. 'comment': ''}
  69. with patch.dict(test.__opts__, {"test": False}):
  70. ret.update({'changes': {'testing': {'new': 'Something pretended'
  71. ' to change',
  72. 'old': 'Unchanged'}},
  73. 'comment': 'Success!',
  74. 'result': True})
  75. self.assertDictEqual(test.succeed_with_changes('salt'), ret)
  76. def test_configurable_test_state(self):
  77. '''
  78. Test test.configurable_test_state with and without comment
  79. '''
  80. # Configure mock parameters
  81. mock_name = 'cheese_shop'
  82. mock_comment = "I'm afraid we're fresh out of Red Leicester sir."
  83. mock_changes = {
  84. 'testing': {
  85. 'old': 'Unchanged',
  86. 'new': 'Something pretended to change'
  87. }
  88. }
  89. # Test default state with comment
  90. with patch.dict(test.__opts__, {'test': False}):
  91. mock_ret = {'name': mock_name,
  92. 'changes': mock_changes,
  93. 'result': True,
  94. 'comment': ''}
  95. ret = test.configurable_test_state(mock_name)
  96. self.assertDictEqual(ret, mock_ret)
  97. # Test default state without comment
  98. with patch.dict(test.__opts__, {'test': False}):
  99. mock_ret = {'name': mock_name,
  100. 'changes': mock_changes,
  101. 'result': True,
  102. 'comment': mock_comment}
  103. ret = test.configurable_test_state(mock_name,
  104. comment=mock_comment)
  105. self.assertDictEqual(ret, mock_ret)
  106. def test_configurable_test_state_changes(self):
  107. '''
  108. Test test.configurable_test_state with permutations of changes and with
  109. comment
  110. '''
  111. # Configure mock parameters
  112. mock_name = 'cheese_shop'
  113. mock_comment = "I'm afraid we're fresh out of Red Leicester sir."
  114. mock_changes = {
  115. 'testing': {
  116. 'old': 'Unchanged',
  117. 'new': 'Something pretended to change'
  118. }
  119. }
  120. # Test changes=Random and comment
  121. with patch.dict(test.__opts__, {'test': False}):
  122. ret = test.configurable_test_state(mock_name,
  123. changes='Random',
  124. comment=mock_comment)
  125. self.assertEqual(ret['name'], mock_name)
  126. self.assertIn(ret['changes'], [mock_changes, {}])
  127. self.assertEqual(ret['result'], True)
  128. self.assertEqual(ret['comment'], mock_comment)
  129. # Test changes=True and comment
  130. with patch.dict(test.__opts__, {'test': False}):
  131. mock_ret = {'name': mock_name,
  132. 'changes': mock_changes,
  133. 'result': True,
  134. 'comment': mock_comment}
  135. ret = test.configurable_test_state(mock_name,
  136. changes=True,
  137. comment=mock_comment)
  138. self.assertDictEqual(ret, mock_ret)
  139. # Test changes=False and comment
  140. with patch.dict(test.__opts__, {'test': False}):
  141. mock_ret = {'name': mock_name,
  142. 'changes': {},
  143. 'result': True,
  144. 'comment': mock_comment}
  145. ret = test.configurable_test_state(mock_name,
  146. changes=False,
  147. comment=mock_comment)
  148. self.assertDictEqual(ret, mock_ret)
  149. # Test changes=Cheese
  150. with patch.dict(test.__opts__, {'test': False}):
  151. self.assertRaises(SaltInvocationError,
  152. test.configurable_test_state,
  153. mock_name,
  154. changes='Cheese')
  155. def test_configurable_test_state_result(self):
  156. '''
  157. Test test.configurable_test_state with permutations of result and with
  158. comment
  159. '''
  160. # Configure mock parameters
  161. mock_name = 'cheese_shop'
  162. mock_comment = "I'm afraid we're fresh out of Red Leicester sir."
  163. mock_changes = {
  164. 'testing': {
  165. 'old': 'Unchanged',
  166. 'new': 'Something pretended to change'
  167. }
  168. }
  169. # Test result=Random and comment
  170. with patch.dict(test.__opts__, {'test': False}):
  171. ret = test.configurable_test_state(mock_name,
  172. result='Random',
  173. comment=mock_comment)
  174. self.assertEqual(ret['name'], mock_name)
  175. self.assertEqual(ret['changes'], mock_changes)
  176. self.assertIn(ret['result'], [True, False])
  177. self.assertEqual(ret['comment'], mock_comment)
  178. # Test result=True and comment
  179. with patch.dict(test.__opts__, {'test': False}):
  180. mock_ret = {'name': mock_name,
  181. 'changes': mock_changes,
  182. 'result': True,
  183. 'comment': mock_comment}
  184. ret = test.configurable_test_state(mock_name,
  185. result=True,
  186. comment=mock_comment)
  187. self.assertDictEqual(ret, mock_ret)
  188. # Test result=False and comment
  189. with patch.dict(test.__opts__, {'test': False}):
  190. mock_ret = {'name': mock_name,
  191. 'changes': mock_changes,
  192. 'result': False,
  193. 'comment': mock_comment}
  194. ret = test.configurable_test_state(mock_name,
  195. result=False,
  196. comment=mock_comment)
  197. self.assertDictEqual(ret, mock_ret)
  198. # Test result=Cheese
  199. with patch.dict(test.__opts__, {'test': False}):
  200. self.assertRaises(SaltInvocationError,
  201. test.configurable_test_state,
  202. mock_name,
  203. result='Cheese')
  204. def test_configurable_test_state_warnings(self):
  205. '''
  206. Test test.configurable_test_state with and without warnings
  207. '''
  208. # Configure mock parameters
  209. mock_name = 'cheese_shop'
  210. mock_comment = "I'm afraid we're fresh out of Red Leicester sir."
  211. mock_warning = 'Today the van broke down.'
  212. mock_warning_list = [
  213. mock_warning,
  214. "Oooooooooohhh........!"
  215. ]
  216. mock_changes = {
  217. 'testing': {
  218. 'old': 'Unchanged',
  219. 'new': 'Something pretended to change'
  220. }
  221. }
  222. # Test default state without warnings
  223. with patch.dict(test.__opts__, {'test': False}):
  224. mock_ret = {'name': mock_name,
  225. 'changes': mock_changes,
  226. 'result': True,
  227. 'comment': ''}
  228. ret = test.configurable_test_state(mock_name)
  229. self.assertDictEqual(ret, mock_ret)
  230. # Test default state with warnings (string)
  231. with patch.dict(test.__opts__, {'test': False}):
  232. mock_ret = {'name': mock_name,
  233. 'changes': mock_changes,
  234. 'result': True,
  235. 'comment': '',
  236. 'warnings': mock_warning_list}
  237. ret = test.configurable_test_state(mock_name,
  238. warnings=mock_warning_list)
  239. self.assertDictEqual(ret, mock_ret)
  240. # Test default state with warnings (list)
  241. with patch.dict(test.__opts__, {'test': False}):
  242. mock_ret = {'name': mock_name,
  243. 'changes': mock_changes,
  244. 'result': True,
  245. 'comment': '',
  246. 'warnings': ['Today the van broke down.']}
  247. ret = test.configurable_test_state(mock_name,
  248. warnings=mock_warning)
  249. self.assertDictEqual(ret, mock_ret)
  250. def test_configurable_test_state_test(self):
  251. '''
  252. Test test.configurable_test_state with test=True with and without
  253. comment
  254. '''
  255. # Configure mock parameters
  256. mock_name = 'cheese_shop'
  257. mock_comment = "I'm afraid we're fresh out of Red Leicester sir."
  258. mock_changes = {
  259. 'testing': {
  260. 'old': 'Unchanged',
  261. 'new': 'Something pretended to change'
  262. }
  263. }
  264. # Test test=True without comment
  265. with patch.dict(test.__opts__, {'test': True}):
  266. mock_ret = {'name': mock_name,
  267. 'changes': mock_changes,
  268. 'result': None,
  269. 'comment': 'This is a test'}
  270. ret = test.configurable_test_state(mock_name)
  271. self.assertDictEqual(ret, mock_ret)
  272. # Test test=True with comment
  273. with patch.dict(test.__opts__, {'test': True}):
  274. mock_ret = {'name': mock_name,
  275. 'changes': mock_changes,
  276. 'result': None,
  277. 'comment': mock_comment}
  278. ret = test.configurable_test_state(mock_name,
  279. comment=mock_comment)
  280. self.assertDictEqual(ret, mock_ret)
  281. # Test test=True and changes=True with comment
  282. with patch.dict(test.__opts__, {'test': True}):
  283. mock_ret = {'name': mock_name,
  284. 'changes': mock_changes,
  285. 'result': None,
  286. 'comment': mock_comment}
  287. ret = test.configurable_test_state(mock_name,
  288. changes=True,
  289. comment=mock_comment)
  290. self.assertDictEqual(ret, mock_ret)
  291. # Test test=True and changes=False with comment
  292. with patch.dict(test.__opts__, {'test': True}):
  293. mock_ret = {'name': mock_name,
  294. 'changes': {},
  295. 'result': True,
  296. 'comment': mock_comment}
  297. ret = test.configurable_test_state(mock_name,
  298. changes=False,
  299. comment=mock_comment)
  300. self.assertDictEqual(ret, mock_ret)
  301. def test_mod_watch(self):
  302. '''
  303. Test to call this function via a watch statement
  304. '''
  305. ret = {'name': 'salt',
  306. 'changes': {},
  307. 'result': True,
  308. 'comment': ''}
  309. ret.update({'changes': {'Requisites with changes': []},
  310. 'comment': 'Watch statement fired.'})
  311. self.assertDictEqual(test.mod_watch('salt'), ret)
  312. def test_check_pillar_present(self):
  313. '''
  314. Test to ensure the check_pillar function
  315. works properly with the 'present' keyword in
  316. the absence of a 'type' keyword.
  317. '''
  318. ret = {
  319. 'name': 'salt',
  320. 'changes': {},
  321. 'result': True,
  322. 'comment': ''
  323. }
  324. pillar_return = 'I am a pillar.'
  325. pillar_mock = MagicMock(return_value=pillar_return)
  326. with patch.dict(test.__salt__, {'pillar.get': pillar_mock}):
  327. self.assertEqual(test.check_pillar('salt', present='my_pillar'), ret)
  328. def test_check_pillar_string(self):
  329. '''
  330. Test to ensure the check_pillar function
  331. works properly with the 'key_type' checks,
  332. using the string key_type.
  333. '''
  334. ret = {
  335. 'name': 'salt',
  336. 'changes': {},
  337. 'result': True,
  338. 'comment': ''
  339. }
  340. pillar_return = 'I am a pillar.'
  341. pillar_mock = MagicMock(return_value=pillar_return)
  342. with patch.dict(test.__salt__, {'pillar.get': pillar_mock}):
  343. self.assertEqual(test.check_pillar('salt', string='my_pillar'), ret)
  344. # With unicode (py2) or str (py3) strings
  345. pillar_return = six.text_type('I am a pillar.')
  346. pillar_mock = MagicMock(return_value=pillar_return)
  347. with patch.dict(test.__salt__, {'pillar.get': pillar_mock}):
  348. self.assertEqual(test.check_pillar('salt', string='my_pillar'), ret)
  349. # With a dict
  350. pillar_return = {'this': 'dictionary'}
  351. pillar_mock = MagicMock(return_value=pillar_return)
  352. with patch.dict(test.__salt__, {'pillar.get': pillar_mock}):
  353. self.assertFalse(test.check_pillar('salt', string='my_pillar')['result'])
  354. # With a list
  355. pillar_return = ['I am a pillar.']
  356. pillar_mock = MagicMock(return_value=pillar_return)
  357. with patch.dict(test.__salt__, {'pillar.get': pillar_mock}):
  358. self.assertFalse(test.check_pillar('salt', string='my_pillar')['result'])
  359. # With a boolean
  360. pillar_return = True
  361. pillar_mock = MagicMock(return_value=pillar_return)
  362. with patch.dict(test.__salt__, {'pillar.get': pillar_mock}):
  363. self.assertFalse(test.check_pillar('salt', string='my_pillar')['result'])
  364. # With an int
  365. pillar_return = 1
  366. pillar_mock = MagicMock(return_value=pillar_return)
  367. with patch.dict(test.__salt__, {'pillar.get': pillar_mock}):
  368. self.assertFalse(test.check_pillar('salt', string='my_pillar')['result'])
  369. def test_check_pillar_dictionary(self):
  370. '''
  371. Test to ensure the check_pillar function
  372. works properly with the 'key_type' checks,
  373. using the dictionary key_type.
  374. '''
  375. ret = {
  376. 'name': 'salt',
  377. 'changes': {},
  378. 'result': True,
  379. 'comment': ''
  380. }
  381. pillar_return = {'this': 'dictionary'}
  382. pillar_mock = MagicMock(return_value=pillar_return)
  383. with patch.dict(test.__salt__, {'pillar.get': pillar_mock}):
  384. self.assertEqual(test.check_pillar('salt', dictionary='my_pillar'), ret)
  385. # With an ordered dict
  386. pillar_return = OrderedDict({'this': 'dictionary'})
  387. pillar_mock = MagicMock(return_value=pillar_return)
  388. with patch.dict(test.__salt__, {'pillar.get': pillar_mock}):
  389. self.assertEqual(test.check_pillar('salt', dictionary='my_pillar'), ret)
  390. # With a string
  391. pillar_return = 'I am a pillar.'
  392. pillar_mock = MagicMock(return_value=pillar_return)
  393. with patch.dict(test.__salt__, {'pillar.get': pillar_mock}):
  394. self.assertFalse(test.check_pillar('salt', dictionary='my_pillar')['result'])
  395. # With a list
  396. pillar_return = ['I am a pillar.']
  397. pillar_mock = MagicMock(return_value=pillar_return)
  398. with patch.dict(test.__salt__, {'pillar.get': pillar_mock}):
  399. self.assertFalse(test.check_pillar('salt', dictionary='my_pillar')['result'])
  400. # With a boolean
  401. pillar_return = True
  402. pillar_mock = MagicMock(return_value=pillar_return)
  403. with patch.dict(test.__salt__, {'pillar.get': pillar_mock}):
  404. self.assertFalse(test.check_pillar('salt', dictionary='my_pillar')['result'])
  405. # With an int
  406. pillar_return = 1
  407. pillar_mock = MagicMock(return_value=pillar_return)
  408. with patch.dict(test.__salt__, {'pillar.get': pillar_mock}):
  409. self.assertFalse(test.check_pillar('salt', dictionary='my_pillar')['result'])