Spaces:
Sleeping
Sleeping
File size: 4,087 Bytes
901e5fa | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | from __future__ import annotations
import json
from pathlib import Path
import pytest
from PIL import Image
from ai_agent.utils import previews
from ai_agent.utils import cache_db
from ai_agent.utils.cache_db import CacheDB, reset_cache_db
@pytest.fixture(autouse=True)
def _isolated_cache_db():
"""Give every test a fresh in-memory SQLite cache."""
db = CacheDB(":memory:")
reset_cache_db(db)
yield
reset_cache_db(None)
def test_preview_cache_roundtrip_hit(tmp_path: Path, monkeypatch: pytest.MonkeyPatch):
key = ("/tmp/example.png::1::1",)
preview_file = tmp_path / "preview.png"
preview_file.write_bytes(b"x")
monkeypatch.setattr(previews, "PREVIEW_CACHE_TTL_SECONDS", 30)
previews._preview_cache_set(key, str(preview_file), "meta")
out_path, out_meta = previews._preview_cache_get(key)
assert out_path == str(preview_file)
assert out_meta == "meta"
def test_preview_cache_evicts_expired_entries(
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
):
key = ("/tmp/expired.png::1::1",)
preview_file = tmp_path / "expired.png"
preview_file.write_bytes(b"x")
now = {"t": 1_000_000.0}
monkeypatch.setattr(cache_db.time, "time", lambda: now["t"])
monkeypatch.setattr(previews, "PREVIEW_CACHE_TTL_SECONDS", 5)
previews._preview_cache_set(key, str(preview_file), "meta")
now["t"] = 1_000_006.0 # past TTL
out_path, out_meta = previews._preview_cache_get(key)
assert out_path is None
assert out_meta is None
def test_preview_cache_drops_missing_file_entry(monkeypatch: pytest.MonkeyPatch):
key = ("/tmp/missing.png::1::1",)
monkeypatch.setattr(previews, "PREVIEW_CACHE_TTL_SECONDS", 3000)
# Manually insert an entry pointing to a non-existent file
db_key = json.dumps(key)
value = json.dumps({"path": "/tmp/does-not-exist.png", "meta": "meta"})
cache_db.get_cache_db().set(
previews._PREVIEW_NS, db_key, value, ttl_seconds=3000
)
out_path, out_meta = previews._preview_cache_get(key)
assert out_path is None
assert out_meta is None
def test_preview_cache_capacity_eviction(tmp_path: Path, monkeypatch: pytest.MonkeyPatch):
monkeypatch.setattr(previews, "PREVIEW_CACHE_TTL_SECONDS", 100)
monkeypatch.setattr(previews, "PREVIEW_CACHE_MAX_ENTRIES", 2)
now = {"t": 1_000_000.0}
monkeypatch.setattr(cache_db.time, "time", lambda: now["t"])
a = tmp_path / "a.png"
b = tmp_path / "b.png"
c = tmp_path / "c.png"
a.write_bytes(b"a")
b.write_bytes(b"b")
c.write_bytes(b"c")
key_a = ("a",)
key_b = ("b",)
key_c = ("c",)
now["t"] = 1_000_001.0
previews._preview_cache_set(key_a, str(a), "a")
now["t"] = 1_000_002.0
previews._preview_cache_set(key_b, str(b), "b")
now["t"] = 1_000_003.0
previews._preview_cache_set(key_c, str(c), "c")
# key_a should have been evicted (oldest-accessed, capacity=2)
assert previews._preview_cache_get(key_a) == (None, None)
assert previews._preview_cache_get(key_b)[0] == str(b)
assert previews._preview_cache_get(key_c)[0] == str(c)
def test_preview_cache_clear_helper_empties_cache(tmp_path: Path, monkeypatch: pytest.MonkeyPatch):
monkeypatch.setattr(previews, "PREVIEW_CACHE_TTL_SECONDS", 30)
preview_file = tmp_path / "x.png"
preview_file.write_bytes(b"x")
previews._preview_cache_set(("x",), str(preview_file), "meta")
previews._clear_preview_cache_for_tests()
assert previews._preview_cache_get(("x",)) == (None, None)
def test_resize_for_preview_preserves_aspect_ratio():
img = Image.new("L", (2000, 1000), color=128)
resized = previews._resize_for_preview(img, max_side_px=500)
assert resized.size == (500, 250)
def test_resize_for_preview_does_not_upscale():
img = Image.new("RGB", (320, 200), color=(0, 0, 0))
resized = previews._resize_for_preview(img, max_side_px=500)
assert resized.size == (320, 200) |