test_mine.py 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. # -*- coding: utf-8 -*-
  2. """
  3. Test the salt mine system
  4. """
  5. from __future__ import absolute_import, print_function, unicode_literals
  6. import pprint
  7. import time
  8. import pytest
  9. import salt.utils.platform
  10. from tests.support.case import ModuleCase, ShellCase
  11. from tests.support.helpers import slowTest
  12. from tests.support.runtests import RUNTIME_VARS
  13. @pytest.mark.windows_whitelisted
  14. @pytest.mark.usefixtures("salt_sub_minion")
  15. class MineTest(ModuleCase, ShellCase):
  16. """
  17. Test the mine system
  18. """
  19. def setUp(self):
  20. self.tgt = r"\*"
  21. if salt.utils.platform.is_windows():
  22. self.tgt = "*"
  23. self.wait_for_all_jobs()
  24. @slowTest
  25. def test_get(self):
  26. """
  27. test mine.get and mine.update
  28. """
  29. assert self.run_function("mine.update", minion_tgt="minion")
  30. assert self.run_function("mine.update", minion_tgt="sub_minion")
  31. # Since the minion has mine_functions defined in its configuration,
  32. # mine.update will return True
  33. self.assertTrue(self.run_function("mine.get", ["minion", "test.ping"]))
  34. @slowTest
  35. def test_get_allow_tgt(self):
  36. """
  37. test mine.get and mine.update using allow_tgt
  38. """
  39. assert self.run_function("mine.update", minion_tgt="minion")
  40. assert self.run_function("mine.update", minion_tgt="sub_minion")
  41. # sub_minion should be able to view test.arg data
  42. sub_min_ret = self.run_call(
  43. "mine.get {0} test.arg".format(self.tgt),
  44. config_dir=RUNTIME_VARS.TMP_SUB_MINION_CONF_DIR,
  45. )
  46. assert " - isn't" in sub_min_ret
  47. # minion should not be able to view test.arg data
  48. min_ret = self.run_call("mine.get {0} test.arg".format(self.tgt))
  49. assert " - isn't" not in min_ret
  50. @slowTest
  51. def test_send_allow_tgt(self):
  52. """
  53. test mine.send with allow_tgt set
  54. """
  55. mine_name = "test_this"
  56. for minion in ["sub_minion", "minion"]:
  57. assert self.run_function(
  58. "mine.send",
  59. [mine_name, "mine_function=test.arg_clean", "one"],
  60. allow_tgt="sub_minion",
  61. minion_tgt=minion,
  62. )
  63. min_ret = self.run_call("mine.get {0} {1}".format(self.tgt, mine_name))
  64. sub_ret = self.run_call(
  65. "mine.get {0} {1}".format(self.tgt, mine_name),
  66. config_dir=RUNTIME_VARS.TMP_SUB_MINION_CONF_DIR,
  67. )
  68. # ensure we did get the mine_name mine function for sub_minion
  69. assert " - one" in sub_ret
  70. # ensure we did not get the mine_name mine function for minion
  71. assert " - one" not in min_ret
  72. @slowTest
  73. def test_send_allow_tgt_compound(self):
  74. """
  75. test mine.send with allow_tgt set
  76. and using compound targeting
  77. """
  78. mine_name = "test_this_comp"
  79. for minion in ["sub_minion", "minion"]:
  80. assert self.run_function(
  81. "mine.send",
  82. [mine_name, "mine_function=test.arg_clean", "one"],
  83. allow_tgt="L@minion,sub_minion",
  84. allow_tgt_type="compound",
  85. minion_tgt=minion,
  86. )
  87. min_ret = self.run_call("mine.get {0} {1}".format(self.tgt, mine_name))
  88. sub_ret = self.run_call(
  89. "mine.get {0} {1}".format(self.tgt, mine_name),
  90. config_dir=RUNTIME_VARS.TMP_SUB_MINION_CONF_DIR,
  91. )
  92. # ensure we get the mine_name mine function for both minions
  93. for ret in [min_ret, sub_ret]:
  94. assert " - one" in ret
  95. @slowTest
  96. def test_send_allow_tgt_doesnotexist(self):
  97. """
  98. test mine.send with allow_tgt set when
  99. the minion defined in allow_tgt does
  100. not exist
  101. """
  102. mine_name = "mine_doesnotexist"
  103. for minion in ["sub_minion", "minion"]:
  104. assert self.run_function(
  105. "mine.send",
  106. [mine_name, "mine_function=test.arg_clean", "one"],
  107. allow_tgt="doesnotexist",
  108. minion_tgt=minion,
  109. )
  110. min_ret = self.run_call("mine.get {0} {1}".format(self.tgt, mine_name))
  111. sub_ret = self.run_call(
  112. "mine.get {0} {1}".format(self.tgt, mine_name),
  113. config_dir=RUNTIME_VARS.TMP_SUB_MINION_CONF_DIR,
  114. )
  115. # ensure we did not get the mine_name mine function for both minions
  116. for ret in [sub_ret, min_ret]:
  117. assert " - one" not in ret
  118. @slowTest
  119. def test_send(self):
  120. """
  121. test mine.send
  122. """
  123. self.assertFalse(self.run_function("mine.send", ["foo.__spam_and_cheese"]))
  124. self.assertTrue(
  125. self.run_function("mine.send", ["grains.items"], minion_tgt="minion",)
  126. )
  127. self.assertTrue(
  128. self.run_function("mine.send", ["grains.items"], minion_tgt="sub_minion",)
  129. )
  130. ret = self.run_function("mine.get", ["sub_minion", "grains.items"])
  131. self.assertEqual(ret["sub_minion"]["id"], "sub_minion")
  132. ret = self.run_function(
  133. "mine.get", ["minion", "grains.items"], minion_tgt="sub_minion"
  134. )
  135. self.assertEqual(ret["minion"]["id"], "minion")
  136. @slowTest
  137. def test_mine_flush(self):
  138. """
  139. Test mine.flush
  140. """
  141. # TODO The calls to sleep were added in an attempt to make this tests
  142. # less flaky. If we still see it fail we need to look for a more robust
  143. # solution.
  144. for minion_id in ("minion", "sub_minion"):
  145. self.assertTrue(
  146. self.run_function("mine.send", ["grains.items"], minion_tgt=minion_id)
  147. )
  148. time.sleep(1)
  149. for minion_id in ("minion", "sub_minion"):
  150. ret = self.run_function(
  151. "mine.get", [minion_id, "grains.items"], minion_tgt=minion_id
  152. )
  153. self.assertEqual(ret[minion_id]["id"], minion_id)
  154. time.sleep(1)
  155. self.assertTrue(self.run_function("mine.flush", minion_tgt="minion"))
  156. time.sleep(1)
  157. ret_flushed = self.run_function("mine.get", ["*", "grains.items"])
  158. self.assertEqual(ret_flushed.get("minion", None), None)
  159. self.assertEqual(ret_flushed["sub_minion"]["id"], "sub_minion")
  160. @slowTest
  161. def test_mine_delete(self):
  162. """
  163. Test mine.delete
  164. """
  165. self.assertTrue(
  166. self.run_function("mine.send", ["grains.items"], minion_tgt="minion")
  167. )
  168. self.wait_for_all_jobs(minions=("minion",))
  169. attempts = 10
  170. ret_grains = None
  171. while True:
  172. if ret_grains:
  173. break
  174. # Smoke testing that grains should now exist in the mine
  175. ret_grains = self.run_function(
  176. "mine.get", ["minion", "grains.items"], minion_tgt="minion"
  177. )
  178. if ret_grains and "minion" in ret_grains:
  179. break
  180. if attempts:
  181. attempts -= 1
  182. if attempts:
  183. time.sleep(1.5)
  184. continue
  185. self.fail(
  186. "'minion' was not found as a key of the 'mine.get' 'grains.items' call. Full return: {}".format(
  187. pprint.pformat(ret_grains)
  188. )
  189. )
  190. self.assertEqual(
  191. ret_grains["minion"]["id"],
  192. "minion",
  193. msg="{} != minion, full return payload: {}".format(
  194. ret_grains["minion"]["id"], pprint.pformat(ret_grains)
  195. ),
  196. )
  197. self.assertTrue(
  198. self.run_function(
  199. "mine.send",
  200. ["test.arg", "foo=bar", "fnord=roscivs"],
  201. minion_tgt="minion",
  202. )
  203. )
  204. self.wait_for_all_jobs(minions=("minion",))
  205. ret_args = self.run_function("mine.get", ["minion", "test.arg"])
  206. expected = {
  207. "minion": {"args": [], "kwargs": {"fnord": "roscivs", "foo": "bar"}},
  208. }
  209. # Smoke testing that test.arg exists in the mine
  210. self.assertDictEqual(ret_args, expected)
  211. self.assertTrue(
  212. self.run_function("mine.send", ["test.echo", "foo"], minion_tgt="minion")
  213. )
  214. self.wait_for_all_jobs(minions=("minion",))
  215. ret_echo = self.run_function(
  216. "mine.get", ["minion", "test.echo"], minion_tgt="minion"
  217. )
  218. # Smoke testing that we were also able to set test.echo in the mine
  219. self.assertEqual(ret_echo["minion"], "foo")
  220. self.assertTrue(
  221. self.run_function("mine.delete", ["test.arg"], minion_tgt="minion")
  222. )
  223. self.wait_for_all_jobs(minions=("minion",))
  224. ret_arg_deleted = self.run_function(
  225. "mine.get", ["minion", "test.arg"], minion_tgt="minion"
  226. )
  227. # Now comes the real test - did we obliterate test.arg from the mine?
  228. # We could assert this a different way, but there shouldn't be any
  229. # other tests that are setting this mine value, so this should
  230. # definitely avoid any race conditions.
  231. self.assertFalse(
  232. ret_arg_deleted.get("minion", {}).get("kwargs", {}).get("fnord", None)
  233. == "roscivs",
  234. '{} contained "fnord":"roscivs", which should be gone'.format(
  235. ret_arg_deleted,
  236. ),
  237. )
  238. ret_echo_stays = self.run_function(
  239. "mine.get", ["minion", "test.echo"], minion_tgt="minion"
  240. )
  241. # Of course, one more health check - we want targeted removal.
  242. # This isn't horseshoes or hand grenades - test.arg should go away
  243. # but test.echo should still be available.
  244. self.assertEqual(ret_echo_stays["minion"], "foo")