test_state.py 9.0 KB

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