102 lines
3.6 KiB
Python
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()
|