1
0

test_archive.py 11 KB

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