From 0db8e8d925245b4f9c2564554ed3a318ce2336c0 Mon Sep 17 00:00:00 2001 From: Johannes Schauer Marin Rodrigues Date: Sun, 19 Jan 2025 23:52:09 +0100 Subject: [PATCH] tests/test_bmap_helpers.py: avoid build failure from disorderfs When running under disorderfs --shuffle-dirents=yes, the following Python code fails: with TemporaryDirectory(prefix="testdir_", dir=".") as directory: fobj = tempfile.NamedTemporaryFile( "r", delete=False, dir=directory ) Traceback (most recent call last): File "/tmp/disorder/test.py", line 4, in with TemporaryDirectory(prefix="testdir_", dir=".") as directory: File "/usr/lib/python3.11/tempfile.py", line 1052, in __exit__ self.cleanup() File "/usr/lib/python3.11/tempfile.py", line 1056, in cleanup self._rmtree(self.name, ignore_errors=self._ignore_cleanup_errors) File "/usr/lib/python3.11/tempfile.py", line 1038, in _rmtree _rmtree(name, onerror=onerror) File "/usr/lib/python3.11/shutil.py", line 738, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/usr/lib/python3.11/shutil.py", line 736, in rmtree os.rmdir(path, dir_fd=dir_fd) OSError: [Errno 39] Directory not empty: './testdir_6jhyg1o6' From investigating this, the reason that the test fails when using `disorderfs` is that, by default, FUSE overlay filesystems (of which `disorderfs` is an instance) don't immediately delete open files completely from the directory they are in; instead they're renamed to a temporary dotfile name, as documented here: http://libfuse.github.io/doxygen/structfuse__config.html#af32ff56fa1131da899756cc352718101 That causes the test to fail, because Python's `TemporaryDirectory` context-handler quite reasonably thinks that it has removed all the files in the directory, and therefore attempts a delete-only-if-empty operation. This currently fails under `disorderfs`, because the `fobj` file is open for reading, and therefore isn't entirely deleted, but only renamed. Closing the file is a simple fix for this. Note also: the `disorderfs` command-line can accept an `-o hard_remove` option to enable FUSE `hard_remove` option, causing deletes to apply directly to the underlying filesystem. I've filed a request/suggestion at https://bugs.debian.org/1093768 to enable it by default in `disorderfs` -- but doing so apparently causes other, potentially more disruptive, side-effects, so there's no guarantee that that behaviour will become the default. Thanks: James Addison --- tests/test_bmap_helpers.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/test_bmap_helpers.py b/tests/test_bmap_helpers.py index f224731..2cefad6 100644 --- a/tests/test_bmap_helpers.py +++ b/tests/test_bmap_helpers.py @@ -64,13 +64,13 @@ def test_get_file_system_type_symlink(self): """Check a file system type is returned when used with a symlink""" with TemporaryDirectory(prefix="testdir_", dir=".") as directory: - fobj = tempfile.NamedTemporaryFile( + with tempfile.NamedTemporaryFile( "r", prefix="testfile_", delete=False, dir=directory, suffix=".img" - ) - lnk = os.path.join(directory, "test_symlink") - os.symlink(fobj.name, lnk) - fstype = BmapHelpers.get_file_system_type(lnk) - self.assertTrue(fstype) + ) as fobj: + lnk = os.path.join(directory, "test_symlink") + os.symlink(fobj.name, lnk) + fstype = BmapHelpers.get_file_system_type(lnk) + self.assertTrue(fstype) def test_is_zfs_configuration_compatible_enabled(self): """Check compatibility check is true when zfs param is set correctly"""