feat(system): resolve every library path in one place
utils/library_location.py decides where the library lives: the PROMPT_MANAGER_DATA_DIR folder (validated: absolute, never inside a folder ComfyUI or Prompt Manager serves), an explicit database.default_path as before, a node-folder library that was not moved, else ComfyUI's user/__promptmanager. The database, diagnostics, config.json, logs and the LoRA image cache all ask it, so a new install never writes into the node folder and an existing one keeps every path until the user moves it. "Keep it here" is persisted as library.keep_in_node_folder.
This commit is contained in:
@@ -0,0 +1,326 @@
|
||||
"""Where the library lives (#249 S6b): the one resolver, ``utils/library_location``.
|
||||
|
||||
Every case builds its own extension root (the node folder) and ComfyUI user
|
||||
folder in a temp directory and hands the resolver a fake ``folder_paths``, so
|
||||
no test reads the real environment, the repository's own files or ComfyUI.
|
||||
"""
|
||||
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import tempfile
|
||||
import types
|
||||
import unittest
|
||||
|
||||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
|
||||
from utils import library_location as ll # noqa: E402
|
||||
|
||||
|
||||
def _touch(path, data=b"x"):
|
||||
os.makedirs(os.path.dirname(path), exist_ok=True)
|
||||
with open(path, "wb") as handle:
|
||||
handle.write(data)
|
||||
|
||||
|
||||
def _folder_paths(base, *, helper=True):
|
||||
"""A ComfyUI ``folder_paths`` stand-in rooted at ``base``."""
|
||||
module = types.SimpleNamespace(base_path=base)
|
||||
for name in ("output", "input", "temp", "user"):
|
||||
directory = os.path.join(base, name)
|
||||
os.makedirs(directory, exist_ok=True)
|
||||
setattr(module, f"get_{name}_directory", lambda d=directory: d)
|
||||
if helper:
|
||||
module.get_system_user_directory = lambda name="system": os.path.join(
|
||||
base, "user", "__" + name
|
||||
)
|
||||
return module
|
||||
|
||||
|
||||
class _Case(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self._tmp = tempfile.TemporaryDirectory()
|
||||
self.addCleanup(self._tmp.cleanup)
|
||||
self.base = os.path.realpath(self._tmp.name)
|
||||
self.comfy = os.path.join(self.base, "ComfyUI")
|
||||
self.ext = os.path.join(self.comfy, "custom_nodes", "ComfyUI_PromptManager")
|
||||
os.makedirs(self.ext)
|
||||
self.fp = _folder_paths(self.comfy)
|
||||
self.default_dir = os.path.join(self.comfy, "user", "__promptmanager")
|
||||
ll.clear_override()
|
||||
self.addCleanup(ll.clear_override)
|
||||
|
||||
def resolve(self, default_path=None, environ=None, **kwargs):
|
||||
kwargs.setdefault("folder_paths", self.fp)
|
||||
return ll.resolve_library(
|
||||
default_path, environ=environ or {}, extension_root=self.ext, **kwargs
|
||||
)
|
||||
|
||||
def config_location(self, environ=None, **kwargs):
|
||||
kwargs.setdefault("folder_paths", self.fp)
|
||||
return ll.config_location(
|
||||
environ=environ or {}, extension_root=self.ext, **kwargs
|
||||
)
|
||||
|
||||
|
||||
class TestDefaultDataFolder(_Case):
|
||||
def test_uses_comfyui_system_user_helper(self):
|
||||
self.assertEqual(ll.default_data_dir(self.fp), self.default_dir)
|
||||
|
||||
def test_falls_back_to_user_directory_without_helper(self):
|
||||
fp = _folder_paths(self.comfy, helper=False)
|
||||
self.assertEqual(ll.default_data_dir(fp), self.default_dir)
|
||||
|
||||
def test_none_outside_comfyui(self):
|
||||
self.assertIsNone(ll.default_data_dir(None))
|
||||
self.assertIsNone(ll.default_data_dir(types.SimpleNamespace()))
|
||||
|
||||
|
||||
class TestResolutionOrder(_Case):
|
||||
def test_new_install_uses_default_folder_and_creates_nothing_in_node_folder(self):
|
||||
location = self.resolve()
|
||||
self.assertEqual(location.source, ll.SOURCE_DEFAULT)
|
||||
self.assertEqual(location.db_path, os.path.join(self.default_dir, "prompts.db"))
|
||||
self.assertEqual(
|
||||
location.config_path, os.path.join(self.default_dir, "config.json")
|
||||
)
|
||||
self.assertFalse(location.movable)
|
||||
self.assertEqual(os.listdir(self.ext), [])
|
||||
|
||||
def test_legacy_node_folder_library_stays_in_use(self):
|
||||
_touch(os.path.join(self.ext, "prompts.db"))
|
||||
location = self.resolve()
|
||||
self.assertEqual(location.source, ll.SOURCE_NODE_FOLDER)
|
||||
self.assertEqual(location.db_path, os.path.join(self.ext, "prompts.db"))
|
||||
self.assertEqual(location.config_path, os.path.join(self.ext, "config.json"))
|
||||
self.assertEqual(location.data_dir, self.ext)
|
||||
self.assertTrue(location.movable)
|
||||
self.assertEqual(location.target_dir, self.default_dir)
|
||||
|
||||
def test_legacy_wins_over_an_unmarked_default_folder_library(self):
|
||||
_touch(os.path.join(self.ext, "prompts.db"))
|
||||
_touch(os.path.join(self.default_dir, "prompts.db"))
|
||||
self.assertEqual(self.resolve().source, ll.SOURCE_NODE_FOLDER)
|
||||
|
||||
def test_explicit_default_path_is_honoured_as_today(self):
|
||||
_touch(os.path.join(self.ext, "prompts.db"))
|
||||
elsewhere = os.path.join(self.base, "elsewhere", "pm.db")
|
||||
location = self.resolve(elsewhere)
|
||||
self.assertEqual(location.source, ll.SOURCE_CONFIG)
|
||||
self.assertEqual(location.db_path, elsewhere)
|
||||
self.assertFalse(location.movable)
|
||||
relative = self.resolve("data/my.db")
|
||||
self.assertEqual(relative.db_path, os.path.join(self.ext, "data", "my.db"))
|
||||
self.assertEqual(relative.source, ll.SOURCE_CONFIG)
|
||||
|
||||
def test_default_setting_value_is_not_explicit(self):
|
||||
for value in (None, "", "prompts.db"):
|
||||
self.assertEqual(self.resolve(value).source, ll.SOURCE_DEFAULT, value)
|
||||
|
||||
def test_environment_folder_wins(self):
|
||||
data = os.path.join(self.base, "pm-data")
|
||||
location = self.resolve(environ={ll.DATA_DIR_ENV: data})
|
||||
self.assertEqual(location.source, ll.SOURCE_ENVIRONMENT)
|
||||
self.assertEqual(location.db_path, os.path.join(data, "prompts.db"))
|
||||
self.assertEqual(location.config_path, os.path.join(data, "config.json"))
|
||||
|
||||
def test_environment_folder_with_a_library_wins_over_legacy(self):
|
||||
data = os.path.join(self.base, "pm-data")
|
||||
_touch(os.path.join(data, "prompts.db"))
|
||||
_touch(os.path.join(self.ext, "prompts.db"))
|
||||
location = self.resolve(environ={ll.DATA_DIR_ENV: data})
|
||||
self.assertEqual(location.source, ll.SOURCE_ENVIRONMENT)
|
||||
|
||||
def test_empty_environment_folder_never_replaces_a_legacy_library(self):
|
||||
data = os.path.join(self.base, "pm-data")
|
||||
_touch(os.path.join(self.ext, "prompts.db"))
|
||||
location = self.resolve(environ={ll.DATA_DIR_ENV: data})
|
||||
self.assertEqual(location.source, ll.SOURCE_NODE_FOLDER)
|
||||
self.assertEqual(location.db_path, os.path.join(self.ext, "prompts.db"))
|
||||
self.assertEqual(location.problem, "data-dir-empty")
|
||||
self.assertEqual(location.target_dir, data)
|
||||
self.assertTrue(location.movable)
|
||||
|
||||
def test_config_path_environment_is_honoured(self):
|
||||
custom = os.path.join(self.base, "cfg", "custom.json")
|
||||
location = self.resolve(environ={ll.CONFIG_PATH_ENV: custom})
|
||||
self.assertEqual(location.config_path, custom)
|
||||
self.assertEqual(location.source, ll.SOURCE_DEFAULT)
|
||||
|
||||
def test_without_comfyui_the_node_folder_is_used(self):
|
||||
location = self.resolve(folder_paths=None)
|
||||
self.assertEqual(location.source, ll.SOURCE_NODE_FOLDER)
|
||||
self.assertEqual(location.db_path, os.path.join(self.ext, "prompts.db"))
|
||||
self.assertFalse(location.movable)
|
||||
|
||||
def test_override_after_a_live_move_wins(self):
|
||||
_touch(os.path.join(self.ext, "prompts.db"))
|
||||
moved = ll.LibraryLocation(
|
||||
source=ll.SOURCE_DEFAULT,
|
||||
db_path=os.path.join(self.default_dir, "prompts.db"),
|
||||
config_path=os.path.join(self.default_dir, "config.json"),
|
||||
data_dir=self.default_dir,
|
||||
target_dir=self.default_dir,
|
||||
)
|
||||
ll.switch_to(moved)
|
||||
self.assertEqual(self.resolve(), moved)
|
||||
self.assertEqual(self.config_location(), (moved.config_path, moved.data_dir))
|
||||
ll.clear_override()
|
||||
self.assertEqual(self.resolve().source, ll.SOURCE_NODE_FOLDER)
|
||||
|
||||
|
||||
class TestMarker(_Case):
|
||||
def _marker(self, directory, state):
|
||||
os.makedirs(directory, exist_ok=True)
|
||||
with open(os.path.join(directory, ll.MARKER_NAME), "w") as handle:
|
||||
json.dump({"version": 1, "state": state}, handle)
|
||||
|
||||
def test_moved_marker_wins_while_the_old_file_was_not_renamed_yet(self):
|
||||
_touch(os.path.join(self.ext, "prompts.db"))
|
||||
_touch(os.path.join(self.default_dir, "prompts.db"))
|
||||
self._marker(self.default_dir, "moved")
|
||||
location = self.resolve()
|
||||
self.assertEqual(location.source, ll.SOURCE_DEFAULT)
|
||||
self.assertEqual(location.db_path, os.path.join(self.default_dir, "prompts.db"))
|
||||
self.assertEqual(
|
||||
location.config_path, os.path.join(self.default_dir, "config.json")
|
||||
)
|
||||
|
||||
def test_pending_marker_keeps_the_old_library(self):
|
||||
_touch(os.path.join(self.ext, "prompts.db"))
|
||||
_touch(os.path.join(self.default_dir, "prompts.db"))
|
||||
self._marker(self.default_dir, "pending")
|
||||
self.assertEqual(self.resolve().source, ll.SOURCE_NODE_FOLDER)
|
||||
data = os.path.join(self.base, "pm-data")
|
||||
_touch(os.path.join(data, "prompts.db"))
|
||||
self._marker(data, "pending")
|
||||
location = self.resolve(environ={ll.DATA_DIR_ENV: data})
|
||||
self.assertEqual(location.source, ll.SOURCE_NODE_FOLDER)
|
||||
self.assertEqual(location.problem, "move-unfinished")
|
||||
|
||||
def test_unreadable_marker_is_not_trusted(self):
|
||||
_touch(os.path.join(self.ext, "prompts.db"))
|
||||
_touch(os.path.join(self.default_dir, "prompts.db"))
|
||||
_touch(os.path.join(self.default_dir, ll.MARKER_NAME), b"{not json")
|
||||
self.assertEqual(self.resolve().source, ll.SOURCE_NODE_FOLDER)
|
||||
self.assertEqual(ll.read_marker(self.default_dir), {})
|
||||
|
||||
def test_renamed_old_file_is_never_picked(self):
|
||||
_touch(os.path.join(self.ext, "prompts.db.moved-to-__promptmanager"))
|
||||
_touch(os.path.join(self.default_dir, "prompts.db"))
|
||||
self.assertEqual(self.resolve().source, ll.SOURCE_DEFAULT)
|
||||
|
||||
|
||||
class TestConfigLocation(_Case):
|
||||
def test_legacy_config_without_a_database_keeps_being_read(self):
|
||||
_touch(os.path.join(self.ext, "config.json"), b"{}")
|
||||
path, data_dir = self.config_location()
|
||||
self.assertEqual(path, os.path.join(self.ext, "config.json"))
|
||||
self.assertEqual(data_dir, self.ext)
|
||||
|
||||
def test_legacy_config_alone_never_puts_a_new_database_in_the_node_folder(self):
|
||||
_touch(os.path.join(self.ext, "config.json"), b"{}")
|
||||
location = self.resolve()
|
||||
self.assertEqual(location.db_path, os.path.join(self.default_dir, "prompts.db"))
|
||||
self.assertEqual(location.config_path, os.path.join(self.ext, "config.json"))
|
||||
self.assertFalse(location.movable)
|
||||
|
||||
def test_new_install_reads_config_from_the_data_folder(self):
|
||||
path, data_dir = self.config_location()
|
||||
self.assertEqual(path, os.path.join(self.default_dir, "config.json"))
|
||||
self.assertEqual(data_dir, self.default_dir)
|
||||
|
||||
def test_logs_and_cache_follow_the_data_folder(self):
|
||||
self.assertEqual(
|
||||
ll.logs_dir(environ={}, extension_root=self.ext, folder_paths=self.fp),
|
||||
os.path.join(self.default_dir, "logs"),
|
||||
)
|
||||
_touch(os.path.join(self.ext, "prompts.db"))
|
||||
self.assertEqual(
|
||||
ll.logs_dir(environ={}, extension_root=self.ext, folder_paths=self.fp),
|
||||
os.path.join(self.ext, "logs"),
|
||||
)
|
||||
self.assertEqual(
|
||||
ll.cache_dir(
|
||||
"lora_images", environ={}, extension_root=self.ext, folder_paths=self.fp
|
||||
),
|
||||
os.path.join(self.ext, "data", "lora_images"),
|
||||
)
|
||||
|
||||
|
||||
class TestDataDirValidation(_Case):
|
||||
def problem(self, path, **kwargs):
|
||||
kwargs.setdefault("folder_paths", self.fp)
|
||||
return ll.data_dir_problem(path, **kwargs)
|
||||
|
||||
def test_valid_folder(self):
|
||||
self.assertIsNone(self.problem(os.path.join(self.base, "pm-data")))
|
||||
self.assertIsNone(self.problem(self.default_dir))
|
||||
|
||||
def test_relative_and_empty_paths_are_refused(self):
|
||||
self.assertEqual(self.problem("pm-data"), "data-dir-not-absolute")
|
||||
self.assertEqual(self.problem(""), "data-dir-not-absolute")
|
||||
|
||||
def test_served_folders_are_refused(self):
|
||||
for name in ("output", "input", "temp"):
|
||||
inside = os.path.join(self.comfy, name, "pm")
|
||||
self.assertEqual(self.problem(inside), "data-dir-served", name)
|
||||
self.assertEqual(
|
||||
self.problem(os.path.join(self.comfy, "output")), "data-dir-served"
|
||||
)
|
||||
|
||||
def test_public_user_folder_is_refused_but_system_users_are_fine(self):
|
||||
public = os.path.join(self.comfy, "user", "default", "pm")
|
||||
self.assertEqual(self.problem(public), "data-dir-served")
|
||||
self.assertIsNone(self.problem(os.path.join(self.comfy, "user", "__pm")))
|
||||
|
||||
def test_gallery_source_is_refused(self):
|
||||
source = os.path.join(self.base, "gallery")
|
||||
os.makedirs(source)
|
||||
self.assertEqual(
|
||||
self.problem(os.path.join(source, "pm"), gallery_roots=[source]),
|
||||
"data-dir-served",
|
||||
)
|
||||
self.assertEqual(
|
||||
self.problem(
|
||||
os.path.join(source, "pm"),
|
||||
environ={ll.EXTRA_GALLERY_ROOTS_ENV: source},
|
||||
),
|
||||
"data-dir-served",
|
||||
)
|
||||
|
||||
def test_symlink_into_output_is_refused(self):
|
||||
link = os.path.join(self.base, "link-to-output")
|
||||
try:
|
||||
os.symlink(os.path.join(self.comfy, "output"), link)
|
||||
except (OSError, NotImplementedError):
|
||||
self.skipTest("symlinks are not available")
|
||||
self.assertEqual(self.problem(os.path.join(link, "pm")), "data-dir-served")
|
||||
|
||||
def test_case_variant_spelling_of_output_is_refused_where_the_volume_folds_case(
|
||||
self,
|
||||
):
|
||||
upper = os.path.join(self.comfy, "OUTPUT")
|
||||
if not os.path.isdir(upper):
|
||||
self.skipTest("this volume is case-sensitive")
|
||||
self.assertEqual(self.problem(os.path.join(upper, "pm")), "data-dir-served")
|
||||
|
||||
def test_invalid_environment_folder_is_ignored_with_a_problem(self):
|
||||
inside = os.path.join(self.comfy, "output", "pm")
|
||||
location = self.resolve(environ={ll.DATA_DIR_ENV: inside})
|
||||
self.assertEqual(location.source, ll.SOURCE_DEFAULT)
|
||||
self.assertEqual(location.problem, "data-dir-served")
|
||||
self.assertFalse(os.path.exists(inside))
|
||||
relative = self.resolve(environ={ll.DATA_DIR_ENV: "relative/dir"})
|
||||
self.assertEqual(relative.problem, "data-dir-not-absolute")
|
||||
|
||||
|
||||
class TestSameFolder(_Case):
|
||||
def test_same_folder_follows_links_and_case(self):
|
||||
self.assertTrue(ll.same_folder(self.ext, self.ext + os.sep))
|
||||
self.assertFalse(ll.same_folder(self.ext, self.default_dir))
|
||||
self.assertFalse(ll.same_folder(self.ext, os.path.join(self.base, "missing")))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -0,0 +1,169 @@
|
||||
"""Every data path asks the one resolver (#249 S6b).
|
||||
|
||||
The database, the diagnostics database, config.json, the logs and the LoRA
|
||||
image cache all follow ``utils.library_location``: a folder named by
|
||||
``PROMPT_MANAGER_DATA_DIR`` (and, after a live move, the switched location).
|
||||
"""
|
||||
|
||||
import os
|
||||
import pathlib
|
||||
import sys
|
||||
import tempfile
|
||||
import types
|
||||
import unittest
|
||||
import unittest.mock as mock
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
_mock_server = MagicMock()
|
||||
_mock_server.PromptServer.instance.routes = MagicMock()
|
||||
sys.modules.setdefault("server", _mock_server)
|
||||
|
||||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
|
||||
from utils import library_location as ll # noqa: E402
|
||||
|
||||
|
||||
class _EnvCase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self._tmp = tempfile.TemporaryDirectory()
|
||||
self.addCleanup(self._tmp.cleanup)
|
||||
base = os.path.realpath(self._tmp.name)
|
||||
self.data = os.path.join(base, "pm-data")
|
||||
patcher = mock.patch.dict(
|
||||
os.environ,
|
||||
{ll.DATA_DIR_ENV: self.data, ll.CONFIG_PATH_ENV: ""},
|
||||
)
|
||||
patcher.start()
|
||||
self.addCleanup(patcher.stop)
|
||||
# This test's own ComfyUI folders (the shared stub serves the system
|
||||
# temp folder as "output", which would rightly refuse self.data).
|
||||
comfy = os.path.join(base, "ComfyUI")
|
||||
fp = types.ModuleType("folder_paths")
|
||||
for name in ("output", "input", "temp", "user"):
|
||||
setattr(fp, f"get_{name}_directory", lambda n=name: os.path.join(comfy, n))
|
||||
modules = mock.patch.dict(sys.modules, {"folder_paths": fp})
|
||||
modules.start()
|
||||
self.addCleanup(modules.stop)
|
||||
ll.clear_override()
|
||||
self.addCleanup(ll.clear_override)
|
||||
|
||||
|
||||
class TestDatabasePath(_EnvCase):
|
||||
def test_database_follows_the_data_folder(self):
|
||||
from database.operations import _resolve_db_path
|
||||
|
||||
with mock.patch.dict(sys.modules, {"py.config": None}):
|
||||
path = _resolve_db_path(None)
|
||||
self.assertEqual(path, os.path.join(self.data, "prompts.db"))
|
||||
self.assertTrue(os.path.isdir(self.data))
|
||||
if os.name == "posix":
|
||||
self.assertEqual(os.stat(self.data).st_mode & 0o777, 0o700)
|
||||
|
||||
def test_diagnostics_use_the_same_resolver(self):
|
||||
from database.operations import _resolve_db_path
|
||||
from utils.diagnostics import GalleryDiagnostics
|
||||
|
||||
with mock.patch.dict(sys.modules, {"py.config": None}):
|
||||
self.assertEqual(GalleryDiagnostics._resolve_db_path(), _resolve_db_path())
|
||||
|
||||
def test_switched_location_wins(self):
|
||||
from database.operations import _resolve_db_path
|
||||
|
||||
moved = ll.LibraryLocation(
|
||||
ll.SOURCE_DEFAULT,
|
||||
os.path.join(self.data, "moved", "prompts.db"),
|
||||
os.path.join(self.data, "moved", "config.json"),
|
||||
os.path.join(self.data, "moved"),
|
||||
)
|
||||
ll.switch_to(moved)
|
||||
self.assertEqual(_resolve_db_path(None), moved.db_path)
|
||||
|
||||
|
||||
class TestConfigPath(_EnvCase):
|
||||
def test_config_json_follows_the_data_folder(self):
|
||||
from py.config import PromptManagerConfig
|
||||
|
||||
self.assertEqual(
|
||||
PromptManagerConfig.get_config_path(),
|
||||
os.path.join(self.data, "config.json"),
|
||||
)
|
||||
|
||||
def test_explicit_config_path_still_wins(self):
|
||||
from py.config import PromptManagerConfig
|
||||
|
||||
custom = os.path.join(self.data, "elsewhere.json")
|
||||
with mock.patch.dict(os.environ, {ll.CONFIG_PATH_ENV: custom}):
|
||||
self.assertEqual(PromptManagerConfig.get_config_path(), custom)
|
||||
|
||||
def test_keep_choice_round_trips(self):
|
||||
from py.config import PromptManagerConfig
|
||||
|
||||
original = PromptManagerConfig.KEEP_LIBRARY_IN_NODE_FOLDER
|
||||
self.addCleanup(
|
||||
setattr, PromptManagerConfig, "KEEP_LIBRARY_IN_NODE_FOLDER", original
|
||||
)
|
||||
PromptManagerConfig.update_config({"library": {"keep_in_node_folder": True}})
|
||||
self.assertTrue(PromptManagerConfig.KEEP_LIBRARY_IN_NODE_FOLDER)
|
||||
self.assertEqual(
|
||||
PromptManagerConfig.get_config()["library"], {"keep_in_node_folder": True}
|
||||
)
|
||||
PromptManagerConfig.update_config({"library": {"keep_in_node_folder": "yes"}})
|
||||
self.assertTrue(PromptManagerConfig.KEEP_LIBRARY_IN_NODE_FOLDER)
|
||||
|
||||
|
||||
class TestLogsAndCache(_EnvCase):
|
||||
def test_logs_go_to_the_data_folder(self):
|
||||
from utils import logging_config
|
||||
from utils.logging_config import PromptManagerLogger
|
||||
|
||||
manager = object.__new__(PromptManagerLogger)
|
||||
self.addCleanup(self._close, manager)
|
||||
manager.__init__()
|
||||
self.assertEqual(manager.log_dir, pathlib.Path(self.data, "logs"))
|
||||
self.assertTrue(manager.log_dir.is_dir())
|
||||
self.assertIs(logging_config.library_location, ll)
|
||||
|
||||
@staticmethod
|
||||
def _close(manager):
|
||||
import logging
|
||||
|
||||
for handler in logging.getLogger("prompt_manager").handlers[:]:
|
||||
if getattr(handler, "_prompt_manager_owned", False):
|
||||
handler.close()
|
||||
try:
|
||||
from utils.logging_config import get_logger_manager
|
||||
|
||||
get_logger_manager()._setup_loggers()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def test_lora_image_cache_follows_the_data_folder(self):
|
||||
from py import lora_utils
|
||||
|
||||
cache = lora_utils.get_lora_image_cache_dir()
|
||||
self.assertEqual(cache, pathlib.Path(self.data, "data", "lora_images"))
|
||||
|
||||
|
||||
class TestNodeFolderUnchangedForLegacyInstalls(unittest.TestCase):
|
||||
"""A node folder that holds the library keeps every path where it was."""
|
||||
|
||||
def test_legacy_paths(self):
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
ext = os.path.join(tmp, "ext")
|
||||
os.makedirs(ext)
|
||||
open(os.path.join(ext, "prompts.db"), "wb").close()
|
||||
fp = types.SimpleNamespace(
|
||||
get_user_directory=lambda: os.path.join(tmp, "u")
|
||||
)
|
||||
location = ll.resolve_library(
|
||||
None, environ={}, extension_root=ext, folder_paths=fp
|
||||
)
|
||||
self.assertEqual(location.db_path, os.path.join(ext, "prompts.db"))
|
||||
self.assertEqual(
|
||||
ll.logs_dir(environ={}, extension_root=ext, folder_paths=fp),
|
||||
os.path.join(ext, "logs"),
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user