blob: d3fb24ad56272bde9fdae55af08c006a79b65ff6 [file] [log] [blame]
Jason R. Coombse7437a72011-12-26 12:17:01 -05001# -*- coding: utf-8 -*-
Tarek Ziadéeb5f27e2009-05-17 12:12:02 +00002"""Tests for distutils.archive_util."""
Tarek Ziadéeb5f27e2009-05-17 12:12:02 +00003import unittest
4import os
Jason R. Coombsbbb08032011-12-28 10:45:08 -05005import sys
Tarek Ziadé77c8b372009-05-28 13:01:13 +00006import tarfile
Tarek Ziadé93fb3aa2009-05-18 12:29:06 +00007from os.path import splitdrive
Tarek Ziadé77c8b372009-05-28 13:01:13 +00008import warnings
Tarek Ziadéeb5f27e2009-05-17 12:12:02 +00009
Antoine Pitrou2c50a092011-03-15 21:02:59 +010010from distutils import archive_util
Tarek Ziadéeb5f27e2009-05-17 12:12:02 +000011from distutils.archive_util import (check_archive_formats, make_tarball,
Tarek Ziadé53fdb182009-10-24 13:42:10 +000012 make_zipfile, make_archive,
13 ARCHIVE_FORMATS)
Tarek Ziadé77c8b372009-05-28 13:01:13 +000014from distutils.spawn import find_executable, spawn
Tarek Ziadéeb5f27e2009-05-17 12:12:02 +000015from distutils.tests import support
Antoine Pitrou2c50a092011-03-15 21:02:59 +010016from test.support import check_warnings, run_unittest, patch
Tarek Ziadéeb5f27e2009-05-17 12:12:02 +000017
18try:
19 import zipfile
20 ZIP_SUPPORT = True
21except ImportError:
22 ZIP_SUPPORT = find_executable('zip')
23
Antoine Pitrou2c50a092011-03-15 21:02:59 +010024try:
25 import zlib
26 ZLIB_SUPPORT = True
27except ImportError:
28 ZLIB_SUPPORT = False
29
Jason R. Coombsbbb08032011-12-28 10:45:08 -050030def can_fs_encode(filename):
31 """
32 Return True if the filename can be saved in the file system.
33 """
34 if os.path.supports_unicode_filenames:
35 return True
36 try:
37 filename.encode(sys.getfilesystemencoding())
38 except UnicodeEncodeError:
39 return False
40 return True
41
Antoine Pitrou2c50a092011-03-15 21:02:59 +010042
Tarek Ziadéeb5f27e2009-05-17 12:12:02 +000043class ArchiveUtilTestCase(support.TempdirManager,
Tarek Ziadée2cedaa2009-05-28 14:02:58 +000044 support.LoggingSilencer,
Tarek Ziadéeb5f27e2009-05-17 12:12:02 +000045 unittest.TestCase):
46
Antoine Pitrou2c50a092011-03-15 21:02:59 +010047 @unittest.skipUnless(ZLIB_SUPPORT, 'Need zlib support to run')
Tarek Ziadéeb5f27e2009-05-17 12:12:02 +000048 def test_make_tarball(self):
Jason R. Coombse7437a72011-12-26 12:17:01 -050049 self._make_tarball('archive')
50
51 @unittest.skipUnless(ZLIB_SUPPORT, 'Need zlib support to run')
Jason R. Coombsbbb08032011-12-28 10:45:08 -050052 @unittest.skipUnless(can_fs_encode('årchiv'),
53 'File system cannot handle this filename')
Jason R. Coombse7437a72011-12-26 12:17:01 -050054 def test_make_tarball_latin1(self):
55 """
56 Mirror test_make_tarball, except filename contains latin characters.
57 """
58 self._make_tarball('årchiv') # note this isn't a real word
59
60 @unittest.skipUnless(ZLIB_SUPPORT, 'Need zlib support to run')
Jason R. Coombsbbb08032011-12-28 10:45:08 -050061 @unittest.skipUnless(can_fs_encode('のアーカイブ'),
62 'File system cannot handle this filename')
Jason R. Coombse7437a72011-12-26 12:17:01 -050063 def test_make_tarball_extended(self):
64 """
65 Mirror test_make_tarball, except filename contains extended
66 characters outside the latin charset.
67 """
68 self._make_tarball('のアーカイブ') # japanese for archive
69
70 def _make_tarball(self, target_name):
Tarek Ziadéeb5f27e2009-05-17 12:12:02 +000071 # creating something to tar
72 tmpdir = self.mkdtemp()
73 self.write_file([tmpdir, 'file1'], 'xxx')
74 self.write_file([tmpdir, 'file2'], 'xxx')
Tarek Ziadé77c8b372009-05-28 13:01:13 +000075 os.mkdir(os.path.join(tmpdir, 'sub'))
76 self.write_file([tmpdir, 'sub', 'file3'], 'xxx')
Tarek Ziadéeb5f27e2009-05-17 12:12:02 +000077
78 tmpdir2 = self.mkdtemp()
Tarek Ziadé93fb3aa2009-05-18 12:29:06 +000079 unittest.skipUnless(splitdrive(tmpdir)[0] == splitdrive(tmpdir2)[0],
80 "Source and target should be on same drive")
81
Jason R. Coombse7437a72011-12-26 12:17:01 -050082 base_name = os.path.join(tmpdir2, target_name)
Tarek Ziadé40c00272009-05-18 08:22:38 +000083
84 # working with relative paths to avoid tar warnings
85 old_dir = os.getcwd()
86 os.chdir(tmpdir)
87 try:
Tarek Ziadé93fb3aa2009-05-18 12:29:06 +000088 make_tarball(splitdrive(base_name)[1], '.')
Tarek Ziadé40c00272009-05-18 08:22:38 +000089 finally:
90 os.chdir(old_dir)
Tarek Ziadéeb5f27e2009-05-17 12:12:02 +000091
92 # check if the compressed tarball was created
93 tarball = base_name + '.tar.gz'
Georg Brandlab91fde2009-08-13 08:51:18 +000094 self.assertTrue(os.path.exists(tarball))
Tarek Ziadéeb5f27e2009-05-17 12:12:02 +000095
96 # trying an uncompressed one
Jason R. Coombse7437a72011-12-26 12:17:01 -050097 base_name = os.path.join(tmpdir2, target_name)
Tarek Ziadé40c00272009-05-18 08:22:38 +000098 old_dir = os.getcwd()
99 os.chdir(tmpdir)
100 try:
Tarek Ziadé93fb3aa2009-05-18 12:29:06 +0000101 make_tarball(splitdrive(base_name)[1], '.', compress=None)
Tarek Ziadé40c00272009-05-18 08:22:38 +0000102 finally:
103 os.chdir(old_dir)
Tarek Ziadéeb5f27e2009-05-17 12:12:02 +0000104 tarball = base_name + '.tar'
Georg Brandlab91fde2009-08-13 08:51:18 +0000105 self.assertTrue(os.path.exists(tarball))
Tarek Ziadéeb5f27e2009-05-17 12:12:02 +0000106
Tarek Ziadé77c8b372009-05-28 13:01:13 +0000107 def _tarinfo(self, path):
108 tar = tarfile.open(path)
109 try:
110 names = tar.getnames()
111 names.sort()
112 return tuple(names)
113 finally:
114 tar.close()
115
116 def _create_files(self):
117 # creating something to tar
118 tmpdir = self.mkdtemp()
119 dist = os.path.join(tmpdir, 'dist')
120 os.mkdir(dist)
121 self.write_file([dist, 'file1'], 'xxx')
122 self.write_file([dist, 'file2'], 'xxx')
123 os.mkdir(os.path.join(dist, 'sub'))
124 self.write_file([dist, 'sub', 'file3'], 'xxx')
125 os.mkdir(os.path.join(dist, 'sub2'))
126 tmpdir2 = self.mkdtemp()
127 base_name = os.path.join(tmpdir2, 'archive')
128 return tmpdir, tmpdir2, base_name
129
Antoine Pitrou2c50a092011-03-15 21:02:59 +0100130 @unittest.skipUnless(find_executable('tar') and find_executable('gzip')
131 and ZLIB_SUPPORT,
132 'Need the tar, gzip and zlib command to run')
Tarek Ziadé77c8b372009-05-28 13:01:13 +0000133 def test_tarfile_vs_tar(self):
134 tmpdir, tmpdir2, base_name = self._create_files()
135 old_dir = os.getcwd()
136 os.chdir(tmpdir)
137 try:
138 make_tarball(base_name, 'dist')
139 finally:
140 os.chdir(old_dir)
141
142 # check if the compressed tarball was created
143 tarball = base_name + '.tar.gz'
Georg Brandlab91fde2009-08-13 08:51:18 +0000144 self.assertTrue(os.path.exists(tarball))
Tarek Ziadé77c8b372009-05-28 13:01:13 +0000145
146 # now create another tarball using `tar`
147 tarball2 = os.path.join(tmpdir, 'archive2.tar.gz')
Tarek Ziadée2cedaa2009-05-28 14:02:58 +0000148 tar_cmd = ['tar', '-cf', 'archive2.tar', 'dist']
149 gzip_cmd = ['gzip', '-f9', 'archive2.tar']
Tarek Ziadé77c8b372009-05-28 13:01:13 +0000150 old_dir = os.getcwd()
151 os.chdir(tmpdir)
152 try:
Tarek Ziadée2cedaa2009-05-28 14:02:58 +0000153 spawn(tar_cmd)
154 spawn(gzip_cmd)
Tarek Ziadé77c8b372009-05-28 13:01:13 +0000155 finally:
156 os.chdir(old_dir)
157
Georg Brandlab91fde2009-08-13 08:51:18 +0000158 self.assertTrue(os.path.exists(tarball2))
Tarek Ziadé77c8b372009-05-28 13:01:13 +0000159 # let's compare both tarballs
Ezio Melotti19f2aeb2010-11-21 01:30:29 +0000160 self.assertEqual(self._tarinfo(tarball), self._tarinfo(tarball2))
Tarek Ziadé77c8b372009-05-28 13:01:13 +0000161
162 # trying an uncompressed one
163 base_name = os.path.join(tmpdir2, 'archive')
164 old_dir = os.getcwd()
165 os.chdir(tmpdir)
166 try:
167 make_tarball(base_name, 'dist', compress=None)
168 finally:
169 os.chdir(old_dir)
170 tarball = base_name + '.tar'
Georg Brandlab91fde2009-08-13 08:51:18 +0000171 self.assertTrue(os.path.exists(tarball))
Tarek Ziadé77c8b372009-05-28 13:01:13 +0000172
173 # now for a dry_run
174 base_name = os.path.join(tmpdir2, 'archive')
175 old_dir = os.getcwd()
176 os.chdir(tmpdir)
177 try:
178 make_tarball(base_name, 'dist', compress=None, dry_run=True)
179 finally:
180 os.chdir(old_dir)
181 tarball = base_name + '.tar'
Georg Brandlab91fde2009-08-13 08:51:18 +0000182 self.assertTrue(os.path.exists(tarball))
Tarek Ziadé77c8b372009-05-28 13:01:13 +0000183
184 @unittest.skipUnless(find_executable('compress'),
185 'The compress program is required')
186 def test_compress_deprecated(self):
187 tmpdir, tmpdir2, base_name = self._create_files()
188
189 # using compress and testing the PendingDeprecationWarning
190 old_dir = os.getcwd()
191 os.chdir(tmpdir)
192 try:
193 with check_warnings() as w:
194 warnings.simplefilter("always")
195 make_tarball(base_name, 'dist', compress='compress')
196 finally:
197 os.chdir(old_dir)
198 tarball = base_name + '.tar.Z'
Georg Brandlab91fde2009-08-13 08:51:18 +0000199 self.assertTrue(os.path.exists(tarball))
Ezio Melotti19f2aeb2010-11-21 01:30:29 +0000200 self.assertEqual(len(w.warnings), 1)
Tarek Ziadé77c8b372009-05-28 13:01:13 +0000201
202 # same test with dry_run
203 os.remove(tarball)
204 old_dir = os.getcwd()
205 os.chdir(tmpdir)
206 try:
207 with check_warnings() as w:
208 warnings.simplefilter("always")
209 make_tarball(base_name, 'dist', compress='compress',
210 dry_run=True)
211 finally:
212 os.chdir(old_dir)
Serhiy Storchaka39989152013-11-17 00:17:46 +0200213 self.assertFalse(os.path.exists(tarball))
Ezio Melotti19f2aeb2010-11-21 01:30:29 +0000214 self.assertEqual(len(w.warnings), 1)
Tarek Ziadé77c8b372009-05-28 13:01:13 +0000215
Antoine Pitrou2c50a092011-03-15 21:02:59 +0100216 @unittest.skipUnless(ZIP_SUPPORT and ZLIB_SUPPORT,
217 'Need zip and zlib support to run')
Tarek Ziadé441efa82009-05-17 15:03:23 +0000218 def test_make_zipfile(self):
Tarek Ziadéeb5f27e2009-05-17 12:12:02 +0000219 # creating something to tar
220 tmpdir = self.mkdtemp()
221 self.write_file([tmpdir, 'file1'], 'xxx')
222 self.write_file([tmpdir, 'file2'], 'xxx')
223
224 tmpdir2 = self.mkdtemp()
225 base_name = os.path.join(tmpdir2, 'archive')
226 make_zipfile(base_name, tmpdir)
227
228 # check if the compressed tarball was created
229 tarball = base_name + '.zip'
Antoine Pitrou2c50a092011-03-15 21:02:59 +0100230 self.assertTrue(os.path.exists(tarball))
231
232 @unittest.skipUnless(ZIP_SUPPORT, 'Need zip support to run')
233 def test_make_zipfile_no_zlib(self):
234 patch(self, archive_util.zipfile, 'zlib', None) # force zlib ImportError
235
236 called = []
237 zipfile_class = zipfile.ZipFile
238 def fake_zipfile(*a, **kw):
239 if kw.get('compression', None) == zipfile.ZIP_STORED:
240 called.append((a, kw))
241 return zipfile_class(*a, **kw)
242
243 patch(self, archive_util.zipfile, 'ZipFile', fake_zipfile)
244
245 # create something to tar and compress
246 tmpdir, tmpdir2, base_name = self._create_files()
247 make_zipfile(base_name, tmpdir)
248
249 tarball = base_name + '.zip'
250 self.assertEqual(called,
251 [((tarball, "w"), {'compression': zipfile.ZIP_STORED})])
252 self.assertTrue(os.path.exists(tarball))
Tarek Ziadéeb5f27e2009-05-17 12:12:02 +0000253
254 def test_check_archive_formats(self):
Ezio Melotti19f2aeb2010-11-21 01:30:29 +0000255 self.assertEqual(check_archive_formats(['gztar', 'xxx', 'zip']),
256 'xxx')
257 self.assertEqual(check_archive_formats(['gztar', 'zip']), None)
Tarek Ziadéeb5f27e2009-05-17 12:12:02 +0000258
259 def test_make_archive(self):
260 tmpdir = self.mkdtemp()
261 base_name = os.path.join(tmpdir, 'archive')
262 self.assertRaises(ValueError, make_archive, base_name, 'xxx')
263
Tarek Ziadé53fdb182009-10-24 13:42:10 +0000264 def test_make_archive_cwd(self):
265 current_dir = os.getcwd()
266 def _breaks(*args, **kw):
267 raise RuntimeError()
268 ARCHIVE_FORMATS['xxx'] = (_breaks, [], 'xxx file')
269 try:
270 try:
271 make_archive('xxx', 'xxx', root_dir=self.mkdtemp())
272 except:
273 pass
Ezio Melotti19f2aeb2010-11-21 01:30:29 +0000274 self.assertEqual(os.getcwd(), current_dir)
Tarek Ziadé53fdb182009-10-24 13:42:10 +0000275 finally:
276 del ARCHIVE_FORMATS['xxx']
277
Tarek Ziadéeb5f27e2009-05-17 12:12:02 +0000278def test_suite():
279 return unittest.makeSuite(ArchiveUtilTestCase)
280
281if __name__ == "__main__":
Éric Araujob344dd02011-02-02 21:38:37 +0000282 run_unittest(test_suite())