Team Ai
Apppublic

diegobeyl/backtesting

sourceHugging Faceupdated 9mo agoView on Hugging Face
2likes
test_phase4_cache.py224 linesDownload Raw Back to tests
1"""2Test suite para Fase 4: Cache Manager3=====================================4Pruebas completas del sistema de caché:5- Memory cache6- Disk cache7- Cache manager multi-nivel8- TTL y expiración9- Estadísticas10"""11 12import sys13import time14import json15from pathlib import Path16 17# Asegurar que el módulo pueda importarse18sys.path.insert(0, "/Users/javier/Projects/backtesting_app_v2")19 20from backtesting_app.core.cache_manager import (21    CacheManager,22    MemoryCache,23    DiskCache,24    CacheEntry,25)26 27 28def test_1_memory_cache_basic():29    """Test 1: Operaciones básicas de memory cache"""30    print("\n✅ Test 1: Memory Cache - Operaciones básicas")31 32    cache = MemoryCache(max_size_mb=10)33 34    # Guardar35    cache.set("key1", {"data": "value1"})36    assert cache.get("key1") == {"data": "value1"}, "No se guardó/recuperó correctamente"37 38    # Borrar39    cache.delete("key1")40    assert cache.get("key1") is None, "No se borró correctamente"41 42    print("   ✅ PASS - Operaciones básicas funcionan")43 44 45def test_2_memory_cache_ttl():46    """Test 2: Memory Cache - Expiración TTL"""47    print("\n✅ Test 2: Memory Cache - TTL y expiración")48 49    cache = MemoryCache(max_size_mb=10)50 51    # Guardar con TTL de 1 segundo52    cache.set("key_ttl", {"data": "expires"}, ttl=1)53    assert cache.get("key_ttl") is not None, "Debería existir antes de expirar"54 55    # Esperar a que expire56    time.sleep(1.1)57    assert cache.get("key_ttl") is None, "Debería haber expirado"58 59    print("   ✅ PASS - TTL funciona correctamente")60 61 62def test_3_disk_cache():63    """Test 3: Disk Cache - Guardado y recuperación"""64    print("\n✅ Test 3: Disk Cache - Guardado en disco")65 66    cache = DiskCache(cache_dir="/tmp/test_cache_disk")67 68    # Guardar69    test_data = {"symbol": "BTC", "price": 45000}70    cache.set("btc_price", test_data)71 72    # Recuperar73    result = cache.get("btc_price")74    assert result is not None, "No se recuperó del disco"75    value, is_valid = result76    assert value == test_data, "Los datos no coinciden"77    assert is_valid, "Los datos no son válidos"78 79    # Limpiar80    cache.clear()81    print("   ✅ PASS - Disk cache funciona")82 83 84def test_4_disk_cache_ttl():85    """Test 4: Disk Cache - TTL en disco"""86    print("\n✅ Test 4: Disk Cache - TTL en disco")87 88    cache = DiskCache(cache_dir="/tmp/test_cache_disk")89 90    # Guardar con TTL91    cache.set("expires_soon", {"value": 123}, ttl=1)92 93    # Antes de expirar94    result = cache.get("expires_soon")95    assert result is not None, "Debería existir"96 97    # Esperar expiración98    time.sleep(1.1)99    result = cache.get("expires_soon")100    assert result is None, "Debería haber expirado"101 102    cache.clear()103    print("   ✅ PASS - TTL en disco funciona")104 105 106def test_5_cache_manager_multi_level():107    """Test 5: Cache Manager - Multi-nivel (memoria + disco)"""108    print("\n✅ Test 5: Cache Manager - Multi-nivel")109 110    cache = CacheManager(memory_size_mb=10, disk_cache_dir="/tmp/test_cache_manager")111 112    # Guardar datos113    data = {"symbol": "ETH", "candles": 100}114    cache.set("eth_data", data, ttl=3600)115 116    # Recuperar de memoria (rápido)117    result = cache.get("eth_data")118    assert result == data, "No recuperó de memoria"119    assert cache.stats_hits == 1, "No registró hit"120 121    # Simular pérdida de memoria (limpiar)122    cache.memory.clear()123 124    # Recuperar de disco (más lento pero existe)125    result = cache.get("eth_data")126    assert result == data, "No recuperó del disco"127    assert cache.stats_hits == 2, "No registró segundo hit"128 129    cache.clear()130    print("   ✅ PASS - Multi-nivel funciona correctamente")131 132 133def test_6_cache_stats():134    """Test 6: Estadísticas del caché"""135    print("\n✅ Test 6: Estadísticas del caché")136 137    cache = CacheManager(memory_size_mb=10)138 139    # Agregar entradas140    for i in range(5):141        cache.set(f"key_{i}", {"value": i * 100})142 143    # Hacer algunos hits144    for i in range(3):145        cache.get(f"key_{i}")146 147    stats = cache.get_stats()148 149    assert stats["memory"]["entries"] == 5, "Número de entradas incorrecto"150    assert stats["stats"]["total_hits"] == 3, "Total de hits incorrecto"151    # Hit rate: 3 hits / (3 hits + 2 misses) = 60%152    assert stats["stats"]["hit_rate_percent"] > 50, "Hit rate debería ser > 50%"153 154    cache.clear()155    print("   ✅ PASS - Estadísticas correctas")156 157 158def test_7_cache_invalidation_pattern():159    """Test 7: Invalidación por patrón"""160    print("\n✅ Test 7: Invalidación por patrón")161 162    cache = CacheManager(memory_size_mb=10)163 164    # Agregar datos solo en memoria (evitar persistencia en disco)165    cache.memory.set("BTC-USDT_1h", {"data": 1})166    cache.memory.set("BTC-USDT_4h", {"data": 2})167    cache.memory.set("ETH-USDT_1h", {"data": 3})168 169    # Invalidar patrón BTC-*170    cache.invalidate_pattern("BTC-*")171 172    assert cache.memory.get("BTC-USDT_1h") is None, "No se invalidó BTC-USDT_1h"173    assert cache.memory.get("BTC-USDT_4h") is None, "No se invalidó BTC-USDT_4h"174    assert cache.memory.get("ETH-USDT_1h") is not None, "Se invalidó ETH-USDT_1h incorrectamente"175 176    cache.clear()177    print("   ✅ PASS - Invalidación por patrón funciona")178 179 180def main():181    """Ejecutar todos los tests"""182    print("=" * 70)183    print("🧪 FASE 4: CACHE MANAGER - TEST SUITE")184    print("=" * 70)185 186    tests = [187        test_1_memory_cache_basic,188        test_2_memory_cache_ttl,189        test_3_disk_cache,190        test_4_disk_cache_ttl,191        test_5_cache_manager_multi_level,192        test_6_cache_stats,193        test_7_cache_invalidation_pattern,194    ]195 196    passed = 0197    failed = 0198 199    for test_func in tests:200        try:201            test_func()202            passed += 1203        except AssertionError as e:204            print(f"   ❌ FAIL - {e}")205            failed += 1206        except Exception as e:207            print(f"   ❌ ERROR - {e}")208            failed += 1209 210    print("\n" + "=" * 70)211    print(f"📊 RESULTADOS: {passed} PASADAS ✅ | {failed} FALLADAS ❌")212    print("=" * 70)213 214    if failed == 0:215        print("\n🎉 ¡TODOS LOS TESTS PASARON!")216        return 0217    else:218        print(f"\n⚠️  {failed} test(s) fallaron")219        return 1220 221 222if __name__ == "__main__":223    sys.exit(main())224