Commit 09352b5e 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 #5528 passed with stage
...@@ -489,21 +489,35 @@ shared = true ...@@ -489,21 +489,35 @@ shared = true
test_node.purgeOldTestSuite(test_suite_data) test_node.purgeOldTestSuite(test_suite_data)
self.assertEquals(['foo'], os.listdir(self.working_directory)) 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 """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_node = self.getTestNode()
test_suite_data = self.getTestSuiteData(add_third_repository=True) test_suite_data = self.getTestSuiteData(add_third_repository=True)
os.mkdir(os.path.join(self.working_directory, 'bar')) 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 = open(os.path.join(self.working_directory, 'bar', 'non-writable-file'), 'w')
non_writable_file.close() 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', 'non-writable-file'), 0o400) # -r--------
os.chmod(os.path.join(self.working_directory, 'bar'), 0o000) os.chmod(os.path.join(self.working_directory, 'bar'), 0o500) # dr-x------
test_node.purgeOldTestSuite(test_suite_data) # should not fail test_node.purgeOldTestSuite(test_suite_data) # should not fail
self.assertEqual([], os.listdir(self.working_directory)) 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'): def test_09_runTestSuite(self, my_test_type='UnitTest'):
""" """
......
...@@ -7,24 +7,31 @@ def rmtree(path): ...@@ -7,24 +7,31 @@ def rmtree(path):
Like shutil.rmtree, but supporting the case that some files or folder Like shutil.rmtree, but supporting the case that some files or folder
might have been marked read only. """ might have been marked read only. """
def chmod_retry(func, path, _): def chmod_retry(func, failed_path, _):
"""Make sure the file is writeable / the directory is executable. """Make sure the file is writeable / the directory is executable.
""" """
if not os.path.exists(path): if not os.path.exists(failed_path):
# because we are calling again rmtree on listdir errors, this path might # because we are calling again rmtree on listdir errors, this path might
# have been already deleted by the recursive call to rmtree. # have been already deleted by the recursive call to rmtree.
return return
os.chmod(path, 0o777) os.chmod(failed_path, 0o777)
if func is os.listdir: if func is os.listdir:
# corner case to handle errors in listing directories. # corner case to handle errors in listing directories.
# https://bugs.python.org/issue8523 # https://bugs.python.org/issue8523
# This might raises MaxRecursionError when the directory cannot be listed # This might raises MaxRecursionError when the directory cannot be listed
# for other reasons than "user does not have read permssion" # for other reasons than "user does not have read permission"
return shutil.rmtree(path, onerror=chmod_retry) return shutil.rmtree(failed_path, onerror=chmod_retry)
func(path) try:
shutil.rmtree(path, onerror=chmod_retry) func(failed_path)
except OSError:
# if parent directory is not writable, we still cannot delete the file.
if failed_path != path: # we don't want to change the parent of the folder we are deleting
parent_folder = os.path.normpath(os.path.join(failed_path, '..'))
os.chmod(parent_folder, 0o777)
func(failed_path)
shutil.rmtree(path, onerror=chmod_retry)
def createFolder(folder, clean=False): def createFolder(folder, clean=False):
if os.path.exists(folder): 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