test_archive.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  1. # -*- coding: utf-8 -*-
  2. """
  3. Tests for the archive state
  4. """
  5. from __future__ import absolute_import, print_function, unicode_literals
  6. import os
  7. import shutil
  8. import textwrap
  9. import pytest
  10. import salt.utils.files
  11. import salt.utils.path
  12. import salt.utils.platform
  13. import salt.utils.stringutils
  14. from salt.ext import six
  15. from tests.support.case import ModuleCase
  16. from tests.support.runtests import RUNTIME_VARS
  17. from tests.support.unit import skipIf
  18. try:
  19. import zipfile # pylint: disable=unused-import
  20. HAS_ZIPFILE = True
  21. except ImportError:
  22. HAS_ZIPFILE = False
  23. @pytest.mark.destructive_test
  24. @pytest.mark.windows_whitelisted
  25. class ArchiveTest(ModuleCase):
  26. """
  27. Validate the archive module
  28. """
  29. @classmethod
  30. def setUpClass(cls):
  31. # Base path used for test artifacts
  32. cls.base_path = os.path.join(RUNTIME_VARS.TMP, "modules", "archive")
  33. @classmethod
  34. def tearDownClass(cls):
  35. cls.base_path = None
  36. def _set_artifact_paths(self, arch_fmt):
  37. """
  38. Define the paths for the source, archive, and destination files
  39. :param str arch_fmt: The archive format used in the test
  40. """
  41. self.src = os.path.join(self.base_path, "{0}_src_dir".format(arch_fmt))
  42. self.src_file = os.path.join(self.src, "file")
  43. self.arch = os.path.join(self.base_path, "archive.{0}".format(arch_fmt))
  44. self.dst = os.path.join(self.base_path, "{0}_dst_dir".format(arch_fmt))
  45. def _set_up(self, arch_fmt, unicode_filename=False):
  46. """
  47. Create source file tree and destination directory
  48. :param str arch_fmt: The archive format used in the test
  49. """
  50. self._set_artifact_paths(arch_fmt)
  51. # Remove the artifacts if any present
  52. if any([os.path.exists(f) for f in (self.src, self.arch, self.dst)]):
  53. self._tear_down()
  54. self._set_artifact_paths(arch_fmt)
  55. # Create source
  56. os.makedirs(self.src)
  57. if unicode_filename:
  58. filename = "file®"
  59. else:
  60. filename = "file"
  61. with salt.utils.files.fopen(os.path.join(self.src, filename), "wb") as theorem:
  62. if six.PY3 and salt.utils.platform.is_windows():
  63. encoding = "utf-8"
  64. else:
  65. encoding = None
  66. theorem.write(
  67. salt.utils.stringutils.to_bytes(
  68. textwrap.dedent(
  69. """\
  70. Compression theorem of computational complexity theory:
  71. Given a Gödel numbering $φ$ of the computable functions and a
  72. Blum complexity measure $Φ$ where a complexity class for a
  73. boundary function $f$ is defined as
  74. $\\mathrm C(f) := \\{φ_i ∈ \\mathbb R^{(1)} | (∀^∞ x) Φ_i(x) ≤ f(x)\\}$.
  75. Then there exists a total computable function $f$ so that for
  76. all $i$
  77. $\\mathrm{Dom}(φ_i) = \\mathrm{Dom}(φ_{f(i)})$
  78. and
  79. $\\mathrm C(φ_i) ⊊ \\mathrm{C}(φ_{f(i)})$.
  80. """
  81. ),
  82. encoding=encoding,
  83. )
  84. )
  85. # Create destination
  86. os.makedirs(self.dst)
  87. def _tear_down(self):
  88. """
  89. Remove source file tree, archive, and destination file tree
  90. """
  91. for f in (self.src, self.arch, self.dst):
  92. if os.path.exists(f):
  93. if os.path.isdir(f):
  94. shutil.rmtree(f, ignore_errors=True)
  95. else:
  96. os.remove(f)
  97. del self.dst
  98. del self.src
  99. del self.arch
  100. del self.src_file
  101. def _assert_artifacts_in_ret(self, ret, file_only=False, unix_sep=False):
  102. """
  103. Assert that the artifact source files are printed in the source command
  104. output
  105. """
  106. def normdir(path):
  107. normdir = os.path.normcase(os.path.abspath(path))
  108. if salt.utils.platform.is_windows():
  109. # Remove the drive portion of path
  110. if len(normdir) >= 2 and normdir[1] == ":":
  111. normdir = normdir.split(":", 1)[1]
  112. normdir = normdir.lstrip(os.path.sep)
  113. # Unzipped paths might have unix line endings
  114. if unix_sep:
  115. normdir = normdir.replace(os.path.sep, "/")
  116. return normdir
  117. # Try to find source directory and file in output lines
  118. dir_in_ret = None
  119. file_in_ret = None
  120. for line in ret:
  121. if normdir(self.src) in os.path.normcase(line) and not normdir(
  122. self.src_file
  123. ) in os.path.normcase(line):
  124. dir_in_ret = True
  125. if normdir(self.src_file) in os.path.normcase(line):
  126. file_in_ret = True
  127. # Assert number of lines, reporting of source directory and file
  128. self.assertTrue(len(ret) >= 1 if file_only else 2)
  129. if not file_only:
  130. self.assertTrue(dir_in_ret)
  131. self.assertTrue(file_in_ret)
  132. @skipIf(not salt.utils.path.which("tar"), "Cannot find tar executable")
  133. @pytest.mark.slow_test(seconds=30) # Test takes >10 and <=30 seconds
  134. def test_tar_pack(self):
  135. """
  136. Validate using the tar function to create archives
  137. """
  138. self._set_up(arch_fmt="tar")
  139. # Test create archive
  140. ret = self.run_function("archive.tar", ["-cvf", self.arch], sources=self.src)
  141. self.assertTrue(isinstance(ret, list), six.text_type(ret))
  142. self._assert_artifacts_in_ret(ret)
  143. self._tear_down()
  144. @skipIf(not salt.utils.path.which("tar"), "Cannot find tar executable")
  145. @pytest.mark.slow_test(seconds=30) # Test takes >10 and <=30 seconds
  146. def test_tar_unpack(self):
  147. """
  148. Validate using the tar function to extract archives
  149. """
  150. self._set_up(arch_fmt="tar")
  151. self.run_function("archive.tar", ["-cvf", self.arch], sources=self.src)
  152. # Test extract archive
  153. ret = self.run_function("archive.tar", ["-xvf", self.arch], dest=self.dst)
  154. self.assertTrue(isinstance(ret, list), six.text_type(ret))
  155. self._assert_artifacts_in_ret(ret)
  156. self._tear_down()
  157. @skipIf(not salt.utils.path.which("tar"), "Cannot find tar executable")
  158. @pytest.mark.slow_test(seconds=30) # Test takes >10 and <=30 seconds
  159. def test_tar_pack_unicode(self):
  160. """
  161. Validate using the tar function to create archives
  162. """
  163. self._set_up(arch_fmt="tar", unicode_filename=True)
  164. # Test create archive
  165. ret = self.run_function("archive.tar", ["-cvf", self.arch], sources=self.src)
  166. self.assertTrue(isinstance(ret, list), six.text_type(ret))
  167. self._assert_artifacts_in_ret(ret)
  168. self._tear_down()
  169. @skipIf(not salt.utils.path.which("tar"), "Cannot find tar executable")
  170. @pytest.mark.slow_test(seconds=30) # Test takes >10 and <=30 seconds
  171. def test_tar_unpack_unicode(self):
  172. """
  173. Validate using the tar function to extract archives
  174. """
  175. self._set_up(arch_fmt="tar", unicode_filename=True)
  176. self.run_function("archive.tar", ["-cvf", self.arch], sources=self.src)
  177. # Test extract archive
  178. ret = self.run_function("archive.tar", ["-xvf", self.arch], dest=self.dst)
  179. self.assertTrue(isinstance(ret, list), six.text_type(ret))
  180. self._assert_artifacts_in_ret(ret)
  181. self._tear_down()
  182. @skipIf(not salt.utils.path.which("tar"), "Cannot find tar executable")
  183. @pytest.mark.slow_test(seconds=30) # Test takes >10 and <=30 seconds
  184. def test_tar_list_unicode(self):
  185. """
  186. Validate using the tar function to extract archives
  187. """
  188. self._set_up(arch_fmt="tar", unicode_filename=True)
  189. self.run_function("archive.tar", ["-cvf", self.arch], sources=self.src)
  190. # Test list archive
  191. ret = self.run_function("archive.list", name=self.arch)
  192. self.assertTrue(isinstance(ret, list), six.text_type(ret))
  193. self._assert_artifacts_in_ret(ret)
  194. self._tear_down()
  195. @skipIf(not salt.utils.path.which("gzip"), "Cannot find gzip executable")
  196. @pytest.mark.slow_test(seconds=1) # Test takes >0.1 and <=1 seconds
  197. def test_gzip(self):
  198. """
  199. Validate using the gzip function
  200. """
  201. self._set_up(arch_fmt="gz")
  202. # Test create archive
  203. ret = self.run_function("archive.gzip", [self.src_file], options="-v")
  204. self.assertTrue(isinstance(ret, list), six.text_type(ret))
  205. self._assert_artifacts_in_ret(ret, file_only=True)
  206. self._tear_down()
  207. @skipIf(not salt.utils.path.which("gzip"), "Cannot find gzip executable")
  208. @skipIf(not salt.utils.path.which("gunzip"), "Cannot find gunzip executable")
  209. @pytest.mark.slow_test(seconds=1) # Test takes >0.1 and <=1 seconds
  210. def test_gunzip(self):
  211. """
  212. Validate using the gunzip function
  213. """
  214. self._set_up(arch_fmt="gz")
  215. self.run_function("archive.gzip", [self.src_file], options="-v")
  216. # Test extract archive
  217. ret = self.run_function("archive.gunzip", [self.src_file + ".gz"], options="-v")
  218. self.assertTrue(isinstance(ret, list), six.text_type(ret))
  219. self._assert_artifacts_in_ret(ret, file_only=True)
  220. self._tear_down()
  221. @skipIf(not salt.utils.path.which("zip"), "Cannot find zip executable")
  222. @pytest.mark.slow_test(seconds=1) # Test takes >0.1 and <=1 seconds
  223. def test_cmd_zip(self):
  224. """
  225. Validate using the cmd_zip function
  226. """
  227. self._set_up(arch_fmt="zip")
  228. # Test create archive
  229. ret = self.run_function("archive.cmd_zip", [self.arch, self.src])
  230. self.assertTrue(isinstance(ret, list), six.text_type(ret))
  231. self._assert_artifacts_in_ret(ret)
  232. self._tear_down()
  233. @skipIf(not salt.utils.path.which("zip"), "Cannot find zip executable")
  234. @skipIf(not salt.utils.path.which("unzip"), "Cannot find unzip executable")
  235. @pytest.mark.slow_test(seconds=1) # Test takes >0.1 and <=1 seconds
  236. def test_cmd_unzip(self):
  237. """
  238. Validate using the cmd_unzip function
  239. """
  240. self._set_up(arch_fmt="zip")
  241. self.run_function("archive.cmd_zip", [self.arch, self.src])
  242. # Test create archive
  243. ret = self.run_function("archive.cmd_unzip", [self.arch, self.dst])
  244. self.assertTrue(isinstance(ret, list), six.text_type(ret))
  245. self._assert_artifacts_in_ret(ret)
  246. self._tear_down()
  247. @skipIf(not HAS_ZIPFILE, "Cannot find zipfile python module")
  248. @pytest.mark.slow_test(seconds=30) # Test takes >10 and <=30 seconds
  249. def test_zip(self):
  250. """
  251. Validate using the zip function
  252. """
  253. self._set_up(arch_fmt="zip")
  254. # Test create archive
  255. ret = self.run_function("archive.zip", [self.arch, self.src])
  256. self.assertTrue(isinstance(ret, list), six.text_type(ret))
  257. self._assert_artifacts_in_ret(ret)
  258. self._tear_down()
  259. @skipIf(not HAS_ZIPFILE, "Cannot find zipfile python module")
  260. @pytest.mark.slow_test(seconds=30) # Test takes >10 and <=30 seconds
  261. def test_unzip(self):
  262. """
  263. Validate using the unzip function
  264. """
  265. self._set_up(arch_fmt="zip")
  266. self.run_function("archive.zip", [self.arch, self.src])
  267. # Test create archive
  268. ret = self.run_function("archive.unzip", [self.arch, self.dst])
  269. self.assertTrue(isinstance(ret, list), six.text_type(ret))
  270. self._assert_artifacts_in_ret(ret, unix_sep=False)
  271. self._tear_down()
  272. @skipIf(not salt.utils.path.which("rar"), "Cannot find rar executable")
  273. def test_rar(self):
  274. """
  275. Validate using the rar function
  276. """
  277. self._set_up(arch_fmt="rar")
  278. # Test create archive
  279. ret = self.run_function("archive.rar", [self.arch, self.src])
  280. self.assertTrue(isinstance(ret, list), six.text_type(ret))
  281. self._assert_artifacts_in_ret(ret)
  282. self._tear_down()
  283. @skipIf(not salt.utils.path.which("rar"), "Cannot find rar executable")
  284. @skipIf(not salt.utils.path.which("unrar"), "Cannot find unrar executable")
  285. def test_unrar(self):
  286. """
  287. Validate using the unrar function
  288. """
  289. self._set_up(arch_fmt="rar")
  290. self.run_function("archive.rar", [self.arch, self.src])
  291. # Test create archive
  292. ret = self.run_function("archive.unrar", [self.arch, self.dst])
  293. self.assertTrue(isinstance(ret, list), six.text_type(ret))
  294. self._assert_artifacts_in_ret(ret)
  295. self._tear_down()