summaryrefslogtreecommitdiffstats
path: root/Lib/test/test_shutil.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/test/test_shutil.py')
-rw-r--r--Lib/test/test_shutil.py258
1 files changed, 147 insertions, 111 deletions
diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py
index e2310e2..b169803 100644
--- a/Lib/test/test_shutil.py
+++ b/Lib/test/test_shutil.py
@@ -21,7 +21,7 @@ import tarfile
import warnings
from test import support
-from test.support import TESTFN, check_warnings, captured_stdout
+from test.support import TESTFN, check_warnings, captured_stdout, requires_zlib
try:
import bz2
@@ -39,11 +39,6 @@ except ImportError:
UID_GID_SUPPORT = False
try:
- import zlib
-except ImportError:
- zlib = None
-
-try:
import zipfile
ZIP_SUPPORT = True
except ImportError:
@@ -64,6 +59,31 @@ def mock_rename(func):
os.rename = builtin_rename
return wrap
+def write_file(path, content, binary=False):
+ """Write *content* to a file located at *path*.
+
+ If *path* is a tuple instead of a string, os.path.join will be used to
+ make a path. If *binary* is true, the file will be opened in binary
+ mode.
+ """
+ if isinstance(path, tuple):
+ path = os.path.join(*path)
+ with open(path, 'wb' if binary else 'w') as fp:
+ fp.write(content)
+
+def read_file(path, binary=False):
+ """Return contents from a file located at *path*.
+
+ If *path* is a tuple instead of a string, os.path.join will be used to
+ make a path. If *binary* is true, the file will be opened in binary
+ mode.
+ """
+ if isinstance(path, tuple):
+ path = os.path.join(*path)
+ with open(path, 'rb' if binary else 'r') as fp:
+ return fp.read()
+
+
class TestShutil(unittest.TestCase):
def setUp(self):
@@ -76,19 +96,6 @@ class TestShutil(unittest.TestCase):
d = self.tempdirs.pop()
shutil.rmtree(d, os.name in ('nt', 'cygwin'))
- def write_file(self, path, content='xxx'):
- """Writes a file in the given path.
-
-
- path can be a string or a sequence.
- """
- if isinstance(path, (list, tuple)):
- path = os.path.join(*path)
- f = open(path, 'w')
- try:
- f.write(content)
- finally:
- f.close()
def mkdtemp(self):
"""Create a temporary directory that will be cleaned up.
@@ -112,8 +119,7 @@ class TestShutil(unittest.TestCase):
self.errorState = 0
os.mkdir(TESTFN)
self.childpath = os.path.join(TESTFN, 'a')
- f = open(self.childpath, 'w')
- f.close()
+ support.create_empty_file(self.childpath)
old_dir_mode = os.stat(TESTFN).st_mode
old_child_mode = os.stat(self.childpath).st_mode
# Make unwritable.
@@ -161,81 +167,46 @@ class TestShutil(unittest.TestCase):
def test_rmtree_dont_delete_file(self):
# When called on a file instead of a directory, don't delete it.
handle, path = tempfile.mkstemp()
- os.fdopen(handle).close()
+ os.close(handle)
self.assertRaises(OSError, shutil.rmtree, path)
os.remove(path)
- def _write_data(self, path, data):
- f = open(path, "w")
- f.write(data)
- f.close()
-
def test_copytree_simple(self):
-
- def read_data(path):
- f = open(path)
- data = f.read()
- f.close()
- return data
-
src_dir = tempfile.mkdtemp()
dst_dir = os.path.join(tempfile.mkdtemp(), 'destination')
- self._write_data(os.path.join(src_dir, 'test.txt'), '123')
+ self.addCleanup(shutil.rmtree, src_dir)
+ self.addCleanup(shutil.rmtree, os.path.dirname(dst_dir))
+ write_file((src_dir, 'test.txt'), '123')
os.mkdir(os.path.join(src_dir, 'test_dir'))
- self._write_data(os.path.join(src_dir, 'test_dir', 'test.txt'), '456')
-
- try:
- shutil.copytree(src_dir, dst_dir)
- self.assertTrue(os.path.isfile(os.path.join(dst_dir, 'test.txt')))
- self.assertTrue(os.path.isdir(os.path.join(dst_dir, 'test_dir')))
- self.assertTrue(os.path.isfile(os.path.join(dst_dir, 'test_dir',
- 'test.txt')))
- actual = read_data(os.path.join(dst_dir, 'test.txt'))
- self.assertEqual(actual, '123')
- actual = read_data(os.path.join(dst_dir, 'test_dir', 'test.txt'))
- self.assertEqual(actual, '456')
- finally:
- for path in (
- os.path.join(src_dir, 'test.txt'),
- os.path.join(dst_dir, 'test.txt'),
- os.path.join(src_dir, 'test_dir', 'test.txt'),
- os.path.join(dst_dir, 'test_dir', 'test.txt'),
- ):
- if os.path.exists(path):
- os.remove(path)
- for path in (src_dir,
- os.path.dirname(dst_dir)
- ):
- if os.path.exists(path):
- shutil.rmtree(path)
+ write_file((src_dir, 'test_dir', 'test.txt'), '456')
+
+ shutil.copytree(src_dir, dst_dir)
+ self.assertTrue(os.path.isfile(os.path.join(dst_dir, 'test.txt')))
+ self.assertTrue(os.path.isdir(os.path.join(dst_dir, 'test_dir')))
+ self.assertTrue(os.path.isfile(os.path.join(dst_dir, 'test_dir',
+ 'test.txt')))
+ actual = read_file((dst_dir, 'test.txt'))
+ self.assertEqual(actual, '123')
+ actual = read_file((dst_dir, 'test_dir', 'test.txt'))
+ self.assertEqual(actual, '456')
def test_copytree_with_exclude(self):
-
- def read_data(path):
- f = open(path)
- data = f.read()
- f.close()
- return data
-
# creating data
join = os.path.join
exists = os.path.exists
src_dir = tempfile.mkdtemp()
try:
dst_dir = join(tempfile.mkdtemp(), 'destination')
- self._write_data(join(src_dir, 'test.txt'), '123')
- self._write_data(join(src_dir, 'test.tmp'), '123')
+ write_file((src_dir, 'test.txt'), '123')
+ write_file((src_dir, 'test.tmp'), '123')
os.mkdir(join(src_dir, 'test_dir'))
- self._write_data(join(src_dir, 'test_dir', 'test.txt'), '456')
+ write_file((src_dir, 'test_dir', 'test.txt'), '456')
os.mkdir(join(src_dir, 'test_dir2'))
- self._write_data(join(src_dir, 'test_dir2', 'test.txt'), '456')
+ write_file((src_dir, 'test_dir2', 'test.txt'), '456')
os.mkdir(join(src_dir, 'test_dir2', 'subdir'))
os.mkdir(join(src_dir, 'test_dir2', 'subdir2'))
- self._write_data(join(src_dir, 'test_dir2', 'subdir', 'test.txt'),
- '456')
- self._write_data(join(src_dir, 'test_dir2', 'subdir2', 'test.py'),
- '456')
-
+ write_file((src_dir, 'test_dir2', 'subdir', 'test.txt'), '456')
+ write_file((src_dir, 'test_dir2', 'subdir2', 'test.py'), '456')
# testing glob-like patterns
try:
@@ -243,21 +214,19 @@ class TestShutil(unittest.TestCase):
shutil.copytree(src_dir, dst_dir, ignore=patterns)
# checking the result: some elements should not be copied
self.assertTrue(exists(join(dst_dir, 'test.txt')))
- self.assertTrue(not exists(join(dst_dir, 'test.tmp')))
- self.assertTrue(not exists(join(dst_dir, 'test_dir2')))
+ self.assertFalse(exists(join(dst_dir, 'test.tmp')))
+ self.assertFalse(exists(join(dst_dir, 'test_dir2')))
finally:
- if os.path.exists(dst_dir):
- shutil.rmtree(dst_dir)
+ shutil.rmtree(dst_dir)
try:
patterns = shutil.ignore_patterns('*.tmp', 'subdir*')
shutil.copytree(src_dir, dst_dir, ignore=patterns)
# checking the result: some elements should not be copied
- self.assertTrue(not exists(join(dst_dir, 'test.tmp')))
- self.assertTrue(not exists(join(dst_dir, 'test_dir2', 'subdir2')))
- self.assertTrue(not exists(join(dst_dir, 'test_dir2', 'subdir')))
+ self.assertFalse(exists(join(dst_dir, 'test.tmp')))
+ self.assertFalse(exists(join(dst_dir, 'test_dir2', 'subdir2')))
+ self.assertFalse(exists(join(dst_dir, 'test_dir2', 'subdir')))
finally:
- if os.path.exists(dst_dir):
- shutil.rmtree(dst_dir)
+ shutil.rmtree(dst_dir)
# testing callable-style
try:
@@ -276,13 +245,12 @@ class TestShutil(unittest.TestCase):
shutil.copytree(src_dir, dst_dir, ignore=_filter)
# checking the result: some elements should not be copied
- self.assertTrue(not exists(join(dst_dir, 'test_dir2', 'subdir2',
- 'test.py')))
- self.assertTrue(not exists(join(dst_dir, 'test_dir2', 'subdir')))
+ self.assertFalse(exists(join(dst_dir, 'test_dir2', 'subdir2',
+ 'test.py')))
+ self.assertFalse(exists(join(dst_dir, 'test_dir2', 'subdir')))
finally:
- if os.path.exists(dst_dir):
- shutil.rmtree(dst_dir)
+ shutil.rmtree(dst_dir)
finally:
shutil.rmtree(src_dir)
shutil.rmtree(os.path.dirname(dst_dir))
@@ -377,9 +345,9 @@ class TestShutil(unittest.TestCase):
src_dir = self.mkdtemp()
dst_dir = os.path.join(self.mkdtemp(), 'destination')
- self._write_data(os.path.join(src_dir, 'test.txt'), '123')
+ write_file((src_dir, 'test.txt'), '123')
os.mkdir(os.path.join(src_dir, 'test_dir'))
- self._write_data(os.path.join(src_dir, 'test_dir', 'test.txt'), '456')
+ write_file((src_dir, 'test_dir', 'test.txt'), '456')
copied = []
def _copy(src, dst):
@@ -396,7 +364,7 @@ class TestShutil(unittest.TestCase):
dst_dir = os.path.join(self.mkdtemp(), 'destination')
os.symlink('IDONTEXIST', os.path.join(src_dir, 'test.txt'))
os.mkdir(os.path.join(src_dir, 'test_dir'))
- self._write_data(os.path.join(src_dir, 'test_dir', 'test.txt'), '456')
+ write_file((src_dir, 'test_dir', 'test.txt'), '456')
self.assertRaises(Error, shutil.copytree, src_dir, dst_dir)
# a dangling symlink is ignored with the proper flag
@@ -412,7 +380,7 @@ class TestShutil(unittest.TestCase):
def _copy_file(self, method):
fname = 'test.txt'
tmpdir = self.mkdtemp()
- self.write_file([tmpdir, fname])
+ write_file((tmpdir, fname), 'xxx')
file1 = os.path.join(tmpdir, fname)
tmpdir2 = self.mkdtemp()
method(file1, tmpdir2)
@@ -444,14 +412,14 @@ class TestShutil(unittest.TestCase):
self.assertEqual(getattr(file1_stat, 'st_flags'),
getattr(file2_stat, 'st_flags'))
- @unittest.skipUnless(zlib, "requires zlib")
+ @requires_zlib
def test_make_tarball(self):
# creating something to tar
tmpdir = self.mkdtemp()
- self.write_file([tmpdir, 'file1'], 'xxx')
- self.write_file([tmpdir, 'file2'], 'xxx')
+ write_file((tmpdir, 'file1'), 'xxx')
+ write_file((tmpdir, 'file2'), 'xxx')
os.mkdir(os.path.join(tmpdir, 'sub'))
- self.write_file([tmpdir, 'sub', 'file3'], 'xxx')
+ write_file((tmpdir, 'sub', 'file3'), 'xxx')
tmpdir2 = self.mkdtemp()
# force shutil to create the directory
@@ -498,16 +466,16 @@ class TestShutil(unittest.TestCase):
tmpdir = self.mkdtemp()
dist = os.path.join(tmpdir, 'dist')
os.mkdir(dist)
- self.write_file([dist, 'file1'], 'xxx')
- self.write_file([dist, 'file2'], 'xxx')
+ write_file((dist, 'file1'), 'xxx')
+ write_file((dist, 'file2'), 'xxx')
os.mkdir(os.path.join(dist, 'sub'))
- self.write_file([dist, 'sub', 'file3'], 'xxx')
+ write_file((dist, 'sub', 'file3'), 'xxx')
os.mkdir(os.path.join(dist, 'sub2'))
tmpdir2 = self.mkdtemp()
base_name = os.path.join(tmpdir2, 'archive')
return tmpdir, tmpdir2, base_name
- @unittest.skipUnless(zlib, "Requires zlib")
+ @requires_zlib
@unittest.skipUnless(find_executable('tar') and find_executable('gzip'),
'Need the tar command to run')
def test_tarfile_vs_tar(self):
@@ -562,13 +530,13 @@ class TestShutil(unittest.TestCase):
tarball = base_name + '.tar'
self.assertTrue(os.path.exists(tarball))
- @unittest.skipUnless(zlib, "Requires zlib")
+ @requires_zlib
@unittest.skipUnless(ZIP_SUPPORT, 'Need zip support to run')
def test_make_zipfile(self):
# creating something to tar
tmpdir = self.mkdtemp()
- self.write_file([tmpdir, 'file1'], 'xxx')
- self.write_file([tmpdir, 'file2'], 'xxx')
+ write_file((tmpdir, 'file1'), 'xxx')
+ write_file((tmpdir, 'file2'), 'xxx')
tmpdir2 = self.mkdtemp()
# force shutil to create the directory
@@ -586,7 +554,7 @@ class TestShutil(unittest.TestCase):
base_name = os.path.join(tmpdir, 'archive')
self.assertRaises(ValueError, make_archive, base_name, 'xxx')
- @unittest.skipUnless(zlib, "Requires zlib")
+ @requires_zlib
def test_make_archive_owner_group(self):
# testing make_archive with owner and group, with various combinations
# this works even if there's not gid/uid support
@@ -614,7 +582,7 @@ class TestShutil(unittest.TestCase):
self.assertTrue(os.path.exists(res))
- @unittest.skipUnless(zlib, "Requires zlib")
+ @requires_zlib
@unittest.skipUnless(UID_GID_SUPPORT, "Requires grp and pwd support")
def test_tarfile_root_owner(self):
tmpdir, tmpdir2, base_name = self._create_files()
@@ -683,7 +651,7 @@ class TestShutil(unittest.TestCase):
diff.append(file_)
return diff
- @unittest.skipUnless(zlib, "Requires zlib")
+ @requires_zlib
def test_unpack_archive(self):
formats = ['tar', 'gztar', 'zip']
if BZ2_SUPPORTED:
@@ -734,6 +702,75 @@ class TestShutil(unittest.TestCase):
unregister_unpack_format('Boo2')
self.assertEqual(get_unpack_formats(), formats)
+ @unittest.skipUnless(hasattr(shutil, 'disk_usage'),
+ "disk_usage not available on this platform")
+ def test_disk_usage(self):
+ usage = shutil.disk_usage(os.getcwd())
+ self.assertGreater(usage.total, 0)
+ self.assertGreater(usage.used, 0)
+ self.assertGreaterEqual(usage.free, 0)
+ self.assertGreaterEqual(usage.total, usage.used)
+ self.assertGreater(usage.total, usage.free)
+
+ @unittest.skipUnless(UID_GID_SUPPORT, "Requires grp and pwd support")
+ @unittest.skipUnless(hasattr(os, 'chown'), 'requires os.chown')
+ def test_chown(self):
+
+ # cleaned-up automatically by TestShutil.tearDown method
+ dirname = self.mkdtemp()
+ filename = tempfile.mktemp(dir=dirname)
+ write_file(filename, 'testing chown function')
+
+ with self.assertRaises(ValueError):
+ shutil.chown(filename)
+
+ with self.assertRaises(LookupError):
+ shutil.chown(filename, user='non-exising username')
+
+ with self.assertRaises(LookupError):
+ shutil.chown(filename, group='non-exising groupname')
+
+ with self.assertRaises(TypeError):
+ shutil.chown(filename, b'spam')
+
+ with self.assertRaises(TypeError):
+ shutil.chown(filename, 3.14)
+
+ uid = os.getuid()
+ gid = os.getgid()
+
+ def check_chown(path, uid=None, gid=None):
+ s = os.stat(filename)
+ if uid is not None:
+ self.assertEqual(uid, s.st_uid)
+ if gid is not None:
+ self.assertEqual(gid, s.st_gid)
+
+ shutil.chown(filename, uid, gid)
+ check_chown(filename, uid, gid)
+ shutil.chown(filename, uid)
+ check_chown(filename, uid)
+ shutil.chown(filename, user=uid)
+ check_chown(filename, uid)
+ shutil.chown(filename, group=gid)
+ check_chown(filename, gid=gid)
+
+ shutil.chown(dirname, uid, gid)
+ check_chown(dirname, uid, gid)
+ shutil.chown(dirname, uid)
+ check_chown(dirname, uid)
+ shutil.chown(dirname, user=uid)
+ check_chown(dirname, uid)
+ shutil.chown(dirname, group=gid)
+ check_chown(dirname, gid=gid)
+
+ user = pwd.getpwuid(uid)[0]
+ group = grp.getgrgid(gid)[0]
+ shutil.chown(filename, user, group)
+ check_chown(filename, uid, gid)
+ shutil.chown(dirname, user, group)
+ check_chown(dirname, uid, gid)
+
class TestMove(unittest.TestCase):
@@ -965,8 +1002,7 @@ class TestCopyFile(unittest.TestCase):
shutil.move(self.src_dir, dst_dir)
self.assertTrue(os.path.isdir(dst_dir))
finally:
- if os.path.exists(dst_dir):
- os.rmdir(dst_dir)
+ os.rmdir(dst_dir)