gh-113086: Add tests for os.chmod() and os.lchmod() (GH-113087)

Also make test_copymode_symlink_to_symlink in test_shutil more strict.
This commit is contained in:
Serhiy Storchaka 2023-12-14 09:16:06 +02:00 committed by GitHub
parent fddc829236
commit b4f2c89118
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 118 additions and 1 deletions

View File

@ -935,6 +935,122 @@ class PosixTester(unittest.TestCase):
posix.utime(os_helper.TESTFN, (int(now), int(now)))
posix.utime(os_helper.TESTFN, (now, now))
def check_chmod(self, chmod_func, target, **kwargs):
mode = os.stat(target).st_mode
try:
new_mode = mode & ~(stat.S_IWOTH | stat.S_IWGRP | stat.S_IWUSR)
chmod_func(target, new_mode, **kwargs)
self.assertEqual(os.stat(target).st_mode, new_mode)
if stat.S_ISREG(mode):
try:
with open(target, 'wb+'):
pass
except PermissionError:
pass
new_mode = mode | (stat.S_IWOTH | stat.S_IWGRP | stat.S_IWUSR)
chmod_func(target, new_mode, **kwargs)
self.assertEqual(os.stat(target).st_mode, new_mode)
if stat.S_ISREG(mode):
with open(target, 'wb+'):
pass
finally:
posix.chmod(target, mode)
def test_chmod_file(self):
self.check_chmod(posix.chmod, os_helper.TESTFN)
def tempdir(self):
target = os_helper.TESTFN + 'd'
posix.mkdir(target)
self.addCleanup(posix.rmdir, target)
return target
def test_chmod_dir(self):
target = self.tempdir()
self.check_chmod(posix.chmod, target)
@unittest.skipUnless(hasattr(posix, 'lchmod'), 'test needs os.lchmod()')
def test_lchmod_file(self):
self.check_chmod(posix.lchmod, os_helper.TESTFN)
self.check_chmod(posix.chmod, os_helper.TESTFN, follow_symlinks=False)
@unittest.skipUnless(hasattr(posix, 'lchmod'), 'test needs os.lchmod()')
def test_lchmod_dir(self):
target = self.tempdir()
self.check_chmod(posix.lchmod, target)
self.check_chmod(posix.chmod, target, follow_symlinks=False)
def check_chmod_link(self, chmod_func, target, link, **kwargs):
target_mode = os.stat(target).st_mode
link_mode = os.lstat(link).st_mode
try:
new_mode = target_mode & ~(stat.S_IWOTH | stat.S_IWGRP | stat.S_IWUSR)
chmod_func(link, new_mode, **kwargs)
self.assertEqual(os.stat(target).st_mode, new_mode)
self.assertEqual(os.lstat(link).st_mode, link_mode)
new_mode = target_mode | (stat.S_IWOTH | stat.S_IWGRP | stat.S_IWUSR)
chmod_func(link, new_mode, **kwargs)
self.assertEqual(os.stat(target).st_mode, new_mode)
self.assertEqual(os.lstat(link).st_mode, link_mode)
finally:
posix.chmod(target, target_mode)
def check_lchmod_link(self, chmod_func, target, link, **kwargs):
target_mode = os.stat(target).st_mode
link_mode = os.lstat(link).st_mode
new_mode = link_mode & ~(stat.S_IWOTH | stat.S_IWGRP | stat.S_IWUSR)
chmod_func(link, new_mode, **kwargs)
self.assertEqual(os.stat(target).st_mode, target_mode)
self.assertEqual(os.lstat(link).st_mode, new_mode)
new_mode = link_mode | (stat.S_IWOTH | stat.S_IWGRP | stat.S_IWUSR)
chmod_func(link, new_mode, **kwargs)
self.assertEqual(os.stat(target).st_mode, target_mode)
self.assertEqual(os.lstat(link).st_mode, new_mode)
@os_helper.skip_unless_symlink
def test_chmod_file_symlink(self):
target = os_helper.TESTFN
link = os_helper.TESTFN + '-link'
os.symlink(target, link)
self.addCleanup(posix.unlink, link)
if os.name == 'nt':
self.check_lchmod_link(posix.chmod, target, link)
else:
self.check_chmod_link(posix.chmod, target, link)
self.check_chmod_link(posix.chmod, target, link, follow_symlinks=True)
@os_helper.skip_unless_symlink
def test_chmod_dir_symlink(self):
target = self.tempdir()
link = os_helper.TESTFN + '-link'
os.symlink(target, link, target_is_directory=True)
self.addCleanup(posix.unlink, link)
if os.name == 'nt':
self.check_lchmod_link(posix.chmod, target, link)
else:
self.check_chmod_link(posix.chmod, target, link)
self.check_chmod_link(posix.chmod, target, link, follow_symlinks=True)
@unittest.skipUnless(hasattr(posix, 'lchmod'), 'test needs os.lchmod()')
@os_helper.skip_unless_symlink
def test_lchmod_file_symlink(self):
target = os_helper.TESTFN
link = os_helper.TESTFN + '-link'
os.symlink(target, link)
self.addCleanup(posix.unlink, link)
self.check_lchmod_link(posix.chmod, target, link, follow_symlinks=False)
self.check_lchmod_link(posix.lchmod, target, link)
@unittest.skipUnless(hasattr(posix, 'lchmod'), 'test needs os.lchmod()')
@os_helper.skip_unless_symlink
def test_lchmod_dir_symlink(self):
target = self.tempdir()
link = os_helper.TESTFN + '-link'
os.symlink(target, link)
self.addCleanup(posix.unlink, link)
self.check_lchmod_link(posix.chmod, target, link, follow_symlinks=False)
self.check_lchmod_link(posix.lchmod, target, link)
def _test_chflags_regular_file(self, chflags_func, target_file, **kwargs):
st = os.stat(target_file)
self.assertTrue(hasattr(st, 'st_flags'))

View File

@ -1132,10 +1132,11 @@ class TestCopy(BaseTest, unittest.TestCase):
os.lchmod(src_link, stat.S_IRWXO|stat.S_IRWXG)
# link to link
os.lchmod(dst_link, stat.S_IRWXO)
old_mode = os.stat(dst).st_mode
shutil.copymode(src_link, dst_link, follow_symlinks=False)
self.assertEqual(os.lstat(src_link).st_mode,
os.lstat(dst_link).st_mode)
self.assertNotEqual(os.stat(src).st_mode, os.stat(dst).st_mode)
self.assertEqual(os.stat(dst).st_mode, old_mode)
# src link - use chmod
os.lchmod(dst_link, stat.S_IRWXO)
shutil.copymode(src_link, dst, follow_symlinks=False)