Skip to content

Commit

Permalink
pythongh-118148: Improve tests for shutil.make_archive() (pythonGH-11…
Browse files Browse the repository at this point in the history
  • Loading branch information
serhiy-storchaka authored Apr 22, 2024
1 parent a6647d1 commit 287d939
Showing 1 changed file with 176 additions and 71 deletions.
247 changes: 176 additions & 71 deletions Lib/test/test_shutil.py
Original file line number Diff line number Diff line change
Expand Up @@ -1615,42 +1615,6 @@ class TestArchives(BaseTest, unittest.TestCase):

### shutil.make_archive

@support.requires_zlib()
def test_make_tarball(self):
# creating something to tar
root_dir, base_dir = self._create_files('')

tmpdir2 = self.mkdtemp()
# force shutil to create the directory
os.rmdir(tmpdir2)
# working with relative paths
work_dir = os.path.dirname(tmpdir2)
rel_base_name = os.path.join(os.path.basename(tmpdir2), 'archive')

with os_helper.change_cwd(work_dir), no_chdir:
base_name = os.path.abspath(rel_base_name)
tarball = make_archive(rel_base_name, 'gztar', root_dir, '.')

# check if the compressed tarball was created
self.assertEqual(tarball, base_name + '.tar.gz')
self.assertTrue(os.path.isfile(tarball))
self.assertTrue(tarfile.is_tarfile(tarball))
with tarfile.open(tarball, 'r:gz') as tf:
self.assertCountEqual(tf.getnames(),
['.', './sub', './sub2',
'./file1', './file2', './sub/file3'])

# trying an uncompressed one
with os_helper.change_cwd(work_dir), no_chdir:
tarball = make_archive(rel_base_name, 'tar', root_dir, '.')
self.assertEqual(tarball, base_name + '.tar')
self.assertTrue(os.path.isfile(tarball))
self.assertTrue(tarfile.is_tarfile(tarball))
with tarfile.open(tarball, 'r') as tf:
self.assertCountEqual(tf.getnames(),
['.', './sub', './sub2',
'./file1', './file2', './sub/file3'])

def _tarinfo(self, path):
with tarfile.open(path) as tar:
names = tar.getnames()
Expand All @@ -1671,6 +1635,92 @@ def _create_files(self, base_dir='dist'):
write_file((root_dir, 'outer'), 'xxx')
return root_dir, base_dir

@support.requires_zlib()
def test_make_tarfile(self):
root_dir, base_dir = self._create_files()
# Test without base_dir.
with os_helper.temp_cwd(), no_chdir:
base_name = os.path.join('dst', 'archive')
archive = make_archive(base_name, 'tar', root_dir)
# check if the compressed tarball was created
self.assertEqual(archive, os.path.abspath(base_name) + '.tar')
self.assertTrue(os.path.isfile(archive))
self.assertTrue(tarfile.is_tarfile(archive))
with tarfile.open(archive, 'r') as tf:
self.assertCountEqual(tf.getnames(),
['.', './dist', './dist/sub', './dist/sub2',
'./dist/file1', './dist/file2', './dist/sub/file3',
'./outer'])

# Test with base_dir.
with os_helper.temp_cwd(), no_chdir:
base_name = os.path.join('dst2', 'archive')
archive = make_archive(base_name, 'tar', root_dir, base_dir)
self.assertEqual(archive, os.path.abspath(base_name) + '.tar')
# check if the uncompressed tarball was created
self.assertTrue(os.path.isfile(archive))
self.assertTrue(tarfile.is_tarfile(archive))
with tarfile.open(archive, 'r') as tf:
self.assertCountEqual(tf.getnames(),
['dist', 'dist/sub', 'dist/sub2',
'dist/file1', 'dist/file2', 'dist/sub/file3'])

# Test with multi-component base_dir.
with os_helper.temp_cwd(), no_chdir:
base_name = os.path.join('dst3', 'archive')
archive = make_archive(base_name, 'tar', root_dir,
os.path.join(base_dir, 'sub'))
self.assertEqual(archive, os.path.abspath(base_name) + '.tar')
self.assertTrue(os.path.isfile(archive))
self.assertTrue(tarfile.is_tarfile(archive))
with tarfile.open(archive, 'r') as tf:
self.assertCountEqual(tf.getnames(),
['dist/sub', 'dist/sub/file3'])

@support.requires_zlib()
def test_make_tarfile_without_rootdir(self):
root_dir, base_dir = self._create_files()
# Test without base_dir.
base_name = os.path.join(self.mkdtemp(), 'dst', 'archive')
base_name = os.path.relpath(base_name, root_dir)
with os_helper.change_cwd(root_dir), no_chdir:
archive = make_archive(base_name, 'gztar')
self.assertEqual(archive, base_name + '.tar.gz')
self.assertTrue(os.path.isfile(archive))
self.assertTrue(tarfile.is_tarfile(archive))
with tarfile.open(archive, 'r:gz') as tf:
self.assertCountEqual(tf.getnames(),
['.', './dist', './dist/sub', './dist/sub2',
'./dist/file1', './dist/file2', './dist/sub/file3',
'./outer'])

# Test with base_dir.
with os_helper.change_cwd(root_dir), no_chdir:
base_name = os.path.join('dst', 'archive')
archive = make_archive(base_name, 'tar', base_dir=base_dir)
self.assertEqual(archive, base_name + '.tar')
self.assertTrue(os.path.isfile(archive))
self.assertTrue(tarfile.is_tarfile(archive))
with tarfile.open(archive, 'r') as tf:
self.assertCountEqual(tf.getnames(),
['dist', 'dist/sub', 'dist/sub2',
'dist/file1', 'dist/file2', 'dist/sub/file3'])

def test_make_tarfile_with_explicit_curdir(self):
# Test with base_dir=os.curdir.
root_dir, base_dir = self._create_files()
with os_helper.temp_cwd(), no_chdir:
base_name = os.path.join('dst', 'archive')
archive = make_archive(base_name, 'tar', root_dir, os.curdir)
self.assertEqual(archive, os.path.abspath(base_name) + '.tar')
self.assertTrue(os.path.isfile(archive))
self.assertTrue(tarfile.is_tarfile(archive))
with tarfile.open(archive, 'r') as tf:
self.assertCountEqual(tf.getnames(),
['.', './dist', './dist/sub', './dist/sub2',
'./dist/file1', './dist/file2', './dist/sub/file3',
'./outer'])

@support.requires_zlib()
@unittest.skipUnless(shutil.which('tar'),
'Need the tar command to run')
Expand Down Expand Up @@ -1720,40 +1770,89 @@ def test_tarfile_vs_tar(self):

@support.requires_zlib()
def test_make_zipfile(self):
# creating something to zip
root_dir, base_dir = self._create_files()
# Test without base_dir.
with os_helper.temp_cwd(), no_chdir:
base_name = os.path.join('dst', 'archive')
archive = make_archive(base_name, 'zip', root_dir)
self.assertEqual(archive, os.path.abspath(base_name) + '.zip')
self.assertTrue(os.path.isfile(archive))
self.assertTrue(zipfile.is_zipfile(archive))
with zipfile.ZipFile(archive) as zf:
self.assertCountEqual(zf.namelist(),
['dist/', 'dist/sub/', 'dist/sub2/',
'dist/file1', 'dist/file2', 'dist/sub/file3',
'outer'])

# Test with base_dir.
with os_helper.temp_cwd(), no_chdir:
base_name = os.path.join('dst2', 'archive')
archive = make_archive(base_name, 'zip', root_dir, base_dir)
self.assertEqual(archive, os.path.abspath(base_name) + '.zip')
self.assertTrue(os.path.isfile(archive))
self.assertTrue(zipfile.is_zipfile(archive))
with zipfile.ZipFile(archive) as zf:
self.assertCountEqual(zf.namelist(),
['dist/', 'dist/sub/', 'dist/sub2/',
'dist/file1', 'dist/file2', 'dist/sub/file3'])

# Test with multi-component base_dir.
with os_helper.temp_cwd(), no_chdir:
base_name = os.path.join('dst3', 'archive')
archive = make_archive(base_name, 'zip', root_dir,
os.path.join(base_dir, 'sub'))
self.assertEqual(archive, os.path.abspath(base_name) + '.zip')
self.assertTrue(os.path.isfile(archive))
self.assertTrue(zipfile.is_zipfile(archive))
with zipfile.ZipFile(archive) as zf:
self.assertCountEqual(zf.namelist(),
['dist/sub/', 'dist/sub/file3'])

tmpdir2 = self.mkdtemp()
# force shutil to create the directory
os.rmdir(tmpdir2)
# working with relative paths
work_dir = os.path.dirname(tmpdir2)
rel_base_name = os.path.join(os.path.basename(tmpdir2), 'archive')

with os_helper.change_cwd(work_dir), no_chdir:
base_name = os.path.abspath(rel_base_name)
res = make_archive(rel_base_name, 'zip', root_dir)
@support.requires_zlib()
def test_make_zipfile_without_rootdir(self):
root_dir, base_dir = self._create_files()
# Test without base_dir.
base_name = os.path.join(self.mkdtemp(), 'dst', 'archive')
base_name = os.path.relpath(base_name, root_dir)
with os_helper.change_cwd(root_dir), no_chdir:
archive = make_archive(base_name, 'zip')
self.assertEqual(archive, base_name + '.zip')
self.assertTrue(os.path.isfile(archive))
self.assertTrue(zipfile.is_zipfile(archive))
with zipfile.ZipFile(archive) as zf:
self.assertCountEqual(zf.namelist(),
['dist/', 'dist/sub/', 'dist/sub2/',
'dist/file1', 'dist/file2', 'dist/sub/file3',
'outer'])

# Test with base_dir.
root_dir, base_dir = self._create_files()
with os_helper.change_cwd(root_dir), no_chdir:
base_name = os.path.join('dst', 'archive')
archive = make_archive(base_name, 'zip', base_dir=base_dir)
self.assertEqual(archive, base_name + '.zip')
self.assertTrue(os.path.isfile(archive))
self.assertTrue(zipfile.is_zipfile(archive))
with zipfile.ZipFile(archive) as zf:
self.assertCountEqual(zf.namelist(),
['dist/', 'dist/sub/', 'dist/sub2/',
'dist/file1', 'dist/file2', 'dist/sub/file3'])

self.assertEqual(res, base_name + '.zip')
self.assertTrue(os.path.isfile(res))
self.assertTrue(zipfile.is_zipfile(res))
with zipfile.ZipFile(res) as zf:
self.assertCountEqual(zf.namelist(),
['dist/', 'dist/sub/', 'dist/sub2/',
'dist/file1', 'dist/file2', 'dist/sub/file3',
'outer'])

with os_helper.change_cwd(work_dir), no_chdir:
base_name = os.path.abspath(rel_base_name)
res = make_archive(rel_base_name, 'zip', root_dir, base_dir)

self.assertEqual(res, base_name + '.zip')
self.assertTrue(os.path.isfile(res))
self.assertTrue(zipfile.is_zipfile(res))
with zipfile.ZipFile(res) as zf:
self.assertCountEqual(zf.namelist(),
['dist/', 'dist/sub/', 'dist/sub2/',
'dist/file1', 'dist/file2', 'dist/sub/file3'])
@support.requires_zlib()
def test_make_zipfile_with_explicit_curdir(self):
# Test with base_dir=os.curdir.
root_dir, base_dir = self._create_files()
with os_helper.temp_cwd(), no_chdir:
base_name = os.path.join('dst', 'archive')
archive = make_archive(base_name, 'zip', root_dir, os.curdir)
self.assertEqual(archive, os.path.abspath(base_name) + '.zip')
self.assertTrue(os.path.isfile(archive))
self.assertTrue(zipfile.is_zipfile(archive))
with zipfile.ZipFile(archive) as zf:
self.assertCountEqual(zf.namelist(),
['dist/', 'dist/sub/', 'dist/sub2/',
'dist/file1', 'dist/file2', 'dist/sub/file3',
'outer'])

@support.requires_zlib()
@unittest.skipUnless(shutil.which('zip'),
Expand Down Expand Up @@ -1923,17 +2022,19 @@ def archiver(base_name, base_dir, **kw):
unregister_archive_format('xxx')

def test_make_tarfile_in_curdir(self):
# Issue #21280
# Issue #21280: Test with the archive in the current directory.
root_dir = self.mkdtemp()
with os_helper.change_cwd(root_dir), no_chdir:
# root_dir must be None, so the archive path is relative.
self.assertEqual(make_archive('test', 'tar'), 'test.tar')
self.assertTrue(os.path.isfile('test.tar'))

@support.requires_zlib()
def test_make_zipfile_in_curdir(self):
# Issue #21280
# Issue #21280: Test with the archive in the current directory.
root_dir = self.mkdtemp()
with os_helper.change_cwd(root_dir), no_chdir:
# root_dir must be None, so the archive path is relative.
self.assertEqual(make_archive('test', 'zip'), 'test.zip')
self.assertTrue(os.path.isfile('test.zip'))

Expand All @@ -1954,10 +2055,11 @@ def test_register_archive_format(self):
self.assertNotIn('xxx', formats)

def test_make_tarfile_rootdir_nodir(self):
# GH-99203
# GH-99203: Test with root_dir is not a real directory.
self.addCleanup(os_helper.unlink, f'{TESTFN}.tar')
for dry_run in (False, True):
with self.subTest(dry_run=dry_run):
# root_dir does not exist.
tmp_dir = self.mkdtemp()
nonexisting_file = os.path.join(tmp_dir, 'nonexisting')
with self.assertRaises(FileNotFoundError) as cm:
Expand All @@ -1966,6 +2068,7 @@ def test_make_tarfile_rootdir_nodir(self):
self.assertEqual(cm.exception.filename, nonexisting_file)
self.assertFalse(os.path.exists(f'{TESTFN}.tar'))

# root_dir is a file.
tmp_fd, tmp_file = tempfile.mkstemp(dir=tmp_dir)
os.close(tmp_fd)
with self.assertRaises(NotADirectoryError) as cm:
Expand All @@ -1976,10 +2079,11 @@ def test_make_tarfile_rootdir_nodir(self):

@support.requires_zlib()
def test_make_zipfile_rootdir_nodir(self):
# GH-99203
# GH-99203: Test with root_dir is not a real directory.
self.addCleanup(os_helper.unlink, f'{TESTFN}.zip')
for dry_run in (False, True):
with self.subTest(dry_run=dry_run):
# root_dir does not exist.
tmp_dir = self.mkdtemp()
nonexisting_file = os.path.join(tmp_dir, 'nonexisting')
with self.assertRaises(FileNotFoundError) as cm:
Expand All @@ -1988,6 +2092,7 @@ def test_make_zipfile_rootdir_nodir(self):
self.assertEqual(cm.exception.filename, nonexisting_file)
self.assertFalse(os.path.exists(f'{TESTFN}.zip'))

# root_dir is a file.
tmp_fd, tmp_file = tempfile.mkstemp(dir=tmp_dir)
os.close(tmp_fd)
with self.assertRaises(NotADirectoryError) as cm:
Expand Down

0 comments on commit 287d939

Please sign in to comment.