Commit 9f8fd853 authored by Jérome Perrin's avatar Jérome Perrin

testnode: properly support deletion of chmod'ed files

The implementation from 0341ea0d did not
cover the case where directory was readble but not writeable.
parent 8c33379a
Pipeline #5530 passed with stage
......@@ -489,21 +489,35 @@ shared = true
test_node.purgeOldTestSuite(test_suite_data)
self.assertEquals(['foo'], os.listdir(self.working_directory))
def test_purgeOldTestSuiteChmod(self):
def test_purgeOldTestSuiteChmodNonWriteable(self):
"""Old test suites can be deleted even when some files/directories have
been chmod'd to make read only. """
been chmod'd to make non-writeable """
test_node = self.getTestNode()
test_suite_data = self.getTestSuiteData(add_third_repository=True)
os.mkdir(os.path.join(self.working_directory, 'bar'))
non_writable_file = open(os.path.join(self.working_directory, 'bar', 'non-writable-file'), 'w')
non_writable_file.close()
# make this file and directory non writeable
os.chmod(os.path.join(self.working_directory, 'bar', 'non-writable-file'), 0o000)
os.chmod(os.path.join(self.working_directory, 'bar'), 0o000)
os.chmod(os.path.join(self.working_directory, 'bar', 'non-writable-file'), 0o400) # -r--------
os.chmod(os.path.join(self.working_directory, 'bar'), 0o500) # dr-x------
test_node.purgeOldTestSuite(test_suite_data) # should not fail
self.assertEqual([], os.listdir(self.working_directory))
def test_purgeOldTestSuiteChmodNonWriteableNonReadable(self):
"""Old test suites can be deleted even when some files/directories have
been chmod'd to make them non readable and non writeable. """
test_node = self.getTestNode()
test_suite_data = self.getTestSuiteData(add_third_repository=True)
os.mkdir(os.path.join(self.working_directory, 'bar'))
non_writable_file = open(os.path.join(self.working_directory, 'bar', 'non-writable-file'), 'w')
non_writable_file.close()
os.chmod(os.path.join(self.working_directory, 'bar', 'non-writable-file'), 0o000) # ----------
os.chmod(os.path.join(self.working_directory, 'bar'), 0o000) # d---------
test_node.purgeOldTestSuite(test_suite_data) # should not fail
self.assertEqual([], os.listdir(self.working_directory))
def test_09_runTestSuite(self, my_test_type='UnitTest'):
"""
......
import os
import stat
import shutil
import errno
def rmtree(path):
"""Delete a path recursively.
Like shutil.rmtree, but supporting the case that some files or folder
might have been marked read only. """
def chmod_retry(func, path, _):
"""Make sure the file is writeable / the directory is executable.
def chmod_retry(func, failed_path, exc_info):
"""Make sure the directories are executable and writable.
"""
if not os.path.exists(path):
e = exc_info[1]
if isinstance(e, OSError):
if e.errno == errno.ENOENT:
# because we are calling again rmtree on listdir errors, this path might
# have been already deleted by the recursive call to rmtree.
return
os.chmod(path, 0o777)
if e.errno == errno.EACCES:
if func is os.listdir:
os.chmod(failed_path, 0o700)
# corner case to handle errors in listing directories.
# https://bugs.python.org/issue8523
# This might raises MaxRecursionError when the directory cannot be listed
# for other reasons than "user does not have read permssion"
return shutil.rmtree(path, onerror=chmod_retry)
func(path)
shutil.rmtree(path, onerror=chmod_retry)
return shutil.rmtree(failed_path, onerror=chmod_retry)
# If parent directory is not writable, we still cannot delete the file.
# But make sure not to change the parent of the folder we are deleting.
if failed_path != path:
os.chmod(os.path.dirname(failed_path), 0o700)
return func(failed_path)
raise
shutil.rmtree(path, onerror=chmod_retry)
def createFolder(folder, clean=False):
if os.path.exists(folder):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment