Files
wehub-resource-sync 7a0da7932b
OSV-Scanner (Scheduled) / scan-scheduled (push) Failing after 0s
Create Release / test-gate (push) Has been cancelled
Create Release / release-gate (push) Has been cancelled
Create Release / ci-gate (push) Has been cancelled
Create Release / version-check (push) Has been cancelled
Create Release / e2e-test-gate (push) Has been cancelled
Create Release / responsive-test-gate (push) Has been cancelled
Create Release / compat-test-gate (push) Has been cancelled
Create Release / compose-integration-gate (push) Has been cancelled
Create Release / vulture-gate (push) Has been cancelled
Create Release / build (push) Has been cancelled
Create Release / provenance (push) Has been cancelled
Create Release / prerelease-docker (push) Has been cancelled
Create Release / publish-docker (push) Has been cancelled
Create Release / create-release (push) Has been cancelled
Create Release / cleanup-changelog (push) Has been cancelled
Create Release / trigger-pypi (push) Has been cancelled
Create Release / monitor-pypi (push) Has been cancelled
Create Release / Clean up orphan prerelease tags and signatures (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-form] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-metrics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-workflow] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-core] (push) Has been cancelled
CodeQL Advanced / Analyze (javascript-typescript) (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [history-news] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [library] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [link-analytics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-core] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-lifecycle] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [error-benchmark] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) (push) Has been cancelled
Docker Tests (Consolidated) / Accessibility Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Unit Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Example Tests (push) Has been cancelled
Docker Tests (Consolidated) / Production Image Smoke Test (push) Has been cancelled
Docker Tests (Consolidated) / Infrastructure Tests (push) Has been cancelled
OSSF Scorecard / OSSF Security Scorecard Analysis (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [mobile] (push) Has been cancelled
Backwards Compatibility / Verify Encryption Constants (push) Has been cancelled
Backwards Compatibility / PyPI Version Compatibility (push) Has been cancelled
Backwards Compatibility / Database Migration Tests (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Docker Tests (Consolidated) / detect-changes (push) Has been cancelled
Docker Tests (Consolidated) / Build Test Image (push) Has been cancelled
Docker Tests (Consolidated) / All Pytest Tests + Coverage (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [accessibility] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [api-crud] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-login] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-register] (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:08:55 +08:00

369 lines
11 KiB
Python

"""
Tests for llm/llm_registry.py
Tests cover:
- LLMRegistry class methods
- Global registry functions
- Thread safety
- Case-insensitive registration
"""
import threading
from unittest.mock import Mock
class TestLLMRegistryInit:
"""Tests for LLMRegistry initialization."""
def test_init_creates_empty_registry(self):
"""Test that initialization creates empty registry."""
from local_deep_research.llm.llm_registry import LLMRegistry
registry = LLMRegistry()
assert registry.list_registered() == []
def test_init_creates_lock(self):
"""Test that initialization creates threading lock."""
from local_deep_research.llm.llm_registry import LLMRegistry
registry = LLMRegistry()
assert registry._lock is not None
assert isinstance(registry._lock, type(threading.Lock()))
class TestLLMRegistryRegister:
"""Tests for LLMRegistry.register method."""
def test_register_llm_instance(self):
"""Test registering an LLM instance."""
from local_deep_research.llm.llm_registry import LLMRegistry
registry = LLMRegistry()
mock_llm = Mock()
registry.register("test-llm", mock_llm)
assert registry.is_registered("test-llm")
assert registry.get("test-llm") is mock_llm
def test_register_llm_factory(self):
"""Test registering an LLM factory function."""
from local_deep_research.llm.llm_registry import LLMRegistry
registry = LLMRegistry()
factory = Mock(return_value=Mock())
registry.register("test-factory", factory)
assert registry.is_registered("test-factory")
assert registry.get("test-factory") is factory
def test_register_normalizes_name_to_lowercase(self):
"""Test that registration normalizes names to lowercase."""
from local_deep_research.llm.llm_registry import LLMRegistry
registry = LLMRegistry()
mock_llm = Mock()
registry.register("Test-LLM", mock_llm)
assert registry.is_registered("test-llm")
assert registry.is_registered("TEST-LLM")
assert registry.is_registered("Test-LLM")
def test_register_overwrites_existing(self):
"""Test that registering overwrites existing LLM with same name."""
from local_deep_research.llm.llm_registry import LLMRegistry
registry = LLMRegistry()
mock_llm1 = Mock(name="llm1")
mock_llm2 = Mock(name="llm2")
registry.register("test", mock_llm1)
registry.register("test", mock_llm2)
assert registry.get("test") is mock_llm2
class TestLLMRegistryUnregister:
"""Tests for LLMRegistry.unregister method."""
def test_unregister_removes_llm(self):
"""Test that unregister removes the LLM."""
from local_deep_research.llm.llm_registry import LLMRegistry
registry = LLMRegistry()
mock_llm = Mock()
registry.register("test", mock_llm)
assert registry.is_registered("test")
registry.unregister("test")
assert not registry.is_registered("test")
def test_unregister_nonexistent_does_nothing(self):
"""Test that unregistering non-existent LLM doesn't raise."""
from local_deep_research.llm.llm_registry import LLMRegistry
registry = LLMRegistry()
# Should not raise
registry.unregister("nonexistent")
def test_unregister_is_case_insensitive(self):
"""Test that unregister is case-insensitive."""
from local_deep_research.llm.llm_registry import LLMRegistry
registry = LLMRegistry()
mock_llm = Mock()
registry.register("Test-LLM", mock_llm)
registry.unregister("TEST-LLM")
assert not registry.is_registered("test-llm")
class TestLLMRegistryGet:
"""Tests for LLMRegistry.get method."""
def test_get_returns_registered_llm(self):
"""Test that get returns the registered LLM."""
from local_deep_research.llm.llm_registry import LLMRegistry
registry = LLMRegistry()
mock_llm = Mock()
registry.register("test", mock_llm)
assert registry.get("test") is mock_llm
def test_get_returns_none_for_nonexistent(self):
"""Test that get returns None for non-existent LLM."""
from local_deep_research.llm.llm_registry import LLMRegistry
registry = LLMRegistry()
assert registry.get("nonexistent") is None
def test_get_is_case_insensitive(self):
"""Test that get is case-insensitive."""
from local_deep_research.llm.llm_registry import LLMRegistry
registry = LLMRegistry()
mock_llm = Mock()
registry.register("Test-LLM", mock_llm)
assert registry.get("test-llm") is mock_llm
assert registry.get("TEST-LLM") is mock_llm
class TestLLMRegistryIsRegistered:
"""Tests for LLMRegistry.is_registered method."""
def test_is_registered_returns_true_for_registered(self):
"""Test that is_registered returns True for registered LLM."""
from local_deep_research.llm.llm_registry import LLMRegistry
registry = LLMRegistry()
mock_llm = Mock()
registry.register("test", mock_llm)
assert registry.is_registered("test") is True
def test_is_registered_returns_false_for_nonexistent(self):
"""Test that is_registered returns False for non-existent LLM."""
from local_deep_research.llm.llm_registry import LLMRegistry
registry = LLMRegistry()
assert registry.is_registered("nonexistent") is False
class TestLLMRegistryListRegistered:
"""Tests for LLMRegistry.list_registered method."""
def test_list_registered_returns_empty_for_new_registry(self):
"""Test that list_registered returns empty list for new registry."""
from local_deep_research.llm.llm_registry import LLMRegistry
registry = LLMRegistry()
assert registry.list_registered() == []
def test_list_registered_returns_all_names(self):
"""Test that list_registered returns all registered names."""
from local_deep_research.llm.llm_registry import LLMRegistry
registry = LLMRegistry()
registry.register("llm1", Mock())
registry.register("llm2", Mock())
registry.register("llm3", Mock())
names = registry.list_registered()
assert len(names) == 3
assert "llm1" in names
assert "llm2" in names
assert "llm3" in names
class TestLLMRegistryClear:
"""Tests for LLMRegistry.clear method."""
def test_clear_removes_all_llms(self):
"""Test that clear removes all registered LLMs."""
from local_deep_research.llm.llm_registry import LLMRegistry
registry = LLMRegistry()
registry.register("llm1", Mock())
registry.register("llm2", Mock())
registry.register("llm3", Mock())
assert len(registry.list_registered()) == 3
registry.clear()
assert registry.list_registered() == []
class TestGlobalRegistryFunctions:
"""Tests for global registry public API functions."""
def test_register_llm_function(self):
"""Test global register_llm function."""
from local_deep_research.llm.llm_registry import (
register_llm,
is_llm_registered,
clear_llm_registry,
)
try:
mock_llm = Mock()
register_llm("global-test", mock_llm)
assert is_llm_registered("global-test")
finally:
clear_llm_registry()
def test_unregister_llm_function(self):
"""Test global unregister_llm function."""
from local_deep_research.llm.llm_registry import (
register_llm,
unregister_llm,
is_llm_registered,
clear_llm_registry,
)
try:
register_llm("global-test", Mock())
assert is_llm_registered("global-test")
unregister_llm("global-test")
assert not is_llm_registered("global-test")
finally:
clear_llm_registry()
def test_get_llm_from_registry_function(self):
"""Test global get_llm_from_registry function."""
from local_deep_research.llm.llm_registry import (
register_llm,
get_llm_from_registry,
clear_llm_registry,
)
try:
mock_llm = Mock()
register_llm("global-test", mock_llm)
assert get_llm_from_registry("global-test") is mock_llm
finally:
clear_llm_registry()
def test_list_registered_llms_function(self):
"""Test global list_registered_llms function."""
from local_deep_research.llm.llm_registry import (
register_llm,
list_registered_llms,
clear_llm_registry,
)
try:
register_llm("test1", Mock())
register_llm("test2", Mock())
names = list_registered_llms()
assert "test1" in names
assert "test2" in names
finally:
clear_llm_registry()
def test_clear_llm_registry_function(self):
"""Test global clear_llm_registry function."""
from local_deep_research.llm.llm_registry import (
register_llm,
list_registered_llms,
clear_llm_registry,
)
register_llm("test1", Mock())
register_llm("test2", Mock())
clear_llm_registry()
assert list_registered_llms() == []
class TestThreadSafety:
"""Tests for thread safety of LLMRegistry."""
def test_concurrent_registration(self):
"""Test that concurrent registrations are thread-safe."""
from local_deep_research.llm.llm_registry import LLMRegistry
registry = LLMRegistry()
errors = []
def register_llm(name):
try:
registry.register(name, Mock())
except Exception as e:
errors.append(e)
threads = [
threading.Thread(target=register_llm, args=(f"llm-{i}",))
for i in range(100)
]
for t in threads:
t.start()
for t in threads:
t.join()
assert len(errors) == 0
assert len(registry.list_registered()) == 100
def test_concurrent_get(self):
"""Test that concurrent gets are thread-safe."""
from local_deep_research.llm.llm_registry import LLMRegistry
registry = LLMRegistry()
mock_llm = Mock()
registry.register("test", mock_llm)
results = []
def get_llm():
result = registry.get("test")
results.append(result)
threads = [threading.Thread(target=get_llm) for _ in range(100)]
for t in threads:
t.start()
for t in threads:
t.join()
assert len(results) == 100
assert all(r is mock_llm for r in results)