Răsfoiți Sursa

Merge pull request #7343 from ThomasWaldmann/timestamp-comparisons-master

relaxed timestamp comparisons (master)
TW 2 ani în urmă
părinte
comite
098fca7861

+ 11 - 4
src/borg/testsuite/__init__.py

@@ -42,14 +42,21 @@ except OSError:
 
 # The mtime get/set precision varies on different OS and Python versions
 if posix and "HAVE_FUTIMENS" in getattr(posix, "_have_functions", []):
-    st_mtime_ns_round = 0
+    st_mtime_ns_round = 0  # 1ns resolution
 elif "HAVE_UTIMES" in sysconfig.get_config_vars():
-    st_mtime_ns_round = -6
+    st_mtime_ns_round = -3  # 1us resolution
 else:
-    st_mtime_ns_round = -9
+    st_mtime_ns_round = -9  # 1s resolution
 
 if sys.platform.startswith("netbsd"):
-    st_mtime_ns_round = -4  # only >1 microsecond resolution here?
+    st_mtime_ns_round = -4  # 10us - strange: only >1 microsecond resolution here?
+
+
+def same_ts_ns(ts_ns1, ts_ns2):
+    """compare 2 timestamps (both in nanoseconds) whether they are (roughly) equal"""
+    diff_ts = int(abs(ts_ns1 - ts_ns2))
+    diff_max = 10 ** (-st_mtime_ns_round)
+    return diff_ts <= diff_max
 
 
 @contextmanager

+ 5 - 3
src/borg/testsuite/archiver/create_cmd.py

@@ -23,6 +23,7 @@ from .. import (
     are_fifos_supported,
     is_utime_fully_supported,
     is_birthtime_fully_supported,
+    same_ts_ns,
 )
 from . import (
     ArchiverTestCaseBase,
@@ -151,9 +152,10 @@ class ArchiverTestCase(ArchiverTestCaseBase):
             self.cmd(f"--repo={self.repository_location}", "extract", "test")
         sti = os.stat("input/file1")
         sto = os.stat("output/input/file1")
-        assert int(sti.st_birthtime * 1e9) == birthtime * 1e9
-        assert int(sto.st_birthtime * 1e9) == mtime * 1e9
-        assert sti.st_mtime_ns == sto.st_mtime_ns == mtime * 1e9
+        assert same_ts_ns(sti.st_birthtime * 1e9, birthtime * 1e9)
+        assert same_ts_ns(sto.st_birthtime * 1e9, mtime * 1e9)
+        assert same_ts_ns(sti.st_mtime_ns, sto.st_mtime_ns)
+        assert same_ts_ns(sto.st_mtime_ns, mtime * 1e9)
 
     def test_create_stdin(self):
         self.cmd(f"--repo={self.repository_location}", "rcreate", RK_ENCRYPTION)

+ 13 - 9
src/borg/testsuite/archiver/extract_cmd.py

@@ -11,7 +11,7 @@ from ...chunker import has_seek_hole
 from ...constants import *  # NOQA
 from ...helpers import EXIT_WARNING
 from ...helpers import flags_noatime, flags_normal
-from .. import changedir
+from .. import changedir, same_ts_ns
 from .. import are_symlinks_supported, are_hardlinks_supported, is_utime_fully_supported, is_birthtime_fully_supported
 from ..platform import is_darwin
 from . import (
@@ -73,7 +73,7 @@ class ArchiverTestCase(ArchiverTestCaseBase):
         # make sure borg fixes the directory mtime after touching it
         sti = os.stat("input/dir2")
         sto = os.stat("output/input/dir2")
-        assert sti.st_mtime_ns == sto.st_mtime_ns
+        assert same_ts_ns(sti.st_mtime_ns, sto.st_mtime_ns)
 
     @pytest.mark.skipif(not is_utime_fully_supported(), reason="cannot properly setup and execute test without utime")
     def test_directory_timestamps2(self):
@@ -90,7 +90,7 @@ class ArchiverTestCase(ArchiverTestCaseBase):
         # make sure borg fixes the directory mtime after touching it
         sti = os.stat("input/dir2")
         sto = os.stat("output/input/dir2")
-        assert sti.st_mtime_ns == sto.st_mtime_ns
+        assert same_ts_ns(sti.st_mtime_ns, sto.st_mtime_ns)
 
     @pytest.mark.skipif(not is_utime_fully_supported(), reason="cannot properly setup and execute test without utime")
     def test_directory_timestamps3(self):
@@ -107,7 +107,7 @@ class ArchiverTestCase(ArchiverTestCaseBase):
         # make sure borg fixes the directory mtime after touching it
         sti = os.stat("input/dir2")
         sto = os.stat("output/input/dir2")
-        assert sti.st_mtime_ns == sto.st_mtime_ns
+        assert same_ts_ns(sti.st_mtime_ns, sto.st_mtime_ns)
 
     @pytest.mark.skipif(not is_utime_fully_supported(), reason="cannot properly setup and execute test without utime")
     def test_atime(self):
@@ -133,12 +133,14 @@ class ArchiverTestCase(ArchiverTestCaseBase):
             self.cmd(f"--repo={self.repository_location}", "extract", "test")
         sti = os.stat("input/file1")
         sto = os.stat("output/input/file1")
-        assert sti.st_mtime_ns == sto.st_mtime_ns == mtime * 1e9
+        assert same_ts_ns(sti.st_mtime_ns, sto.st_mtime_ns)
+        assert same_ts_ns(sto.st_mtime_ns, mtime * 1e9)
         if have_noatime:
-            assert sti.st_atime_ns == sto.st_atime_ns == atime * 1e9
+            assert same_ts_ns(sti.st_atime_ns, sto.st_atime_ns)
+            assert same_ts_ns(sto.st_atime_ns, atime * 1e9)
         else:
             # it touched the input file's atime while backing it up
-            assert sto.st_atime_ns == atime * 1e9
+            assert same_ts_ns(sto.st_atime_ns, atime * 1e9)
 
     @pytest.mark.skipif(not is_utime_fully_supported(), reason="cannot properly setup and execute test without utime")
     @pytest.mark.skipif(
@@ -155,8 +157,10 @@ class ArchiverTestCase(ArchiverTestCaseBase):
             self.cmd(f"--repo={self.repository_location}", "extract", "test")
         sti = os.stat("input/file1")
         sto = os.stat("output/input/file1")
-        assert int(sti.st_birthtime * 1e9) == int(sto.st_birthtime * 1e9) == birthtime * 1e9
-        assert sti.st_mtime_ns == sto.st_mtime_ns == mtime * 1e9
+        assert same_ts_ns(sti.st_birthtime * 1e9, sto.st_birthtime * 1e9)
+        assert same_ts_ns(sto.st_birthtime * 1e9, birthtime * 1e9)
+        assert same_ts_ns(sti.st_mtime_ns, sto.st_mtime_ns)
+        assert same_ts_ns(sto.st_mtime_ns, mtime * 1e9)
 
     def test_sparse_file(self):
         def is_sparse(fn, total_size, hole_size):

+ 4 - 4
src/borg/testsuite/archiver/mount_cmds.py

@@ -11,7 +11,7 @@ from ...constants import *  # NOQA
 from ...locking import Lock
 from ...helpers import flags_noatime, flags_normal
 from .. import has_lchflags, llfuse
-from .. import changedir, no_selinux
+from .. import changedir, no_selinux, same_ts_ns
 from .. import are_symlinks_supported, are_hardlinks_supported, are_fifos_supported
 from ..platform import fakeroot_detected
 from . import (
@@ -109,9 +109,9 @@ class ArchiverTestCase(ArchiverTestCaseBase):
             assert sti1.st_gid == sto1.st_gid
             assert sti1.st_size == sto1.st_size
             if have_noatime:
-                assert sti1.st_atime == sto1.st_atime
-            assert sti1.st_ctime == sto1.st_ctime
-            assert sti1.st_mtime == sto1.st_mtime
+                assert same_ts_ns(sti1.st_atime * 1e9, sto1.st_atime * 1e9)
+            assert same_ts_ns(sti1.st_ctime * 1e9, sto1.st_ctime * 1e9)
+            assert same_ts_ns(sti1.st_mtime * 1e9, sto1.st_mtime * 1e9)
             if are_hardlinks_supported():
                 # note: there is another hardlink to this, see below
                 assert sti1.st_nlink == sto1.st_nlink == 2