Refs #30160 -- Simplified and improved tests for django.utils.archive.

The file executable should have 0o775 permission not only u=x.
The file no_permissions should have 0o644 u=r.
This commit is contained in:
Nick Pope 2019-02-15 23:59:51 +00:00 committed by Mariusz Felisiak
parent 1692f69e37
commit c95d063e77
1 changed files with 28 additions and 54 deletions

View File

@ -1,73 +1,47 @@
import os import os
import shutil
import stat import stat
import sys import sys
import tempfile import tempfile
import unittest import unittest
from django.utils.archive import extract from django.utils import archive
TEST_DIR = os.path.join(os.path.dirname(__file__), 'archives')
class ArchiveTester: class TestArchive(unittest.TestCase):
archive = None
def setUp(self): def setUp(self):
""" self.testdir = os.path.join(os.path.dirname(__file__), 'archives')
Create temporary directory for testing extraction.
"""
self.old_cwd = os.getcwd() self.old_cwd = os.getcwd()
self.tmpdir = tempfile.mkdtemp() os.chdir(self.testdir)
self.addCleanup(shutil.rmtree, self.tmpdir)
self.archive_path = os.path.join(TEST_DIR, self.archive)
self.archive_lead_path = os.path.join(TEST_DIR, "leadpath_%s" % self.archive)
# Always start off in TEST_DIR.
os.chdir(TEST_DIR)
def tearDown(self): def tearDown(self):
os.chdir(self.old_cwd) os.chdir(self.old_cwd)
def test_extract_function(self): def test_extract_function(self):
extract(self.archive_path, self.tmpdir) for entry in os.scandir(self.testdir):
self.check_files(self.tmpdir) with self.subTest(entry.name), tempfile.TemporaryDirectory() as tmpdir:
archive.extract(entry.path, tmpdir)
self.assertTrue(os.path.isfile(os.path.join(tmpdir, '1')))
self.assertTrue(os.path.isfile(os.path.join(tmpdir, '2')))
self.assertTrue(os.path.isfile(os.path.join(tmpdir, 'foo', '1')))
self.assertTrue(os.path.isfile(os.path.join(tmpdir, 'foo', '2')))
self.assertTrue(os.path.isfile(os.path.join(tmpdir, 'foo', 'bar', '1')))
self.assertTrue(os.path.isfile(os.path.join(tmpdir, 'foo', 'bar', '2')))
@unittest.skipIf(sys.platform == 'win32', 'Python on Windows has a limited os.chmod().') @unittest.skipIf(sys.platform == 'win32', 'Python on Windows has a limited os.chmod().')
def test_extract_file_permissions(self): def test_extract_file_permissions(self):
"""Archive.extract() preserves file permissions.""" """archive.extract() preserves file permissions."""
extract(self.archive_path, self.tmpdir) mask = stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO
filepath = os.path.join(self.tmpdir, 'executable') umask = os.umask(0)
# The file has executable permission. os.umask(umask) # Restore the original umask.
self.assertTrue(os.stat(filepath).st_mode & stat.S_IXOTH) for entry in os.scandir(self.testdir):
filepath = os.path.join(self.tmpdir, 'no_permissions') if entry.name.startswith('leadpath_'):
# The file is readable even though it doesn't have permission data in continue
# the archive. with self.subTest(entry.name), tempfile.TemporaryDirectory() as tmpdir:
self.assertTrue(os.stat(filepath).st_mode & stat.S_IROTH) archive.extract(entry.path, tmpdir)
# An executable file in the archive has executable permissions.
def test_extract_function_with_leadpath(self): filepath = os.path.join(tmpdir, 'executable')
extract(self.archive_lead_path, self.tmpdir) self.assertEqual(os.stat(filepath).st_mode & mask, 0o775)
self.check_files(self.tmpdir) # A file is readable even if permission data is missing.
filepath = os.path.join(tmpdir, 'no_permissions')
def check_files(self, tmpdir): self.assertEqual(os.stat(filepath).st_mode & mask, 0o664 & ~umask)
self.assertTrue(os.path.isfile(os.path.join(self.tmpdir, '1')))
self.assertTrue(os.path.isfile(os.path.join(self.tmpdir, '2')))
self.assertTrue(os.path.isfile(os.path.join(self.tmpdir, 'foo', '1')))
self.assertTrue(os.path.isfile(os.path.join(self.tmpdir, 'foo', '2')))
self.assertTrue(os.path.isfile(os.path.join(self.tmpdir, 'foo', 'bar', '1')))
self.assertTrue(os.path.isfile(os.path.join(self.tmpdir, 'foo', 'bar', '2')))
class TestZip(ArchiveTester, unittest.TestCase):
archive = 'foobar.zip'
class TestTar(ArchiveTester, unittest.TestCase):
archive = 'foobar.tar'
class TestGzipTar(ArchiveTester, unittest.TestCase):
archive = 'foobar.tar.gz'
class TestBzip2Tar(ArchiveTester, unittest.TestCase):
archive = 'foobar.tar.bz2'