test_stateconf.py 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386
  1. # -*- coding: utf-8 -*-
  2. # Import Python libs
  3. from __future__ import absolute_import
  4. import os
  5. import os.path
  6. import tempfile
  7. import salt.config
  8. # Import Salt libs
  9. import salt.loader
  10. from salt.exceptions import SaltRenderError
  11. # Import 3rd-party libs
  12. from salt.ext import six
  13. from salt.ext.six.moves import StringIO
  14. from tests.support.runtests import RUNTIME_VARS
  15. # Import Salt Testing libs
  16. from tests.support.unit import TestCase
  17. REQUISITES = ["require", "require_in", "use", "use_in", "watch", "watch_in"]
  18. class StateConfigRendererTestCase(TestCase):
  19. def setUp(self):
  20. self.root_dir = tempfile.mkdtemp(dir=RUNTIME_VARS.TMP)
  21. self.state_tree_dir = os.path.join(self.root_dir, "state_tree")
  22. self.cache_dir = os.path.join(self.root_dir, "cachedir")
  23. if not os.path.isdir(self.root_dir):
  24. os.makedirs(self.root_dir)
  25. if not os.path.isdir(self.state_tree_dir):
  26. os.makedirs(self.state_tree_dir)
  27. if not os.path.isdir(self.cache_dir):
  28. os.makedirs(self.cache_dir)
  29. self.config = salt.config.minion_config(None)
  30. self.config["root_dir"] = self.root_dir
  31. self.config["state_events"] = False
  32. self.config["id"] = "match"
  33. self.config["file_client"] = "local"
  34. self.config["file_roots"] = dict(base=[self.state_tree_dir])
  35. self.config["cachedir"] = self.cache_dir
  36. self.config["test"] = False
  37. self._renderers = salt.loader.render(
  38. self.config, {"config.get": lambda a, b: False}
  39. )
  40. def tearDown(self):
  41. for attrname in ("config", "_renderers"):
  42. try:
  43. delattr(self, attrname)
  44. except AttributeError:
  45. continue
  46. def _render_sls(
  47. self, content, sls="", saltenv="base", argline="-G yaml . jinja", **kws
  48. ):
  49. return self._renderers["stateconf"](
  50. StringIO(content),
  51. saltenv=saltenv,
  52. sls=sls,
  53. argline=argline,
  54. renderers=salt.loader.render(self.config, {}),
  55. **kws
  56. )
  57. def test_state_config(self):
  58. result = self._render_sls(
  59. """
  60. .sls_params:
  61. stateconf.set:
  62. - name1: value1
  63. - name2: value2
  64. .extra:
  65. stateconf:
  66. - set
  67. - name: value
  68. # --- end of state config ---
  69. test:
  70. cmd.run:
  71. - name: echo name1={{sls_params.name1}} name2={{sls_params.name2}} {{extra.name}}
  72. - cwd: /
  73. """,
  74. sls="test",
  75. )
  76. self.assertEqual(len(result), 3)
  77. self.assertTrue("test::sls_params" in result and "test" in result)
  78. self.assertTrue("test::extra" in result)
  79. self.assertEqual(
  80. result["test"]["cmd.run"][0]["name"], "echo name1=value1 name2=value2 value"
  81. )
  82. def test_sls_dir(self):
  83. result = self._render_sls(
  84. """
  85. test:
  86. cmd.run:
  87. - name: echo sls_dir={{sls_dir}}
  88. - cwd: /
  89. """,
  90. sls="path.to.sls",
  91. )
  92. self.assertEqual(
  93. result["test"]["cmd.run"][0]["name"],
  94. "echo sls_dir=path{0}to".format(os.sep),
  95. )
  96. def test_states_declared_with_shorthand_no_args(self):
  97. result = self._render_sls(
  98. """
  99. test:
  100. cmd.run:
  101. - name: echo testing
  102. - cwd: /
  103. test1:
  104. pkg.installed
  105. test2:
  106. user.present
  107. """
  108. )
  109. self.assertEqual(len(result), 3)
  110. for args in (result["test1"]["pkg.installed"], result["test2"]["user.present"]):
  111. self.assertTrue(isinstance(args, list))
  112. self.assertEqual(len(args), 0)
  113. self.assertEqual(result["test"]["cmd.run"][0]["name"], "echo testing")
  114. def test_adding_state_name_arg_for_dot_state_id(self):
  115. result = self._render_sls(
  116. """
  117. .test:
  118. pkg.installed:
  119. - cwd: /
  120. .test2:
  121. pkg.installed:
  122. - name: vim
  123. """,
  124. sls="test",
  125. )
  126. self.assertEqual(result["test::test"]["pkg.installed"][0]["name"], "test")
  127. self.assertEqual(result["test::test2"]["pkg.installed"][0]["name"], "vim")
  128. def test_state_prefix(self):
  129. result = self._render_sls(
  130. """
  131. .test:
  132. cmd.run:
  133. - name: echo renamed
  134. - cwd: /
  135. state_id:
  136. cmd:
  137. - run
  138. - name: echo not renamed
  139. - cwd: /
  140. """,
  141. sls="test",
  142. )
  143. self.assertEqual(len(result), 2)
  144. self.assertTrue("test::test" in result)
  145. self.assertTrue("state_id" in result)
  146. def test_dot_state_id_in_requisites(self):
  147. for req in REQUISITES:
  148. result = self._render_sls(
  149. """
  150. .test:
  151. cmd.run:
  152. - name: echo renamed
  153. - cwd: /
  154. state_id:
  155. cmd.run:
  156. - name: echo not renamed
  157. - cwd: /
  158. - {0}:
  159. - cmd: .test
  160. """.format(
  161. req
  162. ),
  163. sls="test",
  164. )
  165. self.assertEqual(len(result), 2)
  166. self.assertTrue("test::test" in result)
  167. self.assertTrue("state_id" in result)
  168. self.assertEqual(
  169. result["state_id"]["cmd.run"][2][req][0]["cmd"], "test::test"
  170. )
  171. def test_relative_include_with_requisites(self):
  172. for req in REQUISITES:
  173. result = self._render_sls(
  174. """
  175. include:
  176. - some.helper
  177. - .utils
  178. state_id:
  179. cmd.run:
  180. - name: echo test
  181. - cwd: /
  182. - {0}:
  183. - cmd: .utils::some_state
  184. """.format(
  185. req
  186. ),
  187. sls="test.work",
  188. )
  189. self.assertEqual(result["include"][1], {"base": "test.utils"})
  190. self.assertEqual(
  191. result["state_id"]["cmd.run"][2][req][0]["cmd"],
  192. "test.utils::some_state",
  193. )
  194. def test_relative_include_and_extend(self):
  195. result = self._render_sls(
  196. """
  197. include:
  198. - some.helper
  199. - .utils
  200. extend:
  201. .utils::some_state:
  202. cmd.run:
  203. - name: echo overridden
  204. """,
  205. sls="test.work",
  206. )
  207. self.assertTrue("test.utils::some_state" in result["extend"])
  208. def test_multilevel_relative_include_with_requisites(self):
  209. for req in REQUISITES:
  210. result = self._render_sls(
  211. """
  212. include:
  213. - .shared
  214. - ..utils
  215. - ...helper
  216. state_id:
  217. cmd.run:
  218. - name: echo test
  219. - cwd: /
  220. - {0}:
  221. - cmd: ..utils::some_state
  222. """.format(
  223. req
  224. ),
  225. sls="test.nested.work",
  226. )
  227. self.assertEqual(result["include"][0], {"base": "test.nested.shared"})
  228. self.assertEqual(result["include"][1], {"base": "test.utils"})
  229. self.assertEqual(result["include"][2], {"base": "helper"})
  230. self.assertEqual(
  231. result["state_id"]["cmd.run"][2][req][0]["cmd"],
  232. "test.utils::some_state",
  233. )
  234. def test_multilevel_relative_include_beyond_top_level(self):
  235. self.assertRaises(
  236. SaltRenderError,
  237. self._render_sls,
  238. """
  239. include:
  240. - ...shared
  241. """,
  242. sls="test.work",
  243. )
  244. def test_start_state_generation(self):
  245. result = self._render_sls(
  246. """
  247. A:
  248. cmd.run:
  249. - name: echo hello
  250. - cwd: /
  251. B:
  252. cmd.run:
  253. - name: echo world
  254. - cwd: /
  255. """,
  256. sls="test",
  257. argline="-so yaml . jinja",
  258. )
  259. self.assertEqual(len(result), 4)
  260. self.assertEqual(
  261. result["test::start"]["stateconf.set"][0]["require_in"][0]["cmd"], "A"
  262. )
  263. def test_goal_state_generation(self):
  264. result = self._render_sls(
  265. """
  266. {% for sid in "ABCDE": %}
  267. {{sid}}:
  268. cmd.run:
  269. - name: echo this is {{sid}}
  270. - cwd: /
  271. {% endfor %}
  272. """,
  273. sls="test.goalstate",
  274. argline="yaml . jinja",
  275. )
  276. self.assertEqual(len(result), len("ABCDE") + 1)
  277. reqs = result["test.goalstate::goal"]["stateconf.set"][0]["require"]
  278. self.assertEqual(set([next(six.itervalues(i)) for i in reqs]), set("ABCDE"))
  279. def test_implicit_require_with_goal_state(self):
  280. result = self._render_sls(
  281. """
  282. {% for sid in "ABCDE": %}
  283. {{sid}}:
  284. cmd.run:
  285. - name: echo this is {{sid}}
  286. - cwd: /
  287. {% endfor %}
  288. F:
  289. cmd.run:
  290. - name: echo this is F
  291. - cwd: /
  292. - require:
  293. - cmd: A
  294. - cmd: B
  295. G:
  296. cmd.run:
  297. - name: echo this is G
  298. - cwd: /
  299. - require:
  300. - cmd: D
  301. - cmd: F
  302. """,
  303. sls="test",
  304. argline="-o yaml . jinja",
  305. )
  306. sids = "ABCDEFG"[::-1]
  307. for i, sid in enumerate(sids):
  308. if i < len(sids) - 1:
  309. self.assertEqual(
  310. result[sid]["cmd.run"][2]["require"][0]["cmd"], sids[i + 1]
  311. )
  312. F_args = result["F"]["cmd.run"]
  313. self.assertEqual(len(F_args), 3)
  314. F_req = F_args[2]["require"]
  315. self.assertEqual(len(F_req), 3)
  316. self.assertEqual(F_req[1]["cmd"], "A")
  317. self.assertEqual(F_req[2]["cmd"], "B")
  318. G_args = result["G"]["cmd.run"]
  319. self.assertEqual(len(G_args), 3)
  320. G_req = G_args[2]["require"]
  321. self.assertEqual(len(G_req), 3)
  322. self.assertEqual(G_req[1]["cmd"], "D")
  323. self.assertEqual(G_req[2]["cmd"], "F")
  324. goal_args = result["test::goal"]["stateconf.set"]
  325. self.assertEqual(len(goal_args), 1)
  326. self.assertEqual(
  327. [next(six.itervalues(i)) for i in goal_args[0]["require"]], list("ABCDEFG")
  328. )
  329. def test_slsdir(self):
  330. result = self._render_sls(
  331. """
  332. formula/woot.sls:
  333. cmd.run:
  334. - name: echo {{ slspath }}
  335. - cwd: /
  336. """,
  337. sls="formula.woot",
  338. argline="yaml . jinja",
  339. )
  340. r = result["formula/woot.sls"]["cmd.run"][0]["name"]
  341. self.assertEqual(r, "echo formula/woot")