test_cmd.py 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. # -*- coding: utf-8 -*-
  2. """
  3. :codeauthor: Jayesh Kariya <jayeshk@saltstack.com>
  4. """
  5. # Import Python libs
  6. from __future__ import absolute_import, print_function, unicode_literals
  7. import os.path
  8. # Import Salt Libs
  9. import salt.states.cmd as cmd
  10. from salt.exceptions import CommandExecutionError
  11. # Import Salt Testing Libs
  12. from tests.support.mixins import LoaderModuleMockMixin
  13. from tests.support.mock import MagicMock, patch
  14. from tests.support.unit import TestCase
  15. class CmdTestCase(TestCase, LoaderModuleMockMixin):
  16. """
  17. Test cases for salt.states.cmd
  18. """
  19. def setup_loader_modules(self):
  20. return {cmd: {"__env__": "base"}}
  21. # 'mod_run_check' function tests: 1
  22. def test_mod_run_check(self):
  23. """
  24. Test to execute the onlyif and unless logic.
  25. """
  26. cmd_kwargs = {}
  27. creates = "/tmp"
  28. mock = MagicMock(return_value=1)
  29. with patch.dict(cmd.__salt__, {"cmd.retcode": mock}):
  30. with patch.dict(cmd.__opts__, {"test": True}):
  31. ret = {
  32. "comment": "onlyif condition is false",
  33. "result": True,
  34. "skip_watch": True,
  35. }
  36. self.assertDictEqual(
  37. cmd.mod_run_check(cmd_kwargs, "", "", creates), ret
  38. )
  39. self.assertDictEqual(
  40. cmd.mod_run_check(cmd_kwargs, {}, "", creates), ret
  41. )
  42. mock = MagicMock(return_value=1)
  43. with patch.dict(cmd.__salt__, {"cmd.retcode": mock}):
  44. with patch.dict(cmd.__opts__, {"test": True}):
  45. ret = {
  46. "comment": "onlyif condition is false: ",
  47. "result": True,
  48. "skip_watch": True,
  49. }
  50. self.assertDictEqual(
  51. cmd.mod_run_check(cmd_kwargs, [""], "", creates), ret
  52. )
  53. mock = MagicMock(return_value=0)
  54. with patch.dict(cmd.__salt__, {"cmd.retcode": mock}):
  55. ret = {
  56. "comment": "unless condition is true",
  57. "result": True,
  58. "skip_watch": True,
  59. }
  60. self.assertDictEqual(cmd.mod_run_check(cmd_kwargs, None, "", creates), ret)
  61. self.assertDictEqual(
  62. cmd.mod_run_check(cmd_kwargs, None, [""], creates), ret
  63. )
  64. self.assertDictEqual(
  65. cmd.mod_run_check(cmd_kwargs, None, True, creates), ret
  66. )
  67. with patch.object(os.path, "exists", MagicMock(sid_effect=[True, True, False])):
  68. ret = {"comment": "/tmp exists", "result": True}
  69. self.assertDictEqual(
  70. cmd.mod_run_check(cmd_kwargs, None, None, creates), ret
  71. )
  72. ret = {"comment": "All files in creates exist", "result": True}
  73. self.assertDictEqual(
  74. cmd.mod_run_check(cmd_kwargs, None, None, [creates]), ret
  75. )
  76. self.assertTrue(cmd.mod_run_check(cmd_kwargs, None, None, {}))
  77. # 'wait' function tests: 1
  78. def test_wait(self):
  79. """
  80. Test to run the given command only if the watch statement calls it.
  81. """
  82. name = "cmd.script"
  83. ret = {"name": name, "result": True, "changes": {}, "comment": ""}
  84. self.assertDictEqual(cmd.wait(name), ret)
  85. # 'wait_script' function tests: 1
  86. def test_wait_script(self):
  87. """
  88. Test to download a script from a remote source and execute it
  89. only if a watch statement calls it.
  90. """
  91. name = "cmd.script"
  92. ret = {"name": name, "result": True, "changes": {}, "comment": ""}
  93. self.assertDictEqual(cmd.wait_script(name), ret)
  94. # 'run' function tests: 1
  95. def test_run(self):
  96. """
  97. Test to run a command if certain circumstances are met.
  98. """
  99. name = "cmd.script"
  100. ret = {"name": name, "result": False, "changes": {}, "comment": ""}
  101. with patch.dict(cmd.__opts__, {"test": False}):
  102. comt = "Invalidly-formatted 'env' parameter. See documentation."
  103. ret.update({"comment": comt})
  104. self.assertDictEqual(cmd.run(name, env="salt"), ret)
  105. with patch.dict(cmd.__grains__, {"shell": "shell"}):
  106. with patch.dict(cmd.__opts__, {"test": False}):
  107. mock = MagicMock(side_effect=[CommandExecutionError, {"retcode": 1}])
  108. with patch.dict(cmd.__salt__, {"cmd.run_all": mock}):
  109. ret.update({"comment": "", "result": False})
  110. self.assertDictEqual(cmd.run(name), ret)
  111. ret.update(
  112. {
  113. "comment": 'Command "cmd.script" run',
  114. "result": False,
  115. "changes": {"retcode": 1},
  116. }
  117. )
  118. self.assertDictEqual(cmd.run(name), ret)
  119. with patch.dict(cmd.__opts__, {"test": True}):
  120. comt = 'Command "cmd.script" would have been executed'
  121. ret.update({"comment": comt, "result": None, "changes": {}})
  122. self.assertDictEqual(cmd.run(name), ret)
  123. mock = MagicMock(return_value=1)
  124. with patch.dict(cmd.__salt__, {"cmd.retcode": mock}):
  125. with patch.dict(cmd.__opts__, {"test": False}):
  126. comt = "onlyif condition is false"
  127. ret.update({"comment": comt, "result": True, "skip_watch": True})
  128. self.assertDictEqual(cmd.run(name, onlyif=""), ret)
  129. def test_run_root(self):
  130. """
  131. Test to run a command with a different root
  132. """
  133. name = "cmd.script"
  134. ret = {"name": name, "result": False, "changes": {}, "comment": ""}
  135. with patch.dict(cmd.__grains__, {"shell": "shell"}):
  136. with patch.dict(cmd.__opts__, {"test": False}):
  137. mock = MagicMock(side_effect=[CommandExecutionError, {"retcode": 1}])
  138. with patch.dict(cmd.__salt__, {"cmd.run_chroot": mock}):
  139. ret.update({"comment": "", "result": False})
  140. self.assertDictEqual(cmd.run(name, root="/mnt"), ret)
  141. ret.update(
  142. {
  143. "comment": 'Command "cmd.script" run',
  144. "result": False,
  145. "changes": {"retcode": 1},
  146. }
  147. )
  148. self.assertDictEqual(cmd.run(name, root="/mnt"), ret)
  149. # 'script' function tests: 1
  150. def test_script(self):
  151. """
  152. Test to download a script and execute it with specified arguments.
  153. """
  154. name = "cmd.script"
  155. ret = {"name": name, "result": False, "changes": {}, "comment": ""}
  156. with patch.dict(cmd.__opts__, {"test": False}):
  157. comt = "Invalidly-formatted 'env' parameter. See documentation."
  158. ret.update({"comment": comt})
  159. self.assertDictEqual(cmd.script(name, env="salt"), ret)
  160. with patch.dict(cmd.__grains__, {"shell": "shell"}):
  161. with patch.dict(cmd.__opts__, {"test": True}):
  162. comt = "Command 'cmd.script' would have been executed"
  163. ret.update({"comment": comt, "result": None, "changes": {}})
  164. self.assertDictEqual(cmd.script(name), ret)
  165. with patch.dict(cmd.__opts__, {"test": False}):
  166. mock = MagicMock(side_effect=[CommandExecutionError, {"retcode": 1}])
  167. with patch.dict(cmd.__salt__, {"cmd.script": mock}):
  168. ret.update({"comment": "", "result": False})
  169. self.assertDictEqual(cmd.script(name), ret)
  170. ret.update(
  171. {
  172. "comment": "Command 'cmd.script' run",
  173. "result": False,
  174. "changes": {"retcode": 1},
  175. }
  176. )
  177. self.assertDictEqual(cmd.script(name), ret)
  178. mock = MagicMock(return_value=1)
  179. with patch.dict(cmd.__salt__, {"cmd.retcode": mock}):
  180. with patch.dict(cmd.__opts__, {"test": False}):
  181. comt = "onlyif condition is false"
  182. ret.update(
  183. {
  184. "comment": comt,
  185. "result": True,
  186. "skip_watch": True,
  187. "changes": {},
  188. }
  189. )
  190. self.assertDictEqual(cmd.script(name, onlyif=""), ret)
  191. # 'call' function tests: 1
  192. def test_call(self):
  193. """
  194. Test to invoke a pre-defined Python function with arguments
  195. specified in the state declaration.
  196. """
  197. name = "cmd.script"
  198. # func = 'myfunc'
  199. ret = {"name": name, "result": False, "changes": {}, "comment": ""}
  200. flag = None
  201. def func():
  202. """
  203. Mock func method
  204. """
  205. if flag:
  206. return {}
  207. else:
  208. return []
  209. with patch.dict(cmd.__grains__, {"shell": "shell"}):
  210. flag = True
  211. self.assertDictEqual(cmd.call(name, func), ret)
  212. flag = False
  213. comt = "onlyif condition is false"
  214. ret.update({"comment": "", "result": False, "changes": {"retval": []}})
  215. self.assertDictEqual(cmd.call(name, func), ret)
  216. mock = MagicMock(return_value=1)
  217. with patch.dict(cmd.__salt__, {"cmd.retcode": mock}):
  218. with patch.dict(cmd.__opts__, {"test": True}):
  219. comt = "onlyif condition is false"
  220. ret.update(
  221. {
  222. "comment": comt,
  223. "skip_watch": True,
  224. "result": True,
  225. "changes": {},
  226. }
  227. )
  228. self.assertDictEqual(cmd.call(name, func, onlyif=""), ret)
  229. # 'wait_call' function tests: 1
  230. def test_wait_call(self):
  231. """
  232. Test to run wait_call.
  233. """
  234. name = "cmd.script"
  235. func = "myfunc"
  236. ret = {"name": name, "result": True, "changes": {}, "comment": ""}
  237. self.assertDictEqual(cmd.wait_call(name, func), ret)
  238. # 'mod_watch' function tests: 1
  239. def test_mod_watch(self):
  240. """
  241. Test to execute a cmd function based on a watch call
  242. """
  243. name = "cmd.script"
  244. ret = {"name": name, "result": False, "changes": {}, "comment": ""}
  245. def func():
  246. """
  247. Mock func method
  248. """
  249. return {}
  250. with patch.dict(cmd.__grains__, {"shell": "shell"}):
  251. with patch.dict(cmd.__opts__, {"test": False}):
  252. mock = MagicMock(return_value={"retcode": 1})
  253. with patch.dict(cmd.__salt__, {"cmd.run_all": mock}):
  254. self.assertDictEqual(
  255. cmd.mod_watch(name, sfun="wait", stateful=True), ret
  256. )
  257. comt = 'Command "cmd.script" run'
  258. ret.update({"comment": comt, "changes": {"retcode": 1}})
  259. self.assertDictEqual(
  260. cmd.mod_watch(name, sfun="wait", stateful=False), ret
  261. )
  262. with patch.dict(cmd.__salt__, {"cmd.script": mock}):
  263. ret.update({"comment": "", "changes": {}})
  264. self.assertDictEqual(
  265. cmd.mod_watch(name, sfun="script", stateful=True), ret
  266. )
  267. comt = "Command 'cmd.script' run"
  268. ret.update({"comment": comt, "changes": {"retcode": 1}})
  269. self.assertDictEqual(
  270. cmd.mod_watch(name, sfun="script", stateful=False), ret
  271. )
  272. with patch.dict(cmd.__salt__, {"cmd.script": mock}):
  273. ret.update({"comment": "", "changes": {}})
  274. self.assertDictEqual(
  275. cmd.mod_watch(name, sfun="call", func=func), ret
  276. )
  277. comt = "cmd.call needs a named parameter func"
  278. ret.update({"comment": comt})
  279. self.assertDictEqual(cmd.mod_watch(name, sfun="call"), ret)
  280. comt = (
  281. "cmd.salt does not work with the watch requisite,"
  282. " please use cmd.wait or cmd.wait_script"
  283. )
  284. ret.update({"comment": comt})
  285. self.assertDictEqual(cmd.mod_watch(name, sfun="salt"), ret)