refactor(settings): lazily initialize manager

This commit is contained in:
pixelpaws
2025-10-08 08:56:57 +08:00
parent 3118f3b43c
commit c53fa8692b
31 changed files with 299 additions and 172 deletions

View File

@@ -5,7 +5,7 @@ from typing import Any, Dict
import pytest
from py.services.settings_manager import settings
from py.services.settings_manager import get_settings_manager
from py.utils import example_images_download_manager as download_module
@@ -19,19 +19,21 @@ class RecordingWebSocketManager:
@pytest.fixture(autouse=True)
def restore_settings() -> None:
original = settings.settings.copy()
manager = get_settings_manager()
original = manager.settings.copy()
try:
yield
finally:
settings.settings.clear()
settings.settings.update(original)
manager.settings.clear()
manager.settings.update(original)
async def test_start_download_requires_configured_path(monkeypatch: pytest.MonkeyPatch) -> None:
manager = download_module.DownloadManager(ws_manager=RecordingWebSocketManager())
# Ensure example_images_path is not configured
settings.settings.pop('example_images_path', None)
settings_manager = get_settings_manager()
settings_manager.settings.pop('example_images_path', None)
with pytest.raises(download_module.DownloadConfigurationError) as exc_info:
await manager.start_download({})
@@ -44,9 +46,10 @@ async def test_start_download_requires_configured_path(monkeypatch: pytest.Monke
async def test_start_download_bootstraps_progress_and_task(monkeypatch: pytest.MonkeyPatch, tmp_path) -> None:
settings.settings["example_images_path"] = str(tmp_path)
settings.settings["libraries"] = {"default": {}}
settings.settings["active_library"] = "default"
settings_manager = get_settings_manager()
settings_manager.settings["example_images_path"] = str(tmp_path)
settings_manager.settings["libraries"] = {"default": {}}
settings_manager.settings["active_library"] = "default"
ws_manager = RecordingWebSocketManager()
manager = download_module.DownloadManager(ws_manager=ws_manager)
@@ -84,9 +87,10 @@ async def test_start_download_bootstraps_progress_and_task(monkeypatch: pytest.M
async def test_pause_and_resume_flow(monkeypatch: pytest.MonkeyPatch, tmp_path) -> None:
settings.settings["example_images_path"] = str(tmp_path)
settings.settings["libraries"] = {"default": {}}
settings.settings["active_library"] = "default"
settings_manager = get_settings_manager()
settings_manager.settings["example_images_path"] = str(tmp_path)
settings_manager.settings["libraries"] = {"default": {}}
settings_manager.settings["active_library"] = "default"
ws_manager = RecordingWebSocketManager()
manager = download_module.DownloadManager(ws_manager=ws_manager)

View File

@@ -7,7 +7,7 @@ from typing import Any, Dict
import pytest
from py.services.settings_manager import settings
from py.services.settings_manager import get_settings_manager
from py.utils.example_images_file_manager import ExampleImagesFileManager
@@ -22,16 +22,18 @@ class JsonRequest:
@pytest.fixture(autouse=True)
def restore_settings() -> None:
original = settings.settings.copy()
manager = get_settings_manager()
original = manager.settings.copy()
try:
yield
finally:
settings.settings.clear()
settings.settings.update(original)
manager.settings.clear()
manager.settings.update(original)
async def test_open_folder_requires_existing_model_directory(monkeypatch: pytest.MonkeyPatch, tmp_path) -> None:
settings.settings["example_images_path"] = str(tmp_path)
settings_manager = get_settings_manager()
settings_manager.settings["example_images_path"] = str(tmp_path)
model_hash = "a" * 64
model_folder = tmp_path / model_hash
model_folder.mkdir()
@@ -65,7 +67,8 @@ async def test_open_folder_requires_existing_model_directory(monkeypatch: pytest
async def test_open_folder_rejects_invalid_paths(monkeypatch: pytest.MonkeyPatch, tmp_path) -> None:
settings.settings["example_images_path"] = str(tmp_path)
settings_manager = get_settings_manager()
settings_manager.settings["example_images_path"] = str(tmp_path)
def fake_get_model_folder(_hash):
return str(tmp_path.parent / "outside")
@@ -81,7 +84,8 @@ async def test_open_folder_rejects_invalid_paths(monkeypatch: pytest.MonkeyPatch
async def test_get_files_lists_supported_media(tmp_path) -> None:
settings.settings["example_images_path"] = str(tmp_path)
settings_manager = get_settings_manager()
settings_manager.settings["example_images_path"] = str(tmp_path)
model_hash = "b" * 64
model_folder = tmp_path / model_hash
model_folder.mkdir()
@@ -99,7 +103,8 @@ async def test_get_files_lists_supported_media(tmp_path) -> None:
async def test_has_images_reports_presence(tmp_path) -> None:
settings.settings["example_images_path"] = str(tmp_path)
settings_manager = get_settings_manager()
settings_manager.settings["example_images_path"] = str(tmp_path)
model_hash = "c" * 64
model_folder = tmp_path / model_hash
model_folder.mkdir()

View File

@@ -6,7 +6,7 @@ from pathlib import Path
import pytest
from py.services.settings_manager import settings
from py.services.settings_manager import get_settings_manager
from py.utils.example_images_paths import (
ensure_library_root_exists,
get_model_folder,
@@ -18,18 +18,24 @@ from py.utils.example_images_paths import (
@pytest.fixture(autouse=True)
def restore_settings():
original = copy.deepcopy(settings.settings)
manager = get_settings_manager()
original = copy.deepcopy(manager.settings)
try:
yield
finally:
settings.settings.clear()
settings.settings.update(original)
manager.settings.clear()
manager.settings.update(original)
def test_get_model_folder_single_library(tmp_path):
settings.settings['example_images_path'] = str(tmp_path)
settings.settings['libraries'] = {'default': {}}
settings.settings['active_library'] = 'default'
@pytest.fixture
def settings_manager():
return get_settings_manager()
def test_get_model_folder_single_library(tmp_path, settings_manager):
settings_manager.settings['example_images_path'] = str(tmp_path)
settings_manager.settings['libraries'] = {'default': {}}
settings_manager.settings['active_library'] = 'default'
model_hash = 'a' * 64
folder = get_model_folder(model_hash)
@@ -39,13 +45,13 @@ def test_get_model_folder_single_library(tmp_path):
assert relative == model_hash
def test_get_model_folder_multi_library(tmp_path):
settings.settings['example_images_path'] = str(tmp_path)
settings.settings['libraries'] = {
def test_get_model_folder_multi_library(tmp_path, settings_manager):
settings_manager.settings['example_images_path'] = str(tmp_path)
settings_manager.settings['libraries'] = {
'default': {},
'Alt Library': {},
}
settings.settings['active_library'] = 'Alt Library'
settings_manager.settings['active_library'] = 'Alt Library'
model_hash = 'b' * 64
expected_folder = tmp_path / 'Alt_Library' / model_hash
@@ -57,13 +63,13 @@ def test_get_model_folder_multi_library(tmp_path):
assert relative == os.path.join('Alt_Library', model_hash).replace('\\', '/')
def test_get_model_folder_migrates_legacy_structure(tmp_path):
settings.settings['example_images_path'] = str(tmp_path)
settings.settings['libraries'] = {
def test_get_model_folder_migrates_legacy_structure(tmp_path, settings_manager):
settings_manager.settings['example_images_path'] = str(tmp_path)
settings_manager.settings['libraries'] = {
'default': {},
'extra': {},
}
settings.settings['active_library'] = 'extra'
settings_manager.settings['active_library'] = 'extra'
model_hash = 'c' * 64
legacy_folder = tmp_path / model_hash
@@ -82,31 +88,31 @@ def test_get_model_folder_migrates_legacy_structure(tmp_path):
assert (expected_folder / 'image.png').exists()
def test_ensure_library_root_exists_creates_directories(tmp_path):
settings.settings['example_images_path'] = str(tmp_path)
settings.settings['libraries'] = {'default': {}, 'secondary': {}}
settings.settings['active_library'] = 'secondary'
def test_ensure_library_root_exists_creates_directories(tmp_path, settings_manager):
settings_manager.settings['example_images_path'] = str(tmp_path)
settings_manager.settings['libraries'] = {'default': {}, 'secondary': {}}
settings_manager.settings['active_library'] = 'secondary'
resolved = ensure_library_root_exists('secondary')
assert Path(resolved) == tmp_path / 'secondary'
assert (tmp_path / 'secondary').is_dir()
def test_iter_library_roots_returns_all_configured(tmp_path):
settings.settings['example_images_path'] = str(tmp_path)
settings.settings['libraries'] = {'default': {}, 'alt': {}}
settings.settings['active_library'] = 'alt'
def test_iter_library_roots_returns_all_configured(tmp_path, settings_manager):
settings_manager.settings['example_images_path'] = str(tmp_path)
settings_manager.settings['libraries'] = {'default': {}, 'alt': {}}
settings_manager.settings['active_library'] = 'alt'
roots = dict(iter_library_roots())
assert roots['default'] == str(tmp_path / 'default')
assert roots['alt'] == str(tmp_path / 'alt')
def test_is_valid_example_images_root_accepts_hash_directories(tmp_path):
settings.settings['example_images_path'] = str(tmp_path)
def test_is_valid_example_images_root_accepts_hash_directories(tmp_path, settings_manager):
settings_manager.settings['example_images_path'] = str(tmp_path)
# Ensure single-library mode (not multi-library mode)
settings.settings['libraries'] = {'default': {}}
settings.settings['active_library'] = 'default'
settings_manager.settings['libraries'] = {'default': {}}
settings_manager.settings['active_library'] = 'default'
hash_folder = tmp_path / ('d' * 64)
hash_folder.mkdir()

View File

@@ -7,18 +7,19 @@ from typing import Any, Dict, Tuple
import pytest
from py.services.settings_manager import settings
from py.services.settings_manager import get_settings_manager
from py.utils import example_images_processor as processor_module
@pytest.fixture(autouse=True)
def restore_settings() -> None:
original = settings.settings.copy()
manager = get_settings_manager()
original = manager.settings.copy()
try:
yield
finally:
settings.settings.clear()
settings.settings.update(original)
manager.settings.clear()
manager.settings.update(original)
def test_get_file_extension_from_magic_bytes() -> None:
@@ -90,9 +91,10 @@ def stub_scanners(monkeypatch: pytest.MonkeyPatch, tmp_path) -> StubScanner:
async def test_import_images_creates_hash_directory(monkeypatch: pytest.MonkeyPatch, tmp_path, stub_scanners: StubScanner) -> None:
settings.settings["example_images_path"] = str(tmp_path / "examples")
settings.settings["libraries"] = {"default": {}}
settings.settings["active_library"] = "default"
settings_manager = get_settings_manager()
settings_manager.settings["example_images_path"] = str(tmp_path / "examples")
settings_manager.settings["libraries"] = {"default": {}}
settings_manager.settings["active_library"] = "default"
source_file = tmp_path / "upload.png"
source_file.write_bytes(b"PNG data")
@@ -112,7 +114,7 @@ async def test_import_images_creates_hash_directory(monkeypatch: pytest.MonkeyPa
assert result["success"] is True
assert result["files"][0]["name"].startswith("custom_short")
model_folder = Path(settings.settings["example_images_path"]) / ("a" * 64)
model_folder = Path(settings_manager.settings["example_images_path"]) / ("a" * 64)
assert model_folder.exists()
created_files = list(model_folder.glob("custom_short*.png"))
assert len(created_files) == 1
@@ -132,7 +134,8 @@ async def test_import_images_rejects_missing_parameters(monkeypatch: pytest.Monk
async def test_import_images_raises_when_model_not_found(monkeypatch: pytest.MonkeyPatch, tmp_path) -> None:
settings.settings["example_images_path"] = str(tmp_path)
settings_manager = get_settings_manager()
settings_manager.settings["example_images_path"] = str(tmp_path)
async def _empty_scanner(cls=None):
return StubScanner([])

View File

@@ -1,6 +1,6 @@
import pytest
from py.services.settings_manager import settings
from py.services.settings_manager import SettingsManager, get_settings_manager
from py.utils.utils import (
calculate_recipe_fingerprint,
calculate_relative_path_for_model,
@@ -9,7 +9,8 @@ from py.utils.utils import (
@pytest.fixture
def isolated_settings(monkeypatch):
default_settings = settings._get_default_settings()
manager = get_settings_manager()
default_settings = manager._get_default_settings()
default_settings.update(
{
"download_path_templates": {
@@ -20,8 +21,8 @@ def isolated_settings(monkeypatch):
"base_model_path_mappings": {},
}
)
monkeypatch.setattr(settings, "settings", default_settings)
monkeypatch.setattr(type(settings), "_save_settings", lambda self: None)
monkeypatch.setattr(manager, "settings", default_settings)
monkeypatch.setattr(SettingsManager, "_save_settings", lambda self: None)
return default_settings