"""Tests para cache_to_sqlite.""" import os import tempfile import threading import time import pytest from .cache_to_sqlite import cache_to_sqlite @pytest.fixture def store(tmp_path): db = str(tmp_path / "test.db") return cache_to_sqlite(db) @pytest.fixture def store2(tmp_path): """Segundo namespace en la misma BD.""" db = str(tmp_path / "test.db") return cache_to_sqlite(db, namespace="other") @pytest.fixture def store_and_other(tmp_path): db = str(tmp_path / "test.db") s1 = cache_to_sqlite(db, namespace="ns1") s2 = cache_to_sqlite(db, namespace="ns2") return s1, s2 def test_set_y_get_basico(store): store.set("foo", {"x": 1}) assert store.get("foo") == {"x": 1} def test_ttl_expirado_retorna_none(store): store.set("expiring", "hello", ttl=0.05) time.sleep(0.1) assert store.get("expiring") is None def test_ttl_cero_nunca_expira(store): store.set("forever", 42, ttl=0) time.sleep(0.05) assert store.get("forever") == 42 def test_get_or_set_factory_solo_se_llama_en_miss(store): calls = [] def factory(): calls.append(1) return "computed" result1 = store.get_or_set("key", factory, ttl=10) result2 = store.get_or_set("key", factory, ttl=10) assert result1 == "computed" assert result2 == "computed" assert len(calls) == 1 def test_namespaces_independientes(store_and_other): s1, s2 = store_and_other s1.set("k", "from_ns1") assert s2.get("k") is None s2.set("k", "from_ns2") assert s1.get("k") == "from_ns1" assert s2.get("k") == "from_ns2" def test_clear_elimina_solo_el_namespace(store_and_other): s1, s2 = store_and_other s1.set("a", 1) s2.set("b", 2) removed = s1.clear() assert removed == 1 assert s1.get("a") is None assert s2.get("b") == 2 def test_stats_contadores_correctos(store): store.set("x", 10) store.get("x") # hit store.get("x") # hit store.get("z") # miss s = store.stats() assert s["hits"] == 2 assert s["misses"] == 1 assert s["size"] == 1 def test_concurrencia(tmp_path): db = str(tmp_path / "concurrent.db") s = cache_to_sqlite(db, "parallel") errors = [] def worker(i): try: s.set(f"key_{i}", i) val = s.get(f"key_{i}") assert val == i except Exception as e: errors.append(e) threads = [threading.Thread(target=worker, args=(i,)) for i in range(20)] for t in threads: t.start() for t in threads: t.join() assert errors == [], f"Errors in threads: {errors}"