test_cmd.py 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. # -*- coding: utf-8 -*-
  2. """
  3. Tests for the file state
  4. """
  5. # Import Python libs
  6. from __future__ import absolute_import, print_function, unicode_literals
  7. import errno
  8. import os
  9. import sys
  10. import tempfile
  11. import textwrap
  12. import time
  13. import pytest
  14. # Import Salt libs
  15. import salt.utils.files
  16. import salt.utils.platform
  17. # Import 3rd-party libs
  18. from salt.ext import six
  19. from tests.support.case import ModuleCase
  20. from tests.support.mixins import SaltReturnAssertsMixin
  21. # Import Salt Testing libs
  22. from tests.support.runtests import RUNTIME_VARS
  23. class CMDTest(ModuleCase, SaltReturnAssertsMixin):
  24. """
  25. Validate the cmd state
  26. """
  27. @classmethod
  28. def setUpClass(cls):
  29. cls.__cmd = "dir" if salt.utils.platform.is_windows() else "ls"
  30. @pytest.mark.slow_test(seconds=5) # Test takes >1 and <=5 seconds
  31. def test_run_simple(self):
  32. """
  33. cmd.run
  34. """
  35. ret = self.run_state("cmd.run", name=self.__cmd, cwd=tempfile.gettempdir())
  36. self.assertSaltTrueReturn(ret)
  37. @pytest.mark.slow_test(seconds=5) # Test takes >1 and <=5 seconds
  38. def test_run_output_loglevel(self):
  39. """
  40. cmd.run with output_loglevel=quiet
  41. """
  42. ret = self.run_state(
  43. "cmd.run",
  44. name=self.__cmd,
  45. cwd=tempfile.gettempdir(),
  46. output_loglevel="quiet",
  47. )
  48. self.assertSaltTrueReturn(ret)
  49. @pytest.mark.slow_test(seconds=1) # Test takes >0.5 and <=1 seconds
  50. def test_test_run_simple(self):
  51. """
  52. cmd.run test interface
  53. """
  54. ret = self.run_state(
  55. "cmd.run", name=self.__cmd, cwd=tempfile.gettempdir(), test=True
  56. )
  57. self.assertSaltNoneReturn(ret)
  58. @pytest.mark.slow_test(seconds=5) # Test takes >1 and <=5 seconds
  59. def test_run_hide_output(self):
  60. """
  61. cmd.run with output hidden
  62. """
  63. ret = self.run_state("cmd.run", name=self.__cmd, hide_output=True)
  64. self.assertSaltTrueReturn(ret)
  65. ret = ret[next(iter(ret))]
  66. self.assertEqual(ret["changes"]["stdout"], "")
  67. self.assertEqual(ret["changes"]["stderr"], "")
  68. class CMDRunRedirectTest(ModuleCase, SaltReturnAssertsMixin):
  69. """
  70. Validate the cmd state of run_redirect
  71. """
  72. def setUp(self):
  73. self.state_name = "run_redirect"
  74. state_filename = self.state_name + ".sls"
  75. self.state_file = os.path.join(RUNTIME_VARS.TMP_STATE_TREE, state_filename)
  76. # Create the testfile and release the handle
  77. fd, self.test_file = tempfile.mkstemp()
  78. try:
  79. os.close(fd)
  80. except OSError as exc:
  81. if exc.errno != errno.EBADF:
  82. six.reraise(*sys.exc_info())
  83. # Create the testfile and release the handle
  84. fd, self.test_tmp_path = tempfile.mkstemp()
  85. try:
  86. os.close(fd)
  87. except OSError as exc:
  88. if exc.errno != errno.EBADF:
  89. six.reraise(*sys.exc_info())
  90. super(CMDRunRedirectTest, self).setUp()
  91. def tearDown(self):
  92. time.sleep(1)
  93. for path in (self.state_file, self.test_tmp_path, self.test_file):
  94. try:
  95. os.remove(path)
  96. except OSError:
  97. # Not all of the tests leave files around that we want to remove
  98. # As some of the tests create the sls files in the test itself,
  99. # And some are using files in the integration test file state tree.
  100. pass
  101. super(CMDRunRedirectTest, self).tearDown()
  102. @pytest.mark.slow_test(seconds=5) # Test takes >1 and <=5 seconds
  103. def test_run_unless(self):
  104. """
  105. test cmd.run unless
  106. """
  107. state_key = "cmd_|-{0}_|-{0}_|-run".format(self.test_tmp_path)
  108. with salt.utils.files.fopen(self.state_file, "w") as fb_:
  109. fb_.write(
  110. salt.utils.stringutils.to_str(
  111. textwrap.dedent(
  112. """
  113. {0}:
  114. cmd.run:
  115. - unless: echo cheese > {1}
  116. """.format(
  117. self.test_tmp_path, self.test_file
  118. )
  119. )
  120. )
  121. )
  122. ret = self.run_function("state.sls", [self.state_name])
  123. self.assertTrue(ret[state_key]["result"])
  124. @pytest.mark.slow_test(seconds=5) # Test takes >1 and <=5 seconds
  125. def test_run_unless_multiple_cmds(self):
  126. """
  127. test cmd.run using multiple unless options where the first cmd in the
  128. list will pass, but the second will fail. This tests the fix for issue
  129. #35384. (The fix is in PR #35545.)
  130. """
  131. sls = self.run_function("state.sls", mods="issue-35384")
  132. self.assertSaltTrueReturn(sls)
  133. # We must assert against the comment here to make sure the comment reads that the
  134. # command "echo "hello"" was run. This ensures that we made it to the last unless
  135. # command in the state. If the comment reads "unless condition is true", or similar,
  136. # then the unless state run bailed out after the first unless command succeeded,
  137. # which is the bug we're regression testing for.
  138. self.assertEqual(
  139. sls['cmd_|-cmd_run_unless_multiple_|-echo "hello"_|-run']["comment"],
  140. 'Command "echo "hello"" run',
  141. )
  142. @pytest.mark.slow_test(seconds=5) # Test takes >1 and <=5 seconds
  143. def test_run_creates_exists(self):
  144. """
  145. test cmd.run creates already there
  146. """
  147. state_key = "cmd_|-echo >> {0}_|-echo >> {0}_|-run".format(self.test_file)
  148. with salt.utils.files.fopen(self.state_file, "w") as fb_:
  149. fb_.write(
  150. salt.utils.stringutils.to_str(
  151. textwrap.dedent(
  152. """
  153. echo >> {0}:
  154. cmd.run:
  155. - creates: {0}
  156. """.format(
  157. self.test_file
  158. )
  159. )
  160. )
  161. )
  162. ret = self.run_function("state.sls", [self.state_name])
  163. self.assertTrue(ret[state_key]["result"])
  164. self.assertEqual(len(ret[state_key]["changes"]), 0)
  165. @pytest.mark.slow_test(seconds=5) # Test takes >1 and <=5 seconds
  166. def test_run_creates_new(self):
  167. """
  168. test cmd.run creates not there
  169. """
  170. os.remove(self.test_file)
  171. state_key = "cmd_|-echo >> {0}_|-echo >> {0}_|-run".format(self.test_file)
  172. with salt.utils.files.fopen(self.state_file, "w") as fb_:
  173. fb_.write(
  174. salt.utils.stringutils.to_str(
  175. textwrap.dedent(
  176. """
  177. echo >> {0}:
  178. cmd.run:
  179. - creates: {0}
  180. """.format(
  181. self.test_file
  182. )
  183. )
  184. )
  185. )
  186. ret = self.run_function("state.sls", [self.state_name])
  187. self.assertTrue(ret[state_key]["result"])
  188. self.assertEqual(len(ret[state_key]["changes"]), 4)
  189. @pytest.mark.slow_test(seconds=5) # Test takes >1 and <=5 seconds
  190. def test_run_redirect(self):
  191. """
  192. test cmd.run with shell redirect
  193. """
  194. state_key = "cmd_|-echo test > {0}_|-echo test > {0}_|-run".format(
  195. self.test_file
  196. )
  197. with salt.utils.files.fopen(self.state_file, "w") as fb_:
  198. fb_.write(
  199. salt.utils.stringutils.to_str(
  200. textwrap.dedent(
  201. """
  202. echo test > {0}:
  203. cmd.run
  204. """.format(
  205. self.test_file
  206. )
  207. )
  208. )
  209. )
  210. ret = self.run_function("state.sls", [self.state_name])
  211. self.assertTrue(ret[state_key]["result"])
  212. class CMDRunWatchTest(ModuleCase, SaltReturnAssertsMixin):
  213. """
  214. Validate the cmd state of run_watch
  215. """
  216. def setUp(self):
  217. self.state_name = "run_watch"
  218. state_filename = self.state_name + ".sls"
  219. self.state_file = os.path.join(RUNTIME_VARS.TMP_STATE_TREE, state_filename)
  220. super(CMDRunWatchTest, self).setUp()
  221. def tearDown(self):
  222. os.remove(self.state_file)
  223. super(CMDRunWatchTest, self).tearDown()
  224. @pytest.mark.slow_test(seconds=5) # Test takes >1 and <=5 seconds
  225. def test_run_watch(self):
  226. """
  227. test cmd.run watch
  228. """
  229. saltines_key = "cmd_|-saltines_|-echo changed=true_|-run"
  230. biscuits_key = "cmd_|-biscuits_|-echo biscuits_|-wait"
  231. with salt.utils.files.fopen(self.state_file, "w") as fb_:
  232. fb_.write(
  233. salt.utils.stringutils.to_str(
  234. textwrap.dedent(
  235. """
  236. saltines:
  237. cmd.run:
  238. - name: echo changed=true
  239. - cwd: /
  240. - stateful: True
  241. biscuits:
  242. cmd.wait:
  243. - name: echo biscuits
  244. - cwd: /
  245. - watch:
  246. - cmd: saltines
  247. """
  248. )
  249. )
  250. )
  251. ret = self.run_function("state.sls", [self.state_name])
  252. self.assertTrue(ret[saltines_key]["result"])
  253. self.assertTrue(ret[biscuits_key]["result"])