Merge pull request #1131 from willmiao/fix/sidecar-root-identity

fix(sidecars): keep mirrored sidecars when a model root moves
This commit is contained in:
pixelpaws
2026-09-29 09:45:41 +08:00
committed by GitHub
18 changed files with 1450 additions and 65 deletions
+103
View File
@@ -12,6 +12,7 @@ import pytest
from aiohttp import web
from py.services.model_hash_index import ModelHashIndex
from py.routes.handlers import misc_handlers
from py.routes.handlers.misc_handlers import (
BackupHandler,
DoctorHandler,
@@ -209,6 +210,108 @@ async def test_doctor_handler_reports_key_cache_and_ui_issues():
assert diagnostic_map["ui_version"]["status"] == "warning"
@pytest.mark.asyncio
async def test_doctor_handler_flags_orphaned_centralized_sidecars(
monkeypatch: pytest.MonkeyPatch,
):
async def civitai_factory():
return DummyCivitaiClient()
handler = DoctorHandler(
settings_service=DummySettings({"civitai_api_key": "token"}),
civitai_client_factory=civitai_factory,
scanner_factories=(),
)
monkeypatch.setattr(misc_handlers, "get_storage_mode", lambda: "centralized")
monkeypatch.setattr(
misc_handlers,
"get_unmatched_sidecar_components",
lambda: [
{
"component": "loras-abc12345",
"basename": "loras",
"last_path": "/mnt/old/loras",
},
{"component": "loras-def67890", "basename": "loras", "last_path": ""},
],
)
response = await handler.get_doctor_diagnostics(
FakeRequest(method="GET") # pyright: ignore[reportArgumentType]
)
payload = _json_payload(response)
item = {entry["id"]: entry for entry in payload["diagnostics"]}[
"sidecar_mirror_orphans"
]
assert item["status"] == "warning"
assert "2 sidecar directories" in item["summary"]
assert any("/mnt/old/loras" in line for line in item["details"])
assert any("unknown" in line for line in item["details"])
@pytest.mark.asyncio
async def test_doctor_handler_sidecar_check_ok_when_all_linked(
monkeypatch: pytest.MonkeyPatch,
):
async def civitai_factory():
return DummyCivitaiClient()
handler = DoctorHandler(
settings_service=DummySettings({"civitai_api_key": "token"}),
civitai_client_factory=civitai_factory,
scanner_factories=(),
)
monkeypatch.setattr(misc_handlers, "get_storage_mode", lambda: "centralized")
monkeypatch.setattr(misc_handlers, "get_unmatched_sidecar_components", lambda: [])
monkeypatch.setattr(
misc_handlers, "describe_sidecar_root", lambda: {"root": "/sidecars"}
)
response = await handler.get_doctor_diagnostics(
FakeRequest(method="GET") # pyright: ignore[reportArgumentType]
)
payload = _json_payload(response)
item = {entry["id"]: entry for entry in payload["diagnostics"]}[
"sidecar_mirror_orphans"
]
assert item["status"] == "ok"
@pytest.mark.asyncio
async def test_doctor_handler_sidecar_check_skipped_alongside(
monkeypatch: pytest.MonkeyPatch,
):
async def civitai_factory():
return DummyCivitaiClient()
handler = DoctorHandler(
settings_service=DummySettings({"civitai_api_key": "token"}),
civitai_client_factory=civitai_factory,
scanner_factories=(),
)
monkeypatch.setattr(misc_handlers, "get_storage_mode", lambda: "alongside")
def _unexpected():
raise AssertionError("orphan lookup must not run in alongside mode")
monkeypatch.setattr(
misc_handlers, "get_unmatched_sidecar_components", _unexpected
)
response = await handler.get_doctor_diagnostics(
FakeRequest(method="GET") # pyright: ignore[reportArgumentType]
)
payload = _json_payload(response)
item = {entry["id"]: entry for entry in payload["diagnostics"]}[
"sidecar_mirror_orphans"
]
assert item["status"] == "ok"
assert "alongside" in item["summary"]
@pytest.mark.asyncio
async def test_doctor_handler_can_repair_cache():
scanner = DummyDoctorScanner(model_type="lora", raw_data=[])