test_stateconf.py 9.1 KB

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