dilutionrisk-mcp / tests /test_cache.py
mzx's picture
Hot-refresh verified Dataset revisions
6455b57 verified
Raw
History Blame Contribute Delete
2.88 kB
from __future__ import annotations
import hashlib,json,tempfile,unittest
from pathlib import Path
from unittest.mock import patch
from cache import RevisionCache
class CacheTests(unittest.TestCase):
def test_cold_start_and_corrupt_cache_rebuild(self):
with tempfile.TemporaryDirectory() as temporary:
root=Path(temporary);revision="a"*40; bodies={"data/a.parquet":b"parquet-proof","indexes/search.sqlite":b"sqlite-proof"}
manifest={"dataset_revision":revision,"artifacts":[{"storage":"dataset","path":path,"content_type":"application/vnd.apache.parquet" if path.endswith("parquet") else "application/vnd.sqlite3","size_bytes":len(body),"checksum":{"value":hashlib.sha256(body).hexdigest()}} for path,body in bodies.items()]}
cache=RevisionCache(root/"cache","manifest","mzx/test")
def bytes_for(url): return json.dumps(manifest).encode()
def download(url,target):
key=next(path for path in bodies if path in url);target.write_bytes(bodies[key]);return len(bodies[key]),hashlib.sha256(bodies[key]).hexdigest()
with patch.object(cache,"_bytes",side_effect=bytes_for),patch.object(cache,"_download",side_effect=download):
first=cache.bootstrap();self.assertTrue(first["ready"]);self.assertEqual(first["artifact_count"],2)
(Path(first["cache_dir"])/"data/a.parquet").write_bytes(b"corrupt")
second=cache.bootstrap();self.assertTrue(second["ready"]);self.assertEqual((Path(second["cache_dir"])/"data/a.parquet").read_bytes(),b"parquet-proof")
def test_incomplete_download_never_becomes_ready(self):
with tempfile.TemporaryDirectory() as temporary:
revision="b"*40;body=b"expected";manifest={"dataset_revision":revision,"artifacts":[{"storage":"dataset","path":"data/a.parquet","content_type":"application/vnd.apache.parquet","size_bytes":len(body),"checksum":{"value":hashlib.sha256(body).hexdigest()}}]};cache=RevisionCache(Path(temporary),"manifest","mzx/test")
with patch.object(cache,"_bytes",return_value=json.dumps(manifest).encode()),patch.object(cache,"_download",return_value=(3,"0"*64)):
with self.assertRaises(ValueError):cache.bootstrap()
self.assertFalse(cache.status()["ready"]);self.assertFalse(any(Path(temporary).glob("*/ready.json")))
def test_failed_refresh_keeps_last_verified_revision_ready(self):
with tempfile.TemporaryDirectory() as temporary:
cache=RevisionCache(Path(temporary),"manifest","mzx/test");revision="c"*40;active=Path(temporary)/revision;active.mkdir()
cache._status={"status":"ready","ready":True,"dataset_revision":revision,"artifact_count":2,"cached_bytes":12,"cache_dir":str(active),"error":None}
with patch.object(cache,"_bytes",side_effect=OSError("temporary network failure")):
with self.assertRaises(OSError):cache.bootstrap()
self.assertEqual(cache.status()["dataset_revision"],revision);self.assertTrue(cache.status()["ready"])
if __name__=="__main__":unittest.main()