test_state.py 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. # -*- coding: utf-8 -*-
  2. # Import Python libs
  3. from __future__ import absolute_import, print_function, unicode_literals
  4. import os
  5. import shutil
  6. import threading
  7. import time
  8. import logging
  9. # Import Salt Testing Libs
  10. from tests.support.case import SSHCase
  11. from tests.support.helpers import flaky
  12. from tests.support.paths import TMP
  13. # Import Salt Libs
  14. from salt.ext import six
  15. from salt.ext.six.moves import range # pylint: disable=redefined-builtin
  16. SSH_SLS = 'ssh_state_tests'
  17. SSH_SLS_FILE = '/tmp/test'
  18. log = logging.getLogger(__name__)
  19. class SSHStateTest(SSHCase):
  20. '''
  21. testing the state system with salt-ssh
  22. '''
  23. def _check_dict_ret(self, ret, val, exp_ret, equal=True):
  24. self.assertIsInstance(ret, dict)
  25. for key, value in ret.items():
  26. self.assertIsInstance(value, dict)
  27. if equal:
  28. self.assertEqual(value[val], exp_ret)
  29. else:
  30. self.assertNotEqual(value[val], exp_ret)
  31. def _check_request(self, empty=False):
  32. check = self.run_function('state.check_request', wipe=False)
  33. if empty:
  34. self.assertFalse(bool(check), 'bool({0}) is not False'.format(check))
  35. else:
  36. self._check_dict_ret(ret=check['default']['test_run']['local']['return'],
  37. val='__sls__', exp_ret=SSH_SLS)
  38. def test_state_apply(self):
  39. '''
  40. test state.apply with salt-ssh
  41. '''
  42. ret = self.run_function('state.apply', [SSH_SLS])
  43. self._check_dict_ret(ret=ret, val='__sls__', exp_ret=SSH_SLS)
  44. check_file = self.run_function('file.file_exists', ['/tmp/test'])
  45. self.assertTrue(check_file)
  46. def test_state_sls_id(self):
  47. '''
  48. test state.sls_id with salt-ssh
  49. '''
  50. # check state.sls_id with test=True
  51. ret = self.run_function('state.sls_id', ['ssh-file-test', SSH_SLS,
  52. 'test=True'])
  53. self._check_dict_ret(ret=ret, val='comment',
  54. exp_ret='The file /tmp/test is set to be changed\nNote: No changes made, actual changes may\nbe different due to other states.')
  55. # check state.sls_id without test=True
  56. ret = self.run_function('state.sls_id', ['ssh-file-test', SSH_SLS])
  57. self._check_dict_ret(ret=ret, val='__sls__', exp_ret=SSH_SLS)
  58. # make sure the other id in the state was not run
  59. self._check_dict_ret(ret=ret, val='__id__',
  60. exp_ret='second_id', equal=False)
  61. check_file = self.run_function('file.file_exists', ['/tmp/test'])
  62. self.assertTrue(check_file)
  63. def test_state_sls_wrong_id(self):
  64. '''
  65. test state.sls_id when id does not exist
  66. '''
  67. # check state.sls_id with test=True
  68. ret = self.run_function('state.sls_id', ['doesnotexist', SSH_SLS])
  69. assert 'No matches for ID' in ret
  70. def test_state_show_sls(self):
  71. '''
  72. test state.show_sls with salt-ssh
  73. '''
  74. ret = self.run_function('state.show_sls', [SSH_SLS])
  75. self._check_dict_ret(ret=ret, val='__sls__', exp_ret=SSH_SLS)
  76. check_file = self.run_function('file.file_exists', [SSH_SLS_FILE], wipe=False)
  77. self.assertFalse(check_file)
  78. def test_state_show_top(self):
  79. '''
  80. test state.show_top with salt-ssh
  81. '''
  82. ret = self.run_function('state.show_top')
  83. self.assertEqual(ret, {'base': ['core', 'master_tops_test']})
  84. def test_state_single(self):
  85. '''
  86. state.single with salt-ssh
  87. '''
  88. ret_out = {'name': 'itworked',
  89. 'result': True,
  90. 'comment': 'Success!'}
  91. single = self.run_function('state.single',
  92. ['test.succeed_with_changes name=itworked'])
  93. self.assertIsInstance(single, dict)
  94. for key, value in six.iteritems(single):
  95. self.assertIsInstance(value, dict)
  96. self.assertEqual(value['name'], ret_out['name'])
  97. self.assertEqual(value['result'], ret_out['result'])
  98. self.assertEqual(value['comment'], ret_out['comment'])
  99. def test_show_highstate(self):
  100. '''
  101. state.show_highstate with salt-ssh
  102. '''
  103. high = self.run_function('state.show_highstate')
  104. destpath = os.path.join(TMP, 'testfile')
  105. self.assertIsInstance(high, dict)
  106. self.assertIn(destpath, high)
  107. self.assertEqual(high[destpath]['__env__'], 'base')
  108. def test_state_high(self):
  109. '''
  110. state.high with salt-ssh
  111. '''
  112. ret_out = {'name': 'itworked',
  113. 'result': True,
  114. 'comment': 'Success!'}
  115. high = self.run_function('state.high',
  116. ['"{"itworked": {"test": ["succeed_with_changes"]}}"'])
  117. self.assertIsInstance(high, dict)
  118. for key, value in six.iteritems(high):
  119. self.assertIsInstance(value, dict)
  120. self.assertEqual(value['name'], ret_out['name'])
  121. self.assertEqual(value['result'], ret_out['result'])
  122. self.assertEqual(value['comment'], ret_out['comment'])
  123. def test_show_lowstate(self):
  124. '''
  125. state.show_lowstate with salt-ssh
  126. '''
  127. low = self.run_function('state.show_lowstate')
  128. self.assertIsInstance(low, list)
  129. self.assertIsInstance(low[0], dict)
  130. def test_state_low(self):
  131. '''
  132. state.low with salt-ssh
  133. '''
  134. ret_out = {'name': 'itworked',
  135. 'result': True,
  136. 'comment': 'Success!'}
  137. low = self.run_function(
  138. 'state.low',
  139. ['"{"state": "test", "fun": "succeed_with_changes", "name": "itworked"}"'])
  140. self.assertIsInstance(low, dict)
  141. for key, value in six.iteritems(low):
  142. self.assertIsInstance(value, dict)
  143. self.assertEqual(value['name'], ret_out['name'])
  144. self.assertEqual(value['result'], ret_out['result'])
  145. self.assertEqual(value['comment'], ret_out['comment'])
  146. def test_state_request_check_clear(self):
  147. '''
  148. test state.request system with salt-ssh
  149. while also checking and clearing request
  150. '''
  151. request = self.run_function('state.request', [SSH_SLS], wipe=False)
  152. self._check_dict_ret(ret=request, val='__sls__', exp_ret=SSH_SLS)
  153. self._check_request()
  154. clear = self.run_function('state.clear_request', wipe=False)
  155. self._check_request(empty=True)
  156. def test_state_run_request(self):
  157. '''
  158. test state.request system with salt-ssh
  159. while also running the request later
  160. '''
  161. request = self.run_function('state.request', [SSH_SLS], wipe=False)
  162. self._check_dict_ret(ret=request, val='__sls__', exp_ret=SSH_SLS)
  163. run = self.run_function('state.run_request', wipe=False)
  164. check_file = self.run_function('file.file_exists', [SSH_SLS_FILE], wipe=False)
  165. self.assertTrue(check_file)
  166. @flaky
  167. def test_state_running(self):
  168. '''
  169. test state.running with salt-ssh
  170. '''
  171. def _run_in_background():
  172. self.run_function('state.sls', ['running'], wipe=False)
  173. bg_thread = threading.Thread(target=_run_in_background)
  174. bg_thread.start()
  175. expected = 'The function "state.pkg" is running as'
  176. state_ret = []
  177. for _ in range(30):
  178. time.sleep(5)
  179. get_sls = self.run_function('state.running', wipe=False)
  180. state_ret.append(get_sls)
  181. if expected in ' '.join(get_sls):
  182. # We found the expected return
  183. break
  184. else:
  185. self.fail(
  186. 'Did not find \'{0}\' in state.running return: {1}'.format(expected, state_ret)
  187. )
  188. # make sure we wait until the earlier state is complete
  189. future = time.time() + 120
  190. while True:
  191. if expected not in ' '.join(self.run_function('state.running', wipe=False)):
  192. break
  193. if time.time() > future:
  194. self.fail('state.pkg is still running overtime. Test did not clean up correctly.')
  195. def tearDown(self):
  196. '''
  197. make sure to clean up any old ssh directories
  198. '''
  199. salt_dir = self.run_function('config.get', ['thin_dir'], wipe=False)
  200. self.assertIsInstance(salt_dir, six.string_types)
  201. if os.path.exists(salt_dir):
  202. shutil.rmtree(salt_dir)
  203. if os.path.exists(SSH_SLS_FILE):
  204. os.remove(SSH_SLS_FILE)