test_archive.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  1. # -*- coding: utf-8 -*-
  2. """
  3. Tests for the archive state
  4. """
  5. from __future__ import absolute_import, print_function, unicode_literals
  6. import errno
  7. import logging
  8. import os
  9. import pytest
  10. import salt.utils.files
  11. import salt.utils.platform
  12. from tests.support.case import ModuleCase
  13. from tests.support.helpers import Webserver
  14. from tests.support.mixins import SaltReturnAssertsMixin
  15. from tests.support.runtests import RUNTIME_VARS
  16. log = logging.getLogger(__name__)
  17. ARCHIVE_DIR = (
  18. os.path.join("c:/", "tmp") if salt.utils.platform.is_windows() else "/tmp/archive"
  19. )
  20. ARCHIVE_NAME = "custom.tar.gz"
  21. ARCHIVE_TAR_SOURCE = "http://localhost:{0}/{1}".format(9999, ARCHIVE_NAME)
  22. ARCHIVE_TAR_HASH = "md5=7643861ac07c30fe7d2310e9f25ca514"
  23. ARCHIVE_TAR_SHA_HASH = (
  24. "sha256=9591159d86f0a180e4e0645b2320d0235e23e66c66797df61508bf185e0ac1d2"
  25. )
  26. ARCHIVE_TAR_BAD_HASH = "md5=d41d8cd98f00b204e9800998ecf8427e"
  27. ARCHIVE_TAR_HASH_UPPER = "md5=7643861AC07C30FE7D2310E9F25CA514"
  28. class ArchiveTest(ModuleCase, SaltReturnAssertsMixin):
  29. """
  30. Validate the archive state
  31. """
  32. @classmethod
  33. def setUpClass(cls):
  34. cls.webserver = Webserver()
  35. cls.webserver.start()
  36. cls.archive_tar_source = cls.webserver.url("custom.tar.gz")
  37. cls.archive_local_tar_source = "file://{0}".format(
  38. os.path.join(RUNTIME_VARS.BASE_FILES, ARCHIVE_NAME)
  39. )
  40. cls.untar_file = os.path.join(ARCHIVE_DIR, "custom/README")
  41. @classmethod
  42. def tearDownClass(cls):
  43. cls.webserver.stop()
  44. def setUp(self):
  45. self._clear_archive_dir()
  46. def tearDown(self):
  47. self._clear_archive_dir()
  48. @staticmethod
  49. def _clear_archive_dir():
  50. try:
  51. salt.utils.files.rm_rf(ARCHIVE_DIR)
  52. except OSError as exc:
  53. if exc.errno != errno.ENOENT:
  54. raise
  55. def _check_extracted(self, path):
  56. """
  57. function to check if file was extracted
  58. """
  59. log.debug("Checking for extracted file: %s", path)
  60. self.assertTrue(os.path.isfile(path))
  61. def run_function(self, *args, **kwargs): # pylint: disable=arguments-differ
  62. ret = super(ArchiveTest, self).run_function(*args, **kwargs)
  63. log.debug("ret = %s", ret)
  64. return ret
  65. def run_state(self, *args, **kwargs): # pylint: disable=arguments-differ
  66. ret = super(ArchiveTest, self).run_state(*args, **kwargs)
  67. log.debug("ret = %s", ret)
  68. return ret
  69. @pytest.mark.slow_test(seconds=1) # Test takes >0.1 and <=1 seconds
  70. def test_archive_extracted_skip_verify(self):
  71. """
  72. test archive.extracted with skip_verify
  73. """
  74. ret = self.run_state(
  75. "archive.extracted",
  76. name=ARCHIVE_DIR,
  77. source=self.archive_tar_source,
  78. archive_format="tar",
  79. skip_verify=True,
  80. )
  81. if "Timeout" in ret:
  82. self.skipTest("Timeout talking to local tornado server.")
  83. self.assertSaltTrueReturn(ret)
  84. self._check_extracted(self.untar_file)
  85. @pytest.mark.slow_test(seconds=1) # Test takes >0.1 and <=1 seconds
  86. def test_archive_extracted_with_source_hash(self):
  87. """
  88. test archive.extracted without skip_verify
  89. only external resources work to check to
  90. ensure source_hash is verified correctly
  91. """
  92. ret = self.run_state(
  93. "archive.extracted",
  94. name=ARCHIVE_DIR,
  95. source=self.archive_tar_source,
  96. archive_format="tar",
  97. source_hash=ARCHIVE_TAR_HASH,
  98. )
  99. if "Timeout" in ret:
  100. self.skipTest("Timeout talking to local tornado server.")
  101. self.assertSaltTrueReturn(ret)
  102. self._check_extracted(self.untar_file)
  103. @pytest.mark.skip_if_not_root
  104. @pytest.mark.slow_test(seconds=1) # Test takes >0.1 and <=1 seconds
  105. def test_archive_extracted_with_root_user_and_group(self):
  106. """
  107. test archive.extracted with user and group set to "root"
  108. """
  109. r_group = "root"
  110. if salt.utils.platform.is_darwin():
  111. r_group = "wheel"
  112. ret = self.run_state(
  113. "archive.extracted",
  114. name=ARCHIVE_DIR,
  115. source=self.archive_tar_source,
  116. archive_format="tar",
  117. source_hash=ARCHIVE_TAR_HASH,
  118. user="root",
  119. group=r_group,
  120. )
  121. if "Timeout" in ret:
  122. self.skipTest("Timeout talking to local tornado server.")
  123. self.assertSaltTrueReturn(ret)
  124. self._check_extracted(self.untar_file)
  125. @pytest.mark.slow_test(seconds=5) # Test takes >1 and <=5 seconds
  126. def test_archive_extracted_with_strip_in_options(self):
  127. """
  128. test archive.extracted with --strip in options
  129. """
  130. ret = self.run_state(
  131. "archive.extracted",
  132. name=ARCHIVE_DIR,
  133. source=self.archive_tar_source,
  134. source_hash=ARCHIVE_TAR_HASH,
  135. options="--strip=1",
  136. enforce_toplevel=False,
  137. )
  138. if "Timeout" in ret:
  139. self.skipTest("Timeout talking to local tornado server.")
  140. self.assertSaltTrueReturn(ret)
  141. self._check_extracted(os.path.join(ARCHIVE_DIR, "README"))
  142. @pytest.mark.slow_test(seconds=1) # Test takes >0.1 and <=1 seconds
  143. def test_archive_extracted_with_strip_components_in_options(self):
  144. """
  145. test archive.extracted with --strip-components in options
  146. """
  147. ret = self.run_state(
  148. "archive.extracted",
  149. name=ARCHIVE_DIR,
  150. source=self.archive_tar_source,
  151. source_hash=ARCHIVE_TAR_HASH,
  152. options="--strip-components=1",
  153. enforce_toplevel=False,
  154. )
  155. if "Timeout" in ret:
  156. self.skipTest("Timeout talking to local tornado server.")
  157. self.assertSaltTrueReturn(ret)
  158. self._check_extracted(os.path.join(ARCHIVE_DIR, "README"))
  159. @pytest.mark.slow_test(seconds=5) # Test takes >1 and <=5 seconds
  160. def test_archive_extracted_without_archive_format(self):
  161. """
  162. test archive.extracted with no archive_format option
  163. """
  164. ret = self.run_state(
  165. "archive.extracted",
  166. name=ARCHIVE_DIR,
  167. source=self.archive_tar_source,
  168. source_hash=ARCHIVE_TAR_HASH,
  169. )
  170. if "Timeout" in ret:
  171. self.skipTest("Timeout talking to local tornado server.")
  172. self.assertSaltTrueReturn(ret)
  173. self._check_extracted(self.untar_file)
  174. @pytest.mark.slow_test(seconds=1) # Test takes >0.1 and <=1 seconds
  175. def test_archive_extracted_with_cmd_unzip_false(self):
  176. """
  177. test archive.extracted using use_cmd_unzip argument as false
  178. """
  179. ret = self.run_state(
  180. "archive.extracted",
  181. name=ARCHIVE_DIR,
  182. source=self.archive_tar_source,
  183. source_hash=ARCHIVE_TAR_HASH,
  184. use_cmd_unzip=False,
  185. archive_format="tar",
  186. )
  187. if "Timeout" in ret:
  188. self.skipTest("Timeout talking to local tornado server.")
  189. self.assertSaltTrueReturn(ret)
  190. self._check_extracted(self.untar_file)
  191. @pytest.mark.slow_test(seconds=1) # Test takes >0.1 and <=1 seconds
  192. def test_local_archive_extracted(self):
  193. """
  194. test archive.extracted with local file
  195. """
  196. ret = self.run_state(
  197. "archive.extracted",
  198. name=ARCHIVE_DIR,
  199. source=self.archive_local_tar_source,
  200. archive_format="tar",
  201. )
  202. self.assertSaltTrueReturn(ret)
  203. self._check_extracted(self.untar_file)
  204. @pytest.mark.slow_test(seconds=1) # Test takes >0.1 and <=1 seconds
  205. def test_local_archive_extracted_skip_verify(self):
  206. """
  207. test archive.extracted with local file, bad hash and skip_verify
  208. """
  209. ret = self.run_state(
  210. "archive.extracted",
  211. name=ARCHIVE_DIR,
  212. source=self.archive_local_tar_source,
  213. archive_format="tar",
  214. source_hash=ARCHIVE_TAR_BAD_HASH,
  215. skip_verify=True,
  216. )
  217. self.assertSaltTrueReturn(ret)
  218. self._check_extracted(self.untar_file)
  219. @pytest.mark.slow_test(seconds=5) # Test takes >1 and <=5 seconds
  220. def test_local_archive_extracted_with_source_hash(self):
  221. """
  222. test archive.extracted with local file and valid hash
  223. """
  224. ret = self.run_state(
  225. "archive.extracted",
  226. name=ARCHIVE_DIR,
  227. source=self.archive_local_tar_source,
  228. archive_format="tar",
  229. source_hash=ARCHIVE_TAR_HASH,
  230. )
  231. self.assertSaltTrueReturn(ret)
  232. self._check_extracted(self.untar_file)
  233. @pytest.mark.slow_test(seconds=5) # Test takes >1 and <=5 seconds
  234. def test_local_archive_extracted_with_bad_source_hash(self):
  235. """
  236. test archive.extracted with local file and bad hash
  237. """
  238. ret = self.run_state(
  239. "archive.extracted",
  240. name=ARCHIVE_DIR,
  241. source=self.archive_local_tar_source,
  242. archive_format="tar",
  243. source_hash=ARCHIVE_TAR_BAD_HASH,
  244. )
  245. self.assertSaltFalseReturn(ret)
  246. @pytest.mark.slow_test(seconds=1) # Test takes >0.1 and <=1 seconds
  247. def test_local_archive_extracted_with_uppercase_source_hash(self):
  248. """
  249. test archive.extracted with local file and bad hash
  250. """
  251. ret = self.run_state(
  252. "archive.extracted",
  253. name=ARCHIVE_DIR,
  254. source=self.archive_local_tar_source,
  255. archive_format="tar",
  256. source_hash=ARCHIVE_TAR_HASH_UPPER,
  257. )
  258. self.assertSaltTrueReturn(ret)
  259. self._check_extracted(self.untar_file)
  260. @pytest.mark.slow_test(seconds=5) # Test takes >1 and <=5 seconds
  261. def test_archive_extracted_with_non_base_saltenv(self):
  262. """
  263. test archive.extracted with a saltenv other than `base`
  264. """
  265. ret = self.run_function(
  266. "state.sls",
  267. ["issue45893"],
  268. pillar={"issue45893.name": ARCHIVE_DIR},
  269. saltenv="prod",
  270. )
  271. self.assertSaltTrueReturn(ret)
  272. self._check_extracted(os.path.join(ARCHIVE_DIR, self.untar_file))
  273. @pytest.mark.slow_test(seconds=5) # Test takes >1 and <=5 seconds
  274. def test_local_archive_extracted_with_skip_files_list_verify(self):
  275. """
  276. test archive.extracted with local file and skip_files_list_verify set to True
  277. """
  278. expected_comment = (
  279. "existing source sum is the same as the expected one and "
  280. "skip_files_list_verify argument was set to True. "
  281. "Extraction is not needed"
  282. )
  283. ret = self.run_state(
  284. "archive.extracted",
  285. name=ARCHIVE_DIR,
  286. source=self.archive_local_tar_source,
  287. archive_format="tar",
  288. skip_files_list_verify=True,
  289. source_hash_update=True,
  290. source_hash=ARCHIVE_TAR_SHA_HASH,
  291. )
  292. self.assertSaltTrueReturn(ret)
  293. self._check_extracted(self.untar_file)
  294. ret = self.run_state(
  295. "archive.extracted",
  296. name=ARCHIVE_DIR,
  297. source=self.archive_local_tar_source,
  298. archive_format="tar",
  299. skip_files_list_verify=True,
  300. source_hash_update=True,
  301. source_hash=ARCHIVE_TAR_SHA_HASH,
  302. )
  303. self.assertSaltTrueReturn(ret)
  304. self.assertInSaltComment(expected_comment, ret)