mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-08-28 08:21:27 -03:00
574dfbbe55
Add LORA_MANAGER_SETTINGS_DIR env var and standalone --settings-path to pin the settings location (settings.json, cache/, wildcards/, backups/, logs/, stats/) to an arbitrary directory. The override takes precedence over portable mode and the platform user config dir, and skips legacy migration, so sandboxed dev/E2E runs no longer need to write settings.json in the repo root or collide with the real instance. standalone.py pre-scans argv for --settings-path at import time because the settings location is resolved before main() parses arguments. SettingsManager portable-switch migration is a no-op while the directory is pinned. Update the lora-manager-e2e skill (prefer --settings-path sandboxing; start_server.py passes it through) and the lora-manager-runtime-context skill (document precedence; inspect script honors the override).
158 lines
5.3 KiB
Python
158 lines
5.3 KiB
Python
import importlib
|
|
import json
|
|
import os
|
|
import sys
|
|
from pathlib import Path
|
|
from typing import Any
|
|
|
|
import pytest
|
|
|
|
from py.services.settings_manager import get_settings_manager, reset_settings_manager
|
|
from py.utils import settings_paths
|
|
|
|
|
|
@pytest.fixture(autouse=True)
|
|
def reset_settings(tmp_path, monkeypatch):
|
|
"""Reset the settings manager and redirect config to a temp directory."""
|
|
def fake_user_config_dir(*args, **kwargs):
|
|
return str(tmp_path / "config")
|
|
|
|
monkeypatch.setattr(settings_paths, "user_config_dir", fake_user_config_dir)
|
|
monkeypatch.setenv("LORA_MANAGER_STANDALONE", "1")
|
|
reset_settings_manager()
|
|
yield
|
|
reset_settings_manager()
|
|
|
|
|
|
def read_settings_file(path: Path) -> dict[str, Any]:
|
|
with path.open('r', encoding='utf-8') as handle:
|
|
return json.load(handle)
|
|
|
|
|
|
def read_example_settings() -> dict[str, Any]:
|
|
example_path = Path(__file__).resolve().parents[1] / "settings.json.example"
|
|
with example_path.open('r', encoding='utf-8') as handle:
|
|
return json.load(handle)
|
|
|
|
|
|
def test_missing_settings_creates_defaults_and_emits_warnings(tmp_path):
|
|
manager = get_settings_manager()
|
|
settings_path = Path(manager.settings_file)
|
|
|
|
assert settings_path.exists()
|
|
assert read_settings_file(settings_path)
|
|
|
|
messages = manager.get_startup_messages()
|
|
codes = {message["code"] for message in messages}
|
|
assert codes == {"missing-model-paths"}
|
|
|
|
warning = messages[0]
|
|
assert "default settings.json" in warning["message"].lower()
|
|
assert warning["dismissible"] is False
|
|
|
|
actions = warning.get("actions") or []
|
|
assert actions == [
|
|
{
|
|
"action": "open-settings-location",
|
|
"label": "Open settings folder",
|
|
"type": "primary",
|
|
"icon": "fas fa-folder-open",
|
|
}
|
|
]
|
|
|
|
|
|
def test_template_settings_are_preserved_on_restart(tmp_path):
|
|
manager = get_settings_manager()
|
|
settings_path = Path(manager.settings_file)
|
|
|
|
example_payload = read_example_settings()
|
|
assert read_settings_file(settings_path) == example_payload
|
|
|
|
reset_settings_manager()
|
|
|
|
manager = get_settings_manager()
|
|
assert Path(manager.settings_file) == settings_path
|
|
assert read_settings_file(settings_path) == example_payload
|
|
|
|
|
|
def test_invalid_settings_recovers_with_defaults(tmp_path):
|
|
config_dir = Path(settings_paths.user_config_dir())
|
|
config_dir.mkdir(parents=True, exist_ok=True)
|
|
settings_path = config_dir / "settings.json"
|
|
settings_path.write_text("{ invalid json", encoding='utf-8')
|
|
|
|
manager = get_settings_manager()
|
|
|
|
assert settings_path.exists()
|
|
data = read_settings_file(settings_path)
|
|
assert isinstance(data, dict)
|
|
|
|
codes = {message["code"] for message in manager.get_startup_messages()}
|
|
assert "settings-json-invalid" in codes
|
|
|
|
|
|
def test_missing_settings_skips_warning_when_embedded(tmp_path, monkeypatch):
|
|
monkeypatch.setenv("LORA_MANAGER_STANDALONE", "0")
|
|
reset_settings_manager()
|
|
|
|
manager = get_settings_manager()
|
|
|
|
assert manager.get_startup_messages() == []
|
|
|
|
|
|
def test_validate_settings_logs_warnings(tmp_path, monkeypatch, caplog):
|
|
monkeypatch.setattr(settings_paths, "user_config_dir", lambda *args, **kwargs: str(tmp_path / "config"))
|
|
|
|
reset_settings_manager()
|
|
import standalone
|
|
importlib.reload(standalone)
|
|
|
|
reset_settings_manager()
|
|
|
|
with caplog.at_level("INFO", logger="lora-manager-standalone"):
|
|
assert standalone.validate_settings() is True
|
|
|
|
messages = [record.message for record in caplog.records]
|
|
assert any("Standalone mode is using fallback configuration values." in message for message in messages)
|
|
|
|
|
|
@pytest.mark.no_settings_dir_isolation
|
|
def test_explicit_settings_dir_env_used_by_manager(tmp_path, monkeypatch):
|
|
"""LORA_MANAGER_SETTINGS_DIR pins the settings file for the manager."""
|
|
custom_dir = tmp_path / "custom"
|
|
monkeypatch.setenv("LORA_MANAGER_SETTINGS_DIR", str(custom_dir))
|
|
reset_settings_manager()
|
|
|
|
manager = get_settings_manager()
|
|
|
|
assert settings_paths.is_settings_dir_pinned()
|
|
assert Path(manager.settings_file) == custom_dir / "settings.json"
|
|
assert settings_paths.get_settings_dir() == str(custom_dir)
|
|
|
|
|
|
def test_apply_settings_dir_from_argv():
|
|
"""standalone's argv pre-scan publishes --settings-path into the env."""
|
|
import standalone
|
|
|
|
# The helper writes to os.environ directly; manage the variable manually so
|
|
# monkeypatch's undo stack cannot restore a stale value after the test.
|
|
previous = os.environ.pop("LORA_MANAGER_SETTINGS_DIR", None)
|
|
try:
|
|
standalone._apply_settings_dir_from_argv(
|
|
["--port", "8199", "--settings-path", "/tmp/xyz-e2e-settings"]
|
|
)
|
|
assert os.environ["LORA_MANAGER_SETTINGS_DIR"] == "/tmp/xyz-e2e-settings"
|
|
|
|
os.environ.pop("LORA_MANAGER_SETTINGS_DIR", None)
|
|
standalone._apply_settings_dir_from_argv(["--settings-path=/tmp/abc-e2e"])
|
|
assert os.environ["LORA_MANAGER_SETTINGS_DIR"] == "/tmp/abc-e2e"
|
|
|
|
os.environ.pop("LORA_MANAGER_SETTINGS_DIR", None)
|
|
standalone._apply_settings_dir_from_argv(["--port", "8199"])
|
|
assert "LORA_MANAGER_SETTINGS_DIR" not in os.environ
|
|
finally:
|
|
if previous is None:
|
|
os.environ.pop("LORA_MANAGER_SETTINGS_DIR", None)
|
|
else:
|
|
os.environ["LORA_MANAGER_SETTINGS_DIR"] = previous
|