refactor: lru_cache fuer get_settings, vollere field-coverage in tests
This commit is contained in:
@@ -1,3 +1,5 @@
|
|||||||
|
from functools import lru_cache
|
||||||
|
|
||||||
from pydantic_settings import BaseSettings, SettingsConfigDict
|
from pydantic_settings import BaseSettings, SettingsConfigDict
|
||||||
|
|
||||||
|
|
||||||
@@ -22,11 +24,6 @@ class Settings(BaseSettings):
|
|||||||
log_level: str = "INFO"
|
log_level: str = "INFO"
|
||||||
|
|
||||||
|
|
||||||
_settings: Settings | None = None
|
@lru_cache(maxsize=1)
|
||||||
|
|
||||||
|
|
||||||
def get_settings() -> Settings:
|
def get_settings() -> Settings:
|
||||||
global _settings
|
return Settings()
|
||||||
if _settings is None:
|
|
||||||
_settings = Settings()
|
|
||||||
return _settings
|
|
||||||
|
|||||||
@@ -1,39 +1,51 @@
|
|||||||
import os
|
|
||||||
import pytest
|
import pytest
|
||||||
from app.config import Settings
|
from pydantic import ValidationError
|
||||||
|
|
||||||
|
from app.config import Settings, get_settings
|
||||||
|
|
||||||
|
|
||||||
|
REQUIRED_ENV = {
|
||||||
|
"NEXTCLOUD_WEBDAV_URL": "https://nc/remote.php/dav/files/u",
|
||||||
|
"NEXTCLOUD_USER": "u",
|
||||||
|
"NEXTCLOUD_APP_PASSWORD": "pw",
|
||||||
|
"OLLAMA_URL": "http://ollama:11434",
|
||||||
|
"OLLAMA_EMBED_MODEL": "qwen3-embedding:0.6b",
|
||||||
|
"QDRANT_URL": "http://qdrant:6333",
|
||||||
|
"QDRANT_COLLECTION": "rag_test",
|
||||||
|
"WEBHOOK_SECRET": "secret",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def _set_required(monkeypatch):
|
||||||
|
for k, v in REQUIRED_ENV.items():
|
||||||
|
monkeypatch.setenv(k, v)
|
||||||
|
|
||||||
|
|
||||||
def test_settings_loads_all_required_fields(monkeypatch):
|
def test_settings_loads_all_required_fields(monkeypatch):
|
||||||
monkeypatch.setenv("NEXTCLOUD_WEBDAV_URL", "https://nc/remote.php/dav/files/u")
|
_set_required(monkeypatch)
|
||||||
monkeypatch.setenv("NEXTCLOUD_USER", "u")
|
|
||||||
monkeypatch.setenv("NEXTCLOUD_APP_PASSWORD", "pw")
|
|
||||||
monkeypatch.setenv("OLLAMA_URL", "http://ollama:11434")
|
|
||||||
monkeypatch.setenv("OLLAMA_EMBED_MODEL", "qwen3-embedding:0.6b")
|
|
||||||
monkeypatch.setenv("QDRANT_URL", "http://qdrant:6333")
|
|
||||||
monkeypatch.setenv("QDRANT_COLLECTION", "rag_test")
|
|
||||||
monkeypatch.setenv("WEBHOOK_SECRET", "secret")
|
|
||||||
|
|
||||||
s = Settings()
|
s = Settings()
|
||||||
|
|
||||||
assert s.nextcloud_user == "u"
|
assert s.nextcloud_webdav_url == REQUIRED_ENV["NEXTCLOUD_WEBDAV_URL"]
|
||||||
assert s.qdrant_collection == "rag_test"
|
assert s.nextcloud_user == REQUIRED_ENV["NEXTCLOUD_USER"]
|
||||||
assert s.ingest_root == "Documents/THB/Studium" # default
|
assert s.nextcloud_app_password == REQUIRED_ENV["NEXTCLOUD_APP_PASSWORD"]
|
||||||
|
assert s.ollama_url == REQUIRED_ENV["OLLAMA_URL"]
|
||||||
|
assert s.ollama_embed_model == REQUIRED_ENV["OLLAMA_EMBED_MODEL"]
|
||||||
|
assert s.qdrant_url == REQUIRED_ENV["QDRANT_URL"]
|
||||||
|
assert s.qdrant_collection == REQUIRED_ENV["QDRANT_COLLECTION"]
|
||||||
|
assert s.webhook_secret == REQUIRED_ENV["WEBHOOK_SECRET"]
|
||||||
|
# defaults
|
||||||
|
assert s.ingest_root == "Documents/THB/Studium"
|
||||||
assert s.chunk_size_words == 500
|
assert s.chunk_size_words == 500
|
||||||
assert s.chunk_overlap_words == 50
|
assert s.chunk_overlap_words == 50
|
||||||
assert s.log_level == "INFO"
|
assert s.log_level == "INFO"
|
||||||
|
|
||||||
|
|
||||||
def test_settings_overrides_defaults(monkeypatch):
|
def test_settings_overrides_defaults(monkeypatch):
|
||||||
for k, v in {
|
_set_required(monkeypatch)
|
||||||
"NEXTCLOUD_WEBDAV_URL": "x", "NEXTCLOUD_USER": "x",
|
monkeypatch.setenv("INGEST_ROOT", "Other/Path")
|
||||||
"NEXTCLOUD_APP_PASSWORD": "x", "OLLAMA_URL": "x",
|
monkeypatch.setenv("CHUNK_SIZE_WORDS", "300")
|
||||||
"OLLAMA_EMBED_MODEL": "x", "QDRANT_URL": "x",
|
monkeypatch.setenv("CHUNK_OVERLAP_WORDS", "30")
|
||||||
"QDRANT_COLLECTION": "x", "WEBHOOK_SECRET": "x",
|
|
||||||
"INGEST_ROOT": "Other/Path",
|
|
||||||
"CHUNK_SIZE_WORDS": "300",
|
|
||||||
"CHUNK_OVERLAP_WORDS": "30",
|
|
||||||
}.items():
|
|
||||||
monkeypatch.setenv(k, v)
|
|
||||||
|
|
||||||
s = Settings()
|
s = Settings()
|
||||||
|
|
||||||
@@ -43,10 +55,21 @@ def test_settings_overrides_defaults(monkeypatch):
|
|||||||
|
|
||||||
|
|
||||||
def test_settings_missing_required_raises(monkeypatch):
|
def test_settings_missing_required_raises(monkeypatch):
|
||||||
for k in ["NEXTCLOUD_WEBDAV_URL", "NEXTCLOUD_USER", "NEXTCLOUD_APP_PASSWORD",
|
for k in REQUIRED_ENV:
|
||||||
"OLLAMA_URL", "OLLAMA_EMBED_MODEL", "QDRANT_URL",
|
|
||||||
"QDRANT_COLLECTION", "WEBHOOK_SECRET"]:
|
|
||||||
monkeypatch.delenv(k, raising=False)
|
monkeypatch.delenv(k, raising=False)
|
||||||
|
|
||||||
with pytest.raises(Exception):
|
with pytest.raises(ValidationError):
|
||||||
Settings()
|
Settings()
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_settings_caches_instance(monkeypatch):
|
||||||
|
_set_required(monkeypatch)
|
||||||
|
get_settings.cache_clear()
|
||||||
|
|
||||||
|
first = get_settings()
|
||||||
|
second = get_settings()
|
||||||
|
|
||||||
|
assert isinstance(first, Settings)
|
||||||
|
assert first is second
|
||||||
|
|
||||||
|
get_settings.cache_clear()
|
||||||
|
|||||||
Reference in New Issue
Block a user