1
0
Fork 0
Code Issues Pull requests Projects Releases 2 Packages Wiki Activity Actions Pages
DocForge2/tests/test_incremental_cache.py

102 lines
3.6 KiB
Python

from __future__ import annotations
import hashlib
import os
import tempfile
import unittest
from pathlib import Path
from docforge.errors import DocForgeError
from docforge.incremental import (
CachedSource,
ExtractionCache,
load_extraction_cache,
write_extraction_cache,
)
class ExtractionCacheBoundsTests(unittest.TestCase):
@staticmethod
def cache(*, payload: str = "ok", count: int = 1) -> ExtractionCache:
sources = tuple(
CachedSource(
source_id=f"source-{index}",
source_path=f"src/{index}.txt",
fingerprint=hashlib.sha256(str(index).encode()).hexdigest(),
extractor_version="fixture@1",
dependencies=(),
payload={"content": payload},
)
for index in range(count)
)
return ExtractionCache("fixture", "fixture-adapter", "1", sources)
def test_bounded_round_trip_and_oversized_read_is_a_cache_miss(self) -> None:
with tempfile.TemporaryDirectory() as directory:
path = Path(directory) / "extractions.json"
write_extraction_cache(path, self.cache(), max_bytes=1_000, max_sources=2)
loaded = load_extraction_cache(
path,
project_id="fixture",
adapter_id="fixture-adapter",
adapter_version="1",
max_bytes=1_000,
max_sources=2,
)
self.assertEqual(self.cache(), loaded)
with path.open("ab") as handle:
handle.write(b" " * 1_000)
self.assertIsNone(
load_extraction_cache(
path,
project_id="fixture",
adapter_id="fixture-adapter",
adapter_version="1",
max_bytes=1_000,
max_sources=2,
)
)
def test_write_rejects_byte_and_source_limits_without_replacing_target(self) -> None:
with tempfile.TemporaryDirectory() as directory:
path = Path(directory) / "extractions.json"
path.write_bytes(b"preserved\n")
for cache, maximum_bytes, maximum_sources in (
(self.cache(payload="x" * 500), 100, 2),
(self.cache(count=2), 1_000, 1),
):
with self.assertRaises(DocForgeError) as captured:
write_extraction_cache(
path,
cache,
max_bytes=maximum_bytes,
max_sources=maximum_sources,
)
self.assertEqual("cache_limit", captured.exception.code)
self.assertEqual(b"preserved\n", path.read_bytes())
def test_symlink_and_non_regular_targets_are_cache_misses(self) -> None:
with tempfile.TemporaryDirectory() as directory:
root = Path(directory)
real = root / "real.json"
write_extraction_cache(real, self.cache(), max_bytes=1_000, max_sources=2)
linked = root / "linked.json"
linked.symlink_to(real)
fifo = root / "fifo"
os.mkfifo(fifo)
for path in (linked, fifo):
self.assertIsNone(
load_extraction_cache(
path,
project_id="fixture",
adapter_id="fixture-adapter",
adapter_version="1",
max_bytes=1_000,
max_sources=2,
)
)
if __name__ == "__main__":
unittest.main()