perf(model-metadata): persist OpenRouter metadata cache (#46114)
This commit is contained in:
@@ -1083,6 +1083,78 @@ class TestFetchModelMetadata:
|
||||
mm._model_metadata_cache = {}
|
||||
mm._model_metadata_cache_time = 0
|
||||
|
||||
def _isolate_disk_cache(self, monkeypatch, tmp_path):
|
||||
import agent.model_metadata as mm
|
||||
cache_path = tmp_path / "openrouter_model_metadata.json"
|
||||
monkeypatch.setattr(mm, "_get_model_metadata_cache_path", lambda: cache_path)
|
||||
return cache_path
|
||||
|
||||
def test_fresh_disk_cache_skips_network(self, tmp_path, monkeypatch):
|
||||
self._reset_cache()
|
||||
cache_path = self._isolate_disk_cache(monkeypatch, tmp_path)
|
||||
cache_path.write_text(
|
||||
'{"test/model":{"context_length":12345,"name":"Cached","pricing":{}}}',
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
with patch("agent.model_metadata.requests.get") as mock_get:
|
||||
result = fetch_model_metadata()
|
||||
|
||||
mock_get.assert_not_called()
|
||||
assert result["test/model"]["context_length"] == 12345
|
||||
|
||||
def test_force_refresh_bypasses_fresh_disk_cache(self, tmp_path, monkeypatch):
|
||||
self._reset_cache()
|
||||
cache_path = self._isolate_disk_cache(monkeypatch, tmp_path)
|
||||
cache_path.write_text(
|
||||
'{"test/model":{"context_length":12345,"name":"Cached","pricing":{}}}',
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
mock_response = MagicMock()
|
||||
mock_response.json.return_value = {
|
||||
"data": [{"id": "live/model", "context_length": 67890, "name": "Live"}]
|
||||
}
|
||||
mock_response.raise_for_status = MagicMock()
|
||||
|
||||
with patch("agent.model_metadata.requests.get", return_value=mock_response) as mock_get:
|
||||
result = fetch_model_metadata(force_refresh=True)
|
||||
|
||||
assert mock_get.call_count == 1
|
||||
assert "live/model" in result
|
||||
assert "test/model" not in result
|
||||
|
||||
def test_network_success_writes_disk_cache(self, tmp_path, monkeypatch):
|
||||
self._reset_cache()
|
||||
cache_path = self._isolate_disk_cache(monkeypatch, tmp_path)
|
||||
mock_response = MagicMock()
|
||||
mock_response.json.return_value = {
|
||||
"data": [{"id": "live/model", "context_length": 67890, "name": "Live"}]
|
||||
}
|
||||
mock_response.raise_for_status = MagicMock()
|
||||
|
||||
with patch("agent.model_metadata.requests.get", return_value=mock_response):
|
||||
fetch_model_metadata(force_refresh=True)
|
||||
|
||||
assert cache_path.exists()
|
||||
assert "live/model" in cache_path.read_text(encoding="utf-8")
|
||||
|
||||
def test_network_failure_falls_back_to_stale_disk_cache(self, tmp_path, monkeypatch):
|
||||
self._reset_cache()
|
||||
cache_path = self._isolate_disk_cache(monkeypatch, tmp_path)
|
||||
cache_path.write_text(
|
||||
'{"stale/model":{"context_length":50000,"name":"Stale","pricing":{}}}',
|
||||
encoding="utf-8",
|
||||
)
|
||||
old = time.time() - _MODEL_CACHE_TTL - 60
|
||||
import os
|
||||
os.utime(cache_path, (old, old))
|
||||
|
||||
with patch("agent.model_metadata.requests.get", side_effect=Exception("Network error")):
|
||||
result = fetch_model_metadata(force_refresh=True)
|
||||
|
||||
assert result["stale/model"]["context_length"] == 50000
|
||||
|
||||
@patch("agent.model_metadata.requests.get")
|
||||
def test_caches_result(self, mock_get):
|
||||
self._reset_cache()
|
||||
@@ -1162,10 +1234,11 @@ class TestFetchModelMetadata:
|
||||
assert result["test-model"]["context_length"] == 123456
|
||||
|
||||
@patch("agent.model_metadata.requests.get")
|
||||
def test_ttl_expiry_triggers_refetch(self, mock_get):
|
||||
def test_ttl_expiry_triggers_refetch(self, mock_get, tmp_path, monkeypatch):
|
||||
"""Cache expires after _MODEL_CACHE_TTL seconds."""
|
||||
import agent.model_metadata as mm
|
||||
self._reset_cache()
|
||||
cache_path = self._isolate_disk_cache(monkeypatch, tmp_path)
|
||||
|
||||
mock_response = MagicMock()
|
||||
mock_response.json.return_value = {
|
||||
@@ -1177,8 +1250,11 @@ class TestFetchModelMetadata:
|
||||
fetch_model_metadata(force_refresh=True)
|
||||
assert mock_get.call_count == 1
|
||||
|
||||
# Simulate TTL expiry
|
||||
# Simulate both memory and disk TTL expiry.
|
||||
mm._model_metadata_cache_time = time.time() - _MODEL_CACHE_TTL - 1
|
||||
old = time.time() - _MODEL_CACHE_TTL - 1
|
||||
import os
|
||||
os.utime(cache_path, (old, old))
|
||||
fetch_model_metadata()
|
||||
assert mock_get.call_count == 2 # refetched
|
||||
|
||||
|
||||
Reference in New Issue
Block a user