test_grains.py 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. """
  2. Test the grains module
  3. """
  4. import logging
  5. import os
  6. import pprint
  7. import time
  8. import pytest
  9. from tests.support.case import ModuleCase
  10. from tests.support.helpers import flaky, slowTest
  11. from tests.support.unit import skipIf
  12. log = logging.getLogger(__name__)
  13. @pytest.mark.windows_whitelisted
  14. class TestModulesGrains(ModuleCase):
  15. """
  16. Test the grains module
  17. """
  18. @slowTest
  19. def test_items(self):
  20. """
  21. grains.items
  22. """
  23. opts = self.minion_opts
  24. self.assertEqual(
  25. self.run_function("grains.items")["test_grain"],
  26. opts["grains"]["test_grain"],
  27. )
  28. @slowTest
  29. def test_item(self):
  30. """
  31. grains.item
  32. """
  33. opts = self.minion_opts
  34. self.assertEqual(
  35. self.run_function("grains.item", ["test_grain"])["test_grain"],
  36. opts["grains"]["test_grain"],
  37. )
  38. @slowTest
  39. def test_ls(self):
  40. """
  41. grains.ls
  42. """
  43. check_for = (
  44. "cpu_flags",
  45. "cpu_model",
  46. "cpuarch",
  47. "domain",
  48. "fqdn",
  49. "fqdns",
  50. "gid",
  51. "groupname",
  52. "host",
  53. "kernel",
  54. "kernelrelease",
  55. "kernelversion",
  56. "localhost",
  57. "mem_total",
  58. "num_cpus",
  59. "os",
  60. "os_family",
  61. "path",
  62. "pid",
  63. "ps",
  64. "pythonpath",
  65. "pythonversion",
  66. "saltpath",
  67. "saltversion",
  68. "uid",
  69. "username",
  70. "virtual",
  71. )
  72. lsgrains = self.run_function("grains.ls")
  73. os = self.run_function("grains.get", ["os"])
  74. for grain in check_for:
  75. if os == "Windows" and grain in ["cpu_flags", "gid", "groupname", "uid"]:
  76. continue
  77. self.assertTrue(grain in lsgrains)
  78. @skipIf(
  79. os.environ.get("TRAVIS_PYTHON_VERSION", None) is not None,
  80. "Travis environment can't keep up with salt refresh",
  81. )
  82. @slowTest
  83. def test_set_val(self):
  84. """
  85. test grains.set_val
  86. """
  87. self.assertEqual(
  88. self.run_function("grains.setval", ["setgrain", "grainval"]),
  89. {"setgrain": "grainval"},
  90. )
  91. time.sleep(5)
  92. ret = self.run_function("grains.item", ["setgrain"])
  93. if not ret:
  94. # Sleep longer, sometimes test systems get bogged down
  95. time.sleep(20)
  96. ret = self.run_function("grains.item", ["setgrain"])
  97. self.assertTrue(ret)
  98. @slowTest
  99. def test_get(self):
  100. """
  101. test grains.get
  102. """
  103. self.assertEqual(self.run_function("grains.get", ["level1:level2"]), "foo")
  104. @slowTest
  105. def test_get_core_grains(self):
  106. """
  107. test to ensure some core grains are returned
  108. """
  109. grains = ("os", "os_family", "osmajorrelease", "osrelease", "osfullname", "id")
  110. os = self.run_function("grains.get", ["os"])
  111. for grain in grains:
  112. get_grain = self.run_function("grains.get", [grain])
  113. log.debug("Value of '%s' grain: '%s'", grain, get_grain)
  114. if os == "Arch" and grain in ["osmajorrelease"]:
  115. self.assertEqual(get_grain, "")
  116. continue
  117. if os == "Windows" and grain in ["osmajorrelease"]:
  118. self.assertEqual(get_grain, "")
  119. continue
  120. self.assertTrue(get_grain)
  121. @slowTest
  122. def test_get_grains_int(self):
  123. """
  124. test to ensure int grains
  125. are returned as integers
  126. """
  127. grains = ["num_cpus", "mem_total", "num_gpus", "uid"]
  128. os = self.run_function("grains.get", ["os"])
  129. for grain in grains:
  130. get_grain = self.run_function("grains.get", [grain])
  131. if os == "Windows" and grain in ["uid"]:
  132. self.assertEqual(get_grain, "")
  133. continue
  134. self.assertIsInstance(
  135. get_grain, int, msg="grain: {} is not an int or empty".format(grain)
  136. )
  137. @pytest.mark.windows_whitelisted
  138. class GrainsAppendTestCase(ModuleCase):
  139. """
  140. Tests written specifically for the grains.append function.
  141. """
  142. GRAIN_KEY = "salttesting-grain-key"
  143. GRAIN_VAL = "my-grain-val"
  144. def setUp(self):
  145. # Start off with an empty list
  146. self.run_function("grains.setval", [self.GRAIN_KEY, []])
  147. if not self.wait_for_grain(self.GRAIN_KEY, []):
  148. raise Exception("Failed to set grain")
  149. self.addCleanup(self.cleanup_grain)
  150. def cleanup_grain(self):
  151. self.run_function("grains.setval", [self.GRAIN_KEY, []])
  152. if not self.wait_for_grain(self.GRAIN_KEY, []):
  153. raise Exception("Failed to set grain")
  154. @slowTest
  155. def test_grains_append(self):
  156. """
  157. Tests the return of a simple grains.append call.
  158. """
  159. ret = self.run_function("grains.append", [self.GRAIN_KEY, self.GRAIN_VAL])
  160. self.assertEqual(ret[self.GRAIN_KEY], [self.GRAIN_VAL])
  161. @slowTest
  162. def test_grains_append_val_already_present(self):
  163. """
  164. Tests the return of a grains.append call when the value is already
  165. present in the grains list.
  166. """
  167. msg = "The val {} was already in the list " "salttesting-grain-key".format(
  168. self.GRAIN_VAL
  169. )
  170. # First, make sure the test grain is present
  171. ret = self.run_function("grains.append", [self.GRAIN_KEY, self.GRAIN_VAL])
  172. self.assertEqual(ret[self.GRAIN_KEY], [self.GRAIN_VAL])
  173. # Now try to append again
  174. ret = self.run_function("grains.append", [self.GRAIN_KEY, self.GRAIN_VAL])
  175. self.assertTrue(self.wait_for_grain(self.GRAIN_KEY, [self.GRAIN_VAL]))
  176. if not ret or isinstance(ret, dict):
  177. # Sleep for a bit, sometimes the second "append" runs too quickly
  178. time.sleep(5)
  179. ret = self.run_function("grains.append", [self.GRAIN_KEY, self.GRAIN_VAL])
  180. assert msg == ret
  181. @flaky
  182. @slowTest
  183. def test_grains_append_val_is_list(self):
  184. """
  185. Tests the return of a grains.append call when val is passed in as a list.
  186. """
  187. # Start off with an empty list, don't know if the flaky decorator runs the setUp function or not...
  188. self.run_function("grains.setval", [self.GRAIN_KEY, []])
  189. second_grain = self.GRAIN_VAL + "-2"
  190. ret = self.run_function(
  191. "grains.append", [self.GRAIN_KEY, [self.GRAIN_VAL, second_grain]]
  192. )
  193. self.assertEqual(ret[self.GRAIN_KEY], [self.GRAIN_VAL, second_grain])
  194. @slowTest
  195. def test_grains_append_call_twice(self):
  196. """
  197. Tests the return of a grains.append call when the value is already present
  198. but also ensure the grain is not listed twice.
  199. """
  200. # First, add the test grain.
  201. append_1 = self.run_function("grains.append", [self.GRAIN_KEY, self.GRAIN_VAL])
  202. # Call the function again, which results in a string message, as tested in
  203. # test_grains_append_val_already_present above.
  204. append_2 = self.run_function("grains.append", [self.GRAIN_KEY, self.GRAIN_VAL])
  205. # Now make sure the grain doesn't show up twice.
  206. grains = self.run_function("grains.items")
  207. count = 0
  208. for grain in grains:
  209. if grain == self.GRAIN_KEY:
  210. count += 1
  211. # We should only have hit the grain key once.
  212. self.assertEqual(
  213. count,
  214. 1,
  215. msg="Count did not match({}!=1) while looking for key '{}'.\nFirst append return:\n{}\nSecond append return:\n{}".format(
  216. count,
  217. self.GRAIN_KEY,
  218. pprint.pformat(append_1),
  219. pprint.pformat(append_2),
  220. ),
  221. )
  222. def wait_for_grain(self, key, val, timeout=60, sleep=0.3):
  223. start = time.time()
  224. while time.time() - start <= timeout:
  225. ret = self.run_function("grains.get", [key])
  226. if ret == val:
  227. return True
  228. time.sleep(sleep)
  229. return False
  230. @slowTest
  231. def test_grains_remove_add(self):
  232. second_grain = self.GRAIN_VAL + "-2"
  233. ret = self.run_function("grains.get", [self.GRAIN_KEY])
  234. self.assertEqual(ret, [])
  235. for i in range(10):
  236. ret = self.run_function("grains.setval", [self.GRAIN_KEY, []])
  237. self.assertEqual(ret[self.GRAIN_KEY], [])
  238. self.wait_for_grain(self.GRAIN_KEY, [])
  239. ret = self.run_function("grains.append", [self.GRAIN_KEY, self.GRAIN_VAL])
  240. self.assertEqual(ret[self.GRAIN_KEY], [self.GRAIN_VAL])
  241. self.assertEqual(ret[self.GRAIN_KEY], [self.GRAIN_VAL])
  242. ret = self.run_function("grains.setval", [self.GRAIN_KEY, []])
  243. self.wait_for_grain(self.GRAIN_KEY, [])
  244. self.assertTrue(self.wait_for_grain(self.GRAIN_KEY, []))
  245. ret = self.run_function(
  246. "grains.append", [self.GRAIN_KEY, [self.GRAIN_VAL, second_grain]]
  247. )
  248. self.assertEqual(ret[self.GRAIN_KEY], [self.GRAIN_VAL, second_grain])
  249. self.assertEqual(ret[self.GRAIN_KEY], [self.GRAIN_VAL, second_grain])