test_state.py 9.2 KB

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