mirror of
https://github.com/nesquena/hermes-webui.git
synced 2026-05-22 18:30:28 +00:00
115 lines
4.0 KiB
Python
115 lines
4.0 KiB
Python
"""Regression tests for /api/models/live backend TTL caching."""
|
|
|
|
import sys
|
|
import types
|
|
from urllib.parse import urlparse
|
|
|
|
|
|
def _install_provider_model_ids(monkeypatch, fn):
|
|
hermes_cli = types.ModuleType("hermes_cli")
|
|
hermes_cli.__path__ = []
|
|
models = types.ModuleType("hermes_cli.models")
|
|
models.provider_model_ids = fn
|
|
monkeypatch.setitem(sys.modules, "hermes_cli", hermes_cli)
|
|
monkeypatch.setitem(sys.modules, "hermes_cli.models", models)
|
|
|
|
|
|
def _patch_live_models_basics(monkeypatch, routes, profile="default"):
|
|
import api.config as config
|
|
import api.profiles as profiles
|
|
|
|
routes._clear_live_models_cache()
|
|
monkeypatch.setattr(routes, "j", lambda _handler, payload, status=200, extra_headers=None: payload)
|
|
monkeypatch.setattr(config, "get_config", lambda: {"model": {"provider": "openai"}})
|
|
monkeypatch.setattr(config, "_resolve_provider_alias", lambda provider: provider)
|
|
monkeypatch.setattr(profiles, "get_active_profile_name", lambda: profile)
|
|
|
|
|
|
def test_live_models_cache_hits_within_ttl(monkeypatch):
|
|
import api.routes as routes
|
|
|
|
calls = []
|
|
|
|
def provider_model_ids(provider):
|
|
calls.append(provider)
|
|
return ["openai/gpt-test"]
|
|
|
|
_install_provider_model_ids(monkeypatch, provider_model_ids)
|
|
_patch_live_models_basics(monkeypatch, routes)
|
|
|
|
parsed = urlparse("/api/models/live?provider=openai")
|
|
first = routes._handle_live_models(object(), parsed)
|
|
second = routes._handle_live_models(object(), parsed)
|
|
|
|
assert calls == ["openai"]
|
|
assert first == second
|
|
assert first["models"] == [{"id": "openai/gpt-test", "label": "GPT Test"}]
|
|
|
|
|
|
def test_live_models_cache_expires(monkeypatch):
|
|
import api.routes as routes
|
|
|
|
now = [1000.0]
|
|
calls = []
|
|
|
|
def provider_model_ids(provider):
|
|
calls.append(provider)
|
|
return [f"{provider}/model-{len(calls)}"]
|
|
|
|
_install_provider_model_ids(monkeypatch, provider_model_ids)
|
|
_patch_live_models_basics(monkeypatch, routes)
|
|
monkeypatch.setattr(routes.time, "monotonic", lambda: now[0])
|
|
|
|
parsed = urlparse("/api/models/live?provider=openai")
|
|
first = routes._handle_live_models(object(), parsed)
|
|
now[0] += routes._LIVE_MODELS_CACHE_TTL + 1
|
|
second = routes._handle_live_models(object(), parsed)
|
|
|
|
assert calls == ["openai", "openai"]
|
|
assert first["models"][0]["id"] == "openai/model-1"
|
|
assert second["models"][0]["id"] == "openai/model-2"
|
|
|
|
|
|
def test_live_models_cache_is_profile_scoped(monkeypatch):
|
|
import api.routes as routes
|
|
import api.profiles as profiles
|
|
|
|
active_profile = ["default"]
|
|
calls = []
|
|
|
|
def provider_model_ids(provider):
|
|
calls.append((active_profile[0], provider))
|
|
return [f"{provider}/{active_profile[0]}-model"]
|
|
|
|
_install_provider_model_ids(monkeypatch, provider_model_ids)
|
|
_patch_live_models_basics(monkeypatch, routes)
|
|
monkeypatch.setattr(profiles, "get_active_profile_name", lambda: active_profile[0])
|
|
|
|
parsed = urlparse("/api/models/live?provider=openai")
|
|
default_payload = routes._handle_live_models(object(), parsed)
|
|
active_profile[0] = "research"
|
|
research_payload = routes._handle_live_models(object(), parsed)
|
|
again_payload = routes._handle_live_models(object(), parsed)
|
|
|
|
assert calls == [("default", "openai"), ("research", "openai")]
|
|
assert default_payload["models"][0]["id"] == "openai/default-model"
|
|
assert research_payload["models"][0]["id"] == "openai/research-model"
|
|
assert again_payload == research_payload
|
|
|
|
|
|
def test_live_models_cache_returns_deep_copies(monkeypatch):
|
|
import api.routes as routes
|
|
|
|
_install_provider_model_ids(monkeypatch, lambda provider: ["openai/gpt-test"])
|
|
_patch_live_models_basics(monkeypatch, routes)
|
|
|
|
parsed = urlparse("/api/models/live?provider=openai")
|
|
first = routes._handle_live_models(object(), parsed)
|
|
first["models"].clear()
|
|
first["provider"] = "mutated"
|
|
|
|
second = routes._handle_live_models(object(), parsed)
|
|
|
|
assert second["provider"] == "openai"
|
|
assert second["models"] == [{"id": "openai/gpt-test", "label": "GPT Test"}]
|