diff --git a/attic/fuse.py b/attic/fuse.py index 2d477ce6c..5c6017f64 100644 --- a/attic/fuse.py +++ b/attic/fuse.py @@ -6,6 +6,8 @@ import stat import time from attic.helpers import daemonize +# Does this version of llfuse support ns precision? +have_fuse_mtime_ns = hasattr(llfuse.EntryAttributes, 'st_mtime_ns') class AtticOperations(llfuse.Operations): @@ -95,9 +97,14 @@ class AtticOperations(llfuse.Operations): entry.st_size = size entry.st_blksize = 512 entry.st_blocks = 1 - entry.st_atime = item[b'mtime'] / 1e9 - entry.st_mtime = item[b'mtime'] / 1e9 - entry.st_ctime = item[b'mtime'] / 1e9 + if have_fuse_mtime_ns: + entry.st_atime_ns = item[b'mtime'] + entry.st_mtime_ns = item[b'mtime'] + entry.st_ctime_ns = item[b'mtime'] + else: + entry.st_atime = item[b'mtime'] / 1e9 + entry.st_mtime = item[b'mtime'] / 1e9 + entry.st_ctime = item[b'mtime'] / 1e9 return entry def listxattr(self, inode): diff --git a/attic/testsuite/__init__.py b/attic/testsuite/__init__.py index 76a6b08dd..74e0c9c8a 100644 --- a/attic/testsuite/__init__.py +++ b/attic/testsuite/__init__.py @@ -8,6 +8,14 @@ import unittest from attic.helpers import st_mtime_ns from attic.xattr import get_all +try: + import llfuse + # Does this version of llfuse support ns precision? + have_fuse_mtime_ns = hasattr(llfuse.EntryAttributes, 'st_mtime_ns') +except ImportError: + have_fuse_mtime_ns = False + + # The mtime get/set precison varies on different OS and Python versions if 'HAVE_FUTIMENS' in getattr(posix, '_have_functions', []): st_mtime_ns_round = 0 @@ -34,11 +42,11 @@ class AtticTestCase(unittest.TestCase): except EnvironmentError: return {} - def assert_dirs_equal(self, dir1, dir2, fuse=False): + def assert_dirs_equal(self, dir1, dir2): diff = filecmp.dircmp(dir1, dir2) - self._assert_dirs_equal_cmp(diff, fuse) + self._assert_dirs_equal_cmp(diff) - def _assert_dirs_equal_cmp(self, diff, fuse=False): + def _assert_dirs_equal_cmp(self, diff): self.assert_equal(diff.left_only, []) self.assert_equal(diff.right_only, []) self.assert_equal(diff.diff_files, []) @@ -48,6 +56,8 @@ class AtticTestCase(unittest.TestCase): path2 = os.path.join(diff.right, filename) s1 = os.lstat(path1) s2 = os.lstat(path2) + # Assume path2 is on FUSE if st_dev is different + fuse = s1.st_dev != s2.st_dev attrs = ['st_mode', 'st_uid', 'st_gid', 'st_rdev'] if not fuse or not os.path.isdir(path1): # dir nlink is always 1 on our fuse fileystem @@ -55,18 +65,17 @@ class AtticTestCase(unittest.TestCase): d1 = [filename] + [getattr(s1, a) for a in attrs] d2 = [filename] + [getattr(s2, a) for a in attrs] if not os.path.islink(path1) or utime_supports_fd: - # llfuse does not provide ns precision for now - if fuse: + # Older versions of llfuse does not support ns precision properly + if fuse and not have_fuse_mtime_ns: d1.append(round(st_mtime_ns(s1), -4)) d2.append(round(st_mtime_ns(s2), -4)) - else: - d1.append(round(st_mtime_ns(s1), st_mtime_ns_round)) - d2.append(round(st_mtime_ns(s2), st_mtime_ns_round)) + d1.append(round(st_mtime_ns(s1), st_mtime_ns_round)) + d2.append(round(st_mtime_ns(s2), st_mtime_ns_round)) d1.append(self._get_xattrs(path1)) d2.append(self._get_xattrs(path2)) self.assert_equal(d1, d2) for sub_diff in diff.subdirs.values(): - self._assert_dirs_equal_cmp(sub_diff, fuse) + self._assert_dirs_equal_cmp(sub_diff) def wait_for_mount(self, path, timeout=5): """Wait until a filesystem is mounted on `path` diff --git a/attic/testsuite/archiver.py b/attic/testsuite/archiver.py index 71e834431..56d45277a 100644 --- a/attic/testsuite/archiver.py +++ b/attic/testsuite/archiver.py @@ -224,7 +224,7 @@ class ArchiverTestCase(AtticTestCase): try: self.attic('mount', self.repository_location + '::archive', mountpoint, fork=True) self.wait_for_mount(mountpoint) - self.assert_dirs_equal(self.input_path, os.path.join(mountpoint, 'input'), fuse=True) + self.assert_dirs_equal(self.input_path, os.path.join(mountpoint, 'input')) finally: if sys.platform.startswith('linux'): os.system('fusermount -u ' + mountpoint)