def _unlinkold(self): if self._is_dir: # Marker, or object, directory. # # Delete from the filesystem only if it contains no objects. # If it does contain objects, then just remove the object # metadata tag which will make this directory a # fake-filesystem-only directory and will be deleted when the # container or parent directory is deleted. # # FIXME: Ideally we should use an atomic metadata update operation metadata = read_metadata(self._data_file) if dir_is_object(metadata): metadata[X_OBJECT_TYPE] = DIR_NON_OBJECT write_metadata(self._data_file, metadata) rmobjdir(self._data_file) else: # Delete file object do_unlink(self._data_file) # Garbage collection of non-object directories. Now that we # deleted the file, determine if the current directory and any # parent directory may be deleted. dirname = os.path.dirname(self._data_file) while dirname and dirname != self._container_path: # Try to remove any directories that are not objects. if not rmobjdir(dirname): # If a directory with objects has been found, we can stop # garabe collection break else: dirname = os.path.dirname(dirname)
def test_rmobjdir_rmdir_error(self): seen = [0] _orig_rm = utils.do_rmdir def _mock_rm(path): print "_mock_rm-rmdir_enoent(%s)" % path if path == self.rootdir and not seen[0]: seen[0] = 1 raise OSError(errno.ENOTEMPTY, os.strerror(errno.ENOTEMPTY)) else: raise OSError(errno.EACCES, os.strerror(errno.EACCES)) # Remove the files for f in self.files: os.unlink(os.path.join(self.rootdir, f)) utils.do_rmdir = _mock_rm try: try: utils.rmobjdir(self.rootdir) except OSError: pass else: self.fail("Expected OSError") finally: utils.do_rmdir = _orig_rm
def test_rmobjdir_error_final_rmdir(self): seen = [0] _orig_rm = utils.do_rmdir def _mock_rm(path): print "_mock_rm-files_left_in_top_dir(%s)" % path if path == self.rootdir: if not seen[0]: seen[0] = 1 raise OSError(errno.ENOTEMPTY, os.strerror(errno.ENOTEMPTY)) else: raise OSError(errno.EACCES, os.strerror(errno.EACCES)) else: shutil.rmtree(path) raise OSError(errno.ENOENT, os.strerror(errno.ENOENT)) # Remove the files, leaving the ones at the root for f in self.files: os.unlink(os.path.join(self.rootdir, f)) utils.do_rmdir = _mock_rm try: try: utils.rmobjdir(self.rootdir) except OSError: pass else: self.fail("Expected OSError") finally: utils.do_rmdir = _orig_rm
def test_rmobjdir_removing_files(self): self.assertFalse(utils.rmobjdir(self.rootdir)) # Remove the files for f in self.files: os.unlink(os.path.join(self.rootdir, f)) self.assertTrue(utils.rmobjdir(self.rootdir))
def delete_db(self, timestamp): """ Delete the container (directory) if empty. :param timestamp: delete timestamp """ # Let's check and see if it has directories that # where created by the code, but not by the # caller as objects rmobjdir(self.datadir)
def test_rmobjdir_removing_dirs(self): self.assertFalse(utils.rmobjdir(self.rootdir)) # Remove the files for f in self.files: os.unlink(os.path.join(self.rootdir, f)) self._set_dir_object(self.dirs[0]) self.assertFalse(utils.rmobjdir(self.rootdir)) self._clear_dir_object(self.dirs[0]) self.assertTrue(utils.rmobjdir(self.rootdir))
def unlinkold(self, timestamp): """ Remove any older versions of the object file. Any file that has an older timestamp than timestamp will be deleted. :param timestamp: timestamp to compare with each file """ if not self.metadata or self.metadata[X_TIMESTAMP] >= timestamp: return assert self.data_file, \ "Have metadata, %r, but no data_file" % self.metadata if self._is_dir: # Marker, or object, directory. # # Delete from the filesystem only if it contains # no objects. If it does contain objects, then just # remove the object metadata tag which will make this directory a # fake-filesystem-only directory and will be deleted # when the container or parent directory is deleted. metadata = read_metadata(self.data_file) if dir_is_object(metadata): metadata[X_OBJECT_TYPE] = DIR_NON_OBJECT write_metadata(self.data_file, metadata) rmobjdir(self.data_file) else: # Delete file object do_unlink(self.data_file) # Garbage collection of non-object directories. # Now that we deleted the file, determine # if the current directory and any parent # directory may be deleted. dirname = os.path.dirname(self.data_file) while dirname and dirname != self._container_path: # Try to remove any directories that are not # objects. if not rmobjdir(dirname): # If a directory with objects has been # found, we can stop garabe collection break else: dirname = os.path.dirname(dirname) self.metadata = {} self.data_file = None
def test_rmobjdir_metadata_errors(self): def _mock_rm(path): print "_mock_rm-metadata_errors(%s)" % path if path.endswith("dir3"): raise OSError(13, "foo") return {} _orig_rm = utils.read_metadata utils.read_metadata = _mock_rm try: try: utils.rmobjdir(self.rootdir) except OSError: pass else: self.fail("Expected OSError") finally: utils.read_metadata = _orig_rm
def test_rmobjdir_metadata_enoent(self): def _mock_rm(path): print "_mock_rm-metadata_enoent(%s)" % path shutil.rmtree(path) raise OSError(errno.ENOENT, os.strerror(errno.ENOENT)) # Remove the files for f in self.files: os.unlink(os.path.join(self.rootdir, f)) _orig_rm = utils.read_metadata utils.read_metadata = _mock_rm try: try: self.assertTrue(utils.rmobjdir(self.rootdir)) except OSError: self.fail("Unexpected OSError") else: pass finally: utils.read_metadata = _orig_rm