summaryrefslogtreecommitdiffstats
path: root/Lib/test/test_shutil.py
diff options
context:
space:
mode:
authorAntoine Pitrou <solipsis@pitrou.net>2012-05-12 17:02:01 (GMT)
committerAntoine Pitrou <solipsis@pitrou.net>2012-05-12 17:02:01 (GMT)
commit424246fbf3953ccdb3b34961db007a453873a3ea (patch)
tree64fc5c2f67d12ae1ca24201d0569748f7df9352b /Lib/test/test_shutil.py
parent4d688e3275d5a10e2321571392cdc31945bb8a89 (diff)
downloadcpython-424246fbf3953ccdb3b34961db007a453873a3ea.zip
cpython-424246fbf3953ccdb3b34961db007a453873a3ea.tar.gz
cpython-424246fbf3953ccdb3b34961db007a453873a3ea.tar.bz2
Issue #14082: shutil.copy2() now copies extended attributes, if possible.
Patch by Hynek Schlawack.
Diffstat (limited to 'Lib/test/test_shutil.py')
-rw-r--r--Lib/test/test_shutil.py74
1 files changed, 74 insertions, 0 deletions
diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py
index 4700a49..59d83e8 100644
--- a/Lib/test/test_shutil.py
+++ b/Lib/test/test_shutil.py
@@ -311,6 +311,67 @@ class TestShutil(unittest.TestCase):
finally:
os.chflags = old_chflags
+ @support.skip_unless_xattr
+ def test_copyxattr(self):
+ tmp_dir = self.mkdtemp()
+ src = os.path.join(tmp_dir, 'foo')
+ write_file(src, 'foo')
+ dst = os.path.join(tmp_dir, 'bar')
+ write_file(dst, 'bar')
+
+ # no xattr == no problem
+ shutil._copyxattr(src, dst)
+ # common case
+ os.setxattr(src, 'user.foo', b'42')
+ os.setxattr(src, 'user.bar', b'43')
+ shutil._copyxattr(src, dst)
+ self.assertEqual(os.listxattr(src), os.listxattr(dst))
+ self.assertEqual(
+ os.getxattr(src, 'user.foo'),
+ os.getxattr(dst, 'user.foo'))
+ # check errors don't affect other attrs
+ os.remove(dst)
+ write_file(dst, 'bar')
+ os_error = OSError(errno.EPERM, 'EPERM')
+
+ def _raise_on_user_foo(fname, attr, val):
+ if attr == 'user.foo':
+ raise os_error
+ else:
+ orig_setxattr(fname, attr, val)
+ try:
+ orig_setxattr = os.setxattr
+ os.setxattr = _raise_on_user_foo
+ shutil._copyxattr(src, dst)
+ self.assertEqual(['user.bar'], os.listxattr(dst))
+ finally:
+ os.setxattr = orig_setxattr
+
+ @support.skip_unless_symlink
+ @support.skip_unless_xattr
+ @unittest.skipUnless(hasattr(os, 'geteuid') and os.geteuid() == 0,
+ 'root privileges required')
+ def test_copyxattr_symlinks(self):
+ # On Linux, it's only possible to access non-user xattr for symlinks;
+ # which in turn require root privileges. This test should be expanded
+ # as soon as other platforms gain support for extended attributes.
+ tmp_dir = self.mkdtemp()
+ src = os.path.join(tmp_dir, 'foo')
+ src_link = os.path.join(tmp_dir, 'baz')
+ write_file(src, 'foo')
+ os.symlink(src, src_link)
+ os.setxattr(src, 'trusted.foo', b'42')
+ os.lsetxattr(src_link, 'trusted.foo', b'43')
+ dst = os.path.join(tmp_dir, 'bar')
+ dst_link = os.path.join(tmp_dir, 'qux')
+ write_file(dst, 'bar')
+ os.symlink(dst, dst_link)
+ shutil._copyxattr(src_link, dst_link, symlinks=True)
+ self.assertEqual(os.lgetxattr(dst_link, 'trusted.foo'), b'43')
+ self.assertRaises(OSError, os.getxattr, dst, 'trusted.foo')
+ shutil._copyxattr(src_link, dst, symlinks=True)
+ self.assertEqual(os.getxattr(dst, 'trusted.foo'), b'43')
+
@support.skip_unless_symlink
def test_copy_symlinks(self):
tmp_dir = self.mkdtemp()
@@ -369,6 +430,19 @@ class TestShutil(unittest.TestCase):
if hasattr(os, 'lchflags') and hasattr(src_link_stat, 'st_flags'):
self.assertEqual(src_link_stat.st_flags, dst_stat.st_flags)
+ @support.skip_unless_xattr
+ def test_copy2_xattr(self):
+ tmp_dir = self.mkdtemp()
+ src = os.path.join(tmp_dir, 'foo')
+ dst = os.path.join(tmp_dir, 'bar')
+ write_file(src, 'foo')
+ os.setxattr(src, 'user.foo', b'42')
+ shutil.copy2(src, dst)
+ self.assertEqual(
+ os.getxattr(src, 'user.foo'),
+ os.getxattr(dst, 'user.foo'))
+ os.remove(dst)
+
@support.skip_unless_symlink
def test_copyfile_symlinks(self):
tmp_dir = self.mkdtemp()