"""Tests for configuration module.""" import os from unittest.mock import patch import pytest from pydantic import ValidationError from embeddings.config import EmbeddingSettings, SettingsCache class TestEmbeddingSettings: """Tests for EmbeddingSettings.""" def test_required_fields(self) -> None: """Test that required fields must be provided.""" with pytest.raises(ValidationError): EmbeddingSettings() def test_with_required_fields(self) -> None: """Test settings with all required fields provided.""" settings = EmbeddingSettings( default_backend="vllm", enable_vllm=True, enable_llamacpp=False, external_url="http://localhost:54100", ) assert settings.default_backend == "vllm" assert settings.enable_vllm is True assert settings.enable_llamacpp is False assert settings.external_url == "http://localhost:54100" def test_optional_defaults(self) -> None: """Test optional fields have sensible defaults.""" settings = EmbeddingSettings( default_backend="vllm", enable_vllm=True, enable_llamacpp=False, external_url="http://localhost:54100", ) assert settings.host == "0.0.0.0" assert settings.port == 54100 assert settings.request_timeout == 120.0 assert settings.rate_limit_rps == 20.0 assert settings.max_concurrent_requests == 20 def test_env_override(self) -> None: """Test environment variable overrides.""" env_vars = { "EMB_DEFAULT_BACKEND": "llamacpp", "EMB_ENABLE_VLLM": "false", "EMB_ENABLE_LLAMACPP": "true", "EMB_EXTERNAL_URL": "http://example.com", "EMB_PORT": "14100", } with patch.dict(os.environ, env_vars, clear=False): settings = EmbeddingSettings() assert settings.default_backend == "llamacpp" assert settings.enable_vllm is False assert settings.enable_llamacpp is True assert settings.port == 14100 def test_vllm_url_default(self) -> None: """Test vLLM URL default value.""" settings = EmbeddingSettings( default_backend="vllm", enable_vllm=True, enable_llamacpp=False, external_url="http://localhost:54100", ) assert settings.vllm_base_url == "http://localhost:54101" def test_llamacpp_url_default(self) -> None: """Test llama.cpp URL default value.""" settings = EmbeddingSettings( default_backend="vllm", enable_vllm=True, enable_llamacpp=False, external_url="http://localhost:54100", ) assert settings.llamacpp_base_url == "http://localhost:54110" def test_api_tokens_parsing(self) -> None: """Test API tokens are parsed from comma-separated string.""" settings = EmbeddingSettings( default_backend="vllm", enable_vllm=True, enable_llamacpp=False, external_url="http://localhost:54100", api_tokens="token1,token2,token3", # type: ignore[arg-type] ) assert settings.api_tokens is not None assert "token1" in settings.api_tokens assert "token2" in settings.api_tokens assert "token3" in settings.api_tokens assert settings.auth_enabled is True def test_auth_disabled_by_default(self) -> None: """Test authentication is disabled when no tokens set.""" settings = EmbeddingSettings( default_backend="vllm", enable_vllm=True, enable_llamacpp=False, external_url="http://localhost:54100", ) assert settings.api_tokens is None assert settings.auth_enabled is False class TestSettingsCache: """Tests for SettingsCache class.""" def test_set_and_get(self) -> None: """Test setting and getting cached settings.""" SettingsCache.clear() settings = EmbeddingSettings( default_backend="vllm", enable_vllm=True, enable_llamacpp=False, external_url="http://localhost:54100", ) SettingsCache.set(settings) retrieved = SettingsCache.get() assert retrieved is settings def test_get_without_set_creates_instance(self) -> None: """Test that get() creates instance from environment if not set.""" SettingsCache.clear() env_vars = { "EMB_DEFAULT_BACKEND": "vllm", "EMB_ENABLE_VLLM": "true", "EMB_ENABLE_LLAMACPP": "false", "EMB_EXTERNAL_URL": "http://localhost:54100", } with patch.dict(os.environ, env_vars, clear=False): settings = SettingsCache.get() assert isinstance(settings, EmbeddingSettings) assert settings.default_backend == "vllm" def test_cached_returns_same_instance(self) -> None: """Test that SettingsCache returns cached instance.""" SettingsCache.clear() settings = EmbeddingSettings( default_backend="vllm", enable_vllm=True, enable_llamacpp=False, external_url="http://localhost:54100", ) SettingsCache.set(settings) settings1 = SettingsCache.get() settings2 = SettingsCache.get() assert settings1 is settings2 def test_clear_removes_cached_instance(self) -> None: """Test that clear() removes the cached instance.""" settings = EmbeddingSettings( default_backend="vllm", enable_vllm=True, enable_llamacpp=False, external_url="http://localhost:54100", ) SettingsCache.set(settings) SettingsCache.clear() assert SettingsCache._instance is None