zico-agent / tests /test_strategy_live_data.py
github-actions[bot]
Deploy from GitHub Actions: 45adc209fd7d164663375a81a6d4f7a761468085
0f123dc
import os
import sys
import time
import json
import unittest
from unittest.mock import patch
from pathlib import Path
ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
if ROOT not in sys.path:
sys.path.insert(0, ROOT)
from src.agents.strategy import live_data
class _FakeCache:
def __init__(self):
self.store = {}
self.exp = {}
def _alive(self, key: str) -> bool:
exp = self.exp.get(key)
if exp is None:
return key in self.store
if time.time() > exp:
self.store.pop(key, None)
self.exp.pop(key, None)
return False
return True
def get_json(self, key: str):
return self.store.get(key) if self._alive(key) else None
def set_json(self, key: str, value, ttl: int):
self.store[key] = value
self.exp[key] = time.time() + ttl
def set_error(self, key: str, payload, ttl: int):
self.set_json(key, {"__error__": True, "payload": payload}, ttl=ttl)
def incr(self, key: str, ttl: int):
value = int(self.store.get(key, 0) or 0) + 1
self.store[key] = value
self.exp[key] = time.time() + ttl
return value
def exists(self, key: str):
return self._alive(key)
class LiveDataTest(unittest.TestCase):
def setUp(self):
self.cache = _FakeCache()
live_data._CACHE = self.cache
live_data._MICRO_CACHE.clear()
def test_slug_mapping_known_protocol(self):
self.assertEqual(live_data._defillama_protocol_slug("Euler V2"), "euler-v2")
def test_alias_matching_variants(self):
self.assertTrue(live_data._project_matches_protocol("spark-savings", "Spark"))
self.assertTrue(live_data._project_matches_protocol("joe-v2.1", "LFJ"))
self.assertTrue(live_data._project_matches_protocol("blackhole-clmm", "Blackhole"))
def test_fresh_cache_hit(self):
key = live_data._build_cache_key("lending", ["Spark"])
self.cache.set_json(
key,
{"payload": {"apy": 0.09, "freshness": "fresh", "source": "defillama"}, "_cached_at": time.time()},
ttl=live_data._STALE_TTL,
)
with patch("src.agents.strategy.live_data.lending_adapter", side_effect=RuntimeError("should not fetch")):
result = live_data.enrich_live_data("lending", ["Spark"])
self.assertEqual(result["apy"], 0.09)
self.assertEqual(result["freshness"], "fresh")
def test_stale_cache_used_on_fetch_failure(self):
key = live_data._build_cache_key("lending", ["Spark"])
self.cache.set_json(
key,
{"payload": {"apy": 0.08, "freshness": "fresh", "source": "defillama"}, "_cached_at": time.time() - 240},
ttl=live_data._STALE_TTL,
)
with patch("src.agents.strategy.live_data.lending_adapter", side_effect=RuntimeError("network")):
result = live_data.enrich_live_data("lending", ["Spark"])
self.assertEqual(result["apy"], 0.08)
self.assertEqual(result["freshness"], "stale")
def test_negative_cache_triggers_static_fallback(self):
key = live_data._build_cache_key("lending", ["Spark"])
self.cache.set_error(f"{key}:error", {"err": "timeout"}, ttl=live_data._ERROR_TTL)
result = live_data.enrich_live_data("lending", ["Spark"])
self.assertEqual(result["source"], "static_assumption")
self.assertEqual(result["confidence"], "low")
self.assertIsNotNone(result.get("apy"))
def test_source_failover_to_static_when_no_pool_and_no_protocol_stats(self):
with patch("src.agents.strategy.live_data._fetch_pool_apy", return_value=None), patch(
"src.agents.strategy.live_data._fetch_protocol_stats", side_effect=RuntimeError("boom")
):
result = live_data.enrich_live_data("lending", ["Spark"])
self.assertEqual(result["source"], "static_assumption")
self.assertEqual(result["confidence"], "low")
def test_protocol_adapter_map_covers_all_registry_protocols(self):
registry_protocols = set()
for registry_name in ("strategy_registry.avalanche.json", "strategy_registry.base.json"):
registry = json.loads(
Path(
f"/home/inteli/Área de trabalho/projects/panorama/zico_agent/new_zico/src/agents/strategy/{registry_name}"
).read_text(encoding="utf-8")
)
registry_protocols.update({p for s in registry for p in s.get("protocols", [])})
adapter_protocols = set(live_data._PROTOCOL_ADAPTERS.keys())
self.assertTrue(registry_protocols.issubset(adapter_protocols))
def test_multi_protocol_strategy_selects_best_apy(self):
with patch(
"src.agents.strategy.live_data._PROTOCOL_ADAPTERS",
{
"Hypha": lambda _network: {
"apy": 0.07,
"tvl": 1000.0,
"capacity": "ok",
"risk_flags": [],
"as_of": "now",
"source": "defillama",
"freshness": "fresh",
"warning": None,
"confidence": "high",
},
"Euler V2": lambda _network: {
"apy": 0.05,
"tvl": 2000.0,
"capacity": "ok",
"risk_flags": [],
"as_of": "now",
"source": "defillama",
"freshness": "fresh",
"warning": None,
"confidence": "high",
},
},
):
result = live_data.enrich_live_data("structured", ["Hypha", "Euler V2"])
self.assertEqual(result["protocol"], "Hypha")
self.assertEqual(result["apy"], 0.07)
if __name__ == "__main__":
unittest.main()