diff --git a/tests/utils_tests/test_archive.py b/tests/utils_tests/test_archive.py index 42ced7768b..dfbef8ab18 100644 --- a/tests/utils_tests/test_archive.py +++ b/tests/utils_tests/test_archive.py @@ -1,73 +1,47 @@ import os -import shutil import stat import sys import tempfile import unittest -from django.utils.archive import extract - -TEST_DIR = os.path.join(os.path.dirname(__file__), 'archives') +from django.utils import archive -class ArchiveTester: - archive = None +class TestArchive(unittest.TestCase): def setUp(self): - """ - Create temporary directory for testing extraction. - """ + self.testdir = os.path.join(os.path.dirname(__file__), 'archives') self.old_cwd = os.getcwd() - self.tmpdir = tempfile.mkdtemp() - 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) + os.chdir(self.testdir) def tearDown(self): os.chdir(self.old_cwd) def test_extract_function(self): - extract(self.archive_path, self.tmpdir) - self.check_files(self.tmpdir) + for entry in os.scandir(self.testdir): + 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().') def test_extract_file_permissions(self): - """Archive.extract() preserves file permissions.""" - extract(self.archive_path, self.tmpdir) - filepath = os.path.join(self.tmpdir, 'executable') - # The file has executable permission. - self.assertTrue(os.stat(filepath).st_mode & stat.S_IXOTH) - filepath = os.path.join(self.tmpdir, 'no_permissions') - # The file is readable even though it doesn't have permission data in - # the archive. - self.assertTrue(os.stat(filepath).st_mode & stat.S_IROTH) - - def test_extract_function_with_leadpath(self): - extract(self.archive_lead_path, self.tmpdir) - self.check_files(self.tmpdir) - - def check_files(self, tmpdir): - 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' + """archive.extract() preserves file permissions.""" + mask = stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO + umask = os.umask(0) + os.umask(umask) # Restore the original umask. + for entry in os.scandir(self.testdir): + if entry.name.startswith('leadpath_'): + continue + with self.subTest(entry.name), tempfile.TemporaryDirectory() as tmpdir: + archive.extract(entry.path, tmpdir) + # An executable file in the archive has executable permissions. + filepath = os.path.join(tmpdir, 'executable') + self.assertEqual(os.stat(filepath).st_mode & mask, 0o775) + # A file is readable even if permission data is missing. + filepath = os.path.join(tmpdir, 'no_permissions') + self.assertEqual(os.stat(filepath).st_mode & mask, 0o664 & ~umask)