Skip to content

Commit

Permalink
trying to workout how to how to accurately determine mtime resolution
Browse files Browse the repository at this point in the history
  • Loading branch information
tclose committed Sep 12, 2024
1 parent f9c9626 commit 6006c44
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 13 deletions.
32 changes: 20 additions & 12 deletions fileformats/core/fs_mount_identifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,20 +171,24 @@ def get_mtime_resolution(cls, path: PathLike) -> int:
the root of the mount the path sits on
fstype : str
the type of the file-system (e.g. ext4 or cifs)"""
mount_point, _ = cls.get_mount(path)
# try:
# resolution = cls.FS_MTIME_NS_RESOLUTION[fstype]
# except KeyError:
# try:
resolution = cls.measure_mtime_resolution(mount_point)
# except (RuntimeError, OSError):
# # Fallback to the largest known mtime
# resolution = max(cls.FS_MTIME_NS_RESOLUTION.values())
mount_point, fstype = cls.get_mount(path)
try:
resolution = cls.FS_MTIME_NS_RESOLUTION[fstype]
except KeyError:
try:
resolution = cls.measure_mtime_resolution(path)
except (RuntimeError, OSError):

Check warning on line 180 in fileformats/core/fs_mount_identifier.py

View check run for this annotation

Codecov / codecov/patch

fileformats/core/fs_mount_identifier.py#L180

Added line #L180 was not covered by tests
# Fallback to the largest known mtime
resolution = max(cls.FS_MTIME_NS_RESOLUTION.values())

Check warning on line 182 in fileformats/core/fs_mount_identifier.py

View check run for this annotation

Codecov / codecov/patch

fileformats/core/fs_mount_identifier.py#L182

Added line #L182 was not covered by tests
else:
cls.FS_MTIME_NS_RESOLUTION[fstype] = resolution
return resolution

@classmethod
def measure_mtime_resolution(cls, mount_point: Path) -> int:
tmp_file = Path(mount_point) / ".__fileformats_mtime_measurement_test_file__"
def measure_mtime_resolution(cls, sample_path: PathLike) -> int:
tmp_file = (
Path(sample_path).parent / ".__fileformats_mtime_measurement_test_file__"
)
tmp_file.touch()
try:
# Get the initial mtime
Expand All @@ -198,11 +202,15 @@ def measure_mtime_resolution(cls, mount_point: Path) -> int:
# Calculate the resolution
resolution = new_mtime - initial_mtime
return resolution
raise RuntimeError(f"Couldn't determine the mtime for the {mount_point}")
raise RuntimeError(

Check warning on line 205 in fileformats/core/fs_mount_identifier.py

View check run for this annotation

Codecov / codecov/patch

fileformats/core/fs_mount_identifier.py#L205

Added line #L205 was not covered by tests
f"Couldn't determine the mtime for the file-system that {sample_path}"
"is stored on"
)
finally:
tmp_file.unlink()

_mount_table: ty.Optional[ty.List[ty.Tuple[str, str]]] = None
# _inode_size_table: ty.Dict[str, int] = {}

# Define a table of file system types and their mtime resolutions (in seconds)
FS_MTIME_NS_RESOLUTION: ty.Dict[str, int] = {
Expand Down
6 changes: 5 additions & 1 deletion fileformats/core/tests/test_decorators.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from pathlib import Path
import time
from fileformats.core.decorators import (
mtime_cached_property,
enough_time_has_elapsed_given_mtime_resolution,
Expand All @@ -20,6 +21,9 @@ def test_mtime_cached_property(tmp_path: Path):
fspath.write_text("hello")

file = MtimeTestFile(fspath)
time.sleep(
2
) # ensure enough time has elapsed since file creation/modification for mtime to increment

file.flag = 0
assert file.cached_prop == 0
Expand All @@ -31,7 +35,7 @@ def test_mtime_cached_property(tmp_path: Path):

def test_enough_time_has_elapsed_given_mtime_resolution():
assert enough_time_has_elapsed_given_mtime_resolution(
[("", 110), ("", 220), ("", 300)], 311
[("", 110), ("", 220), ("", 300)], int(3e9) # need to make it high for windows
)


Expand Down

0 comments on commit 6006c44

Please sign in to comment.