Skip to content

Commit

Permalink
Test that file order is irrelevant for DirFingerprints
Browse files Browse the repository at this point in the history
  • Loading branch information
jwodder committed Feb 21, 2022
1 parent 7c1ca60 commit a5f1e86
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 6 deletions.
12 changes: 6 additions & 6 deletions src/fscacher/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,17 +197,17 @@ def to_tuple(self):
class DirFingerprint:
def __init__(self):
self.last_modified = None
self.hash_ords = None
self.hash = None

def add_file(self, path, fprint: FileFingerprint):
fprint_hash = md5(
ascii((str(path), fprint.to_tuple())).encode("us-ascii")
).digest()
if self.hash_ords is None:
self.hash_ords = fprint_hash
if self.hash is None:
self.hash = fprint_hash
self.last_modified = fprint.mtime_ns
else:
self.hash_ords = xor_bytes(self.hash_ords, fprint_hash)
self.hash = xor_bytes(self.hash, fprint_hash)
if self.last_modified < fprint.mtime_ns:
self.last_modified = fprint.mtime_ns

Expand All @@ -218,10 +218,10 @@ def modified_in_window(self, min_dtime):
return abs(time.time() - self.last_modified * 1e-9) < min_dtime

def to_tuple(self):
if self.hash_ords is None:
if self.hash is None:
return (None,)
else:
return (bytes(self.hash_ords).hex(),)
return (self.hash.hex(),)


def xor_bytes(b1: bytes, b2: bytes) -> bytes:
Expand Down
27 changes: 27 additions & 0 deletions src/fscacher/tests/test_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import time
import pytest
from .. import PersistentCache
from ..cache import DirFingerprint, FileFingerprint

platform_system = platform.system().lower()
on_windows = platform_system == "windows"
Expand Down Expand Up @@ -415,3 +416,29 @@ def memoread(filepath, arg, kwarg=None):
assert len(calls) == ncalls + 1
assert memoread(arg=1, filepath=path) == "content"
assert len(calls) == ncalls + 1


def test_dir_fingerprint_order_irrelevant(tmp_path):
start = time.time()
file1 = tmp_path / "apple.txt"
file1.write_text("Apple\n")
os.utime(file1, (start - 1, start - 1))
file2 = tmp_path / "banana.txt"
file2.write_text("This is test text.\n")
os.utime(file2, (start - 2, start - 2))
file3 = tmp_path / "coconut.txt"
file3.write_text("Lorem ipsum dolor sit amet, consectetur adipisicing elit\n")
os.utime(file3, (start - 3, start - 3))
df_tuples = []
for file_list in [
[file1, file2, file3],
[file3, file2, file1],
[file2, file1, file3],
]:
dprint = DirFingerprint()
for f in file_list:
fprint = FileFingerprint.from_stat(os.stat(f))
dprint.add_file(f, fprint)
df_tuples.append(dprint.to_tuple())
for i in range(1, len(df_tuples)):
assert df_tuples[0] == df_tuples[i]

0 comments on commit a5f1e86

Please sign in to comment.