diff --git a/supervisor/resolution/fixups/store_execute_reset.py b/supervisor/resolution/fixups/store_execute_reset.py index c65bee95e..167b29679 100644 --- a/supervisor/resolution/fixups/store_execute_reset.py +++ b/supervisor/resolution/fixups/store_execute_reset.py @@ -42,13 +42,8 @@ class FixupStoreExecuteReset(FixupBase): _LOGGER.warning("Can't find store %s for fixup", reference) return - # Local add-ons are not a git repo, can't remove and re-pull try: - if repository.git: - await repository.git.reset() - - # Load data again - await repository.load() + await repository.reset() except StoreError: raise ResolutionFixupError() from None diff --git a/supervisor/store/__init__.py b/supervisor/store/__init__.py index 9f1e2b12f..3b7d81541 100644 --- a/supervisor/store/__init__.py +++ b/supervisor/store/__init__.py @@ -135,7 +135,7 @@ class StoreManager(CoreSysAttributes, FileConfiguration): if url == URL_HASSIO_ADDONS: url = StoreType.CORE - repository = Repository(self.coresys, url) + repository = Repository.create(self.coresys, url) if repository.slug in self.repositories: raise StoreError(f"Can't add {url}, already in the store", _LOGGER.error) @@ -183,7 +183,7 @@ class StoreManager(CoreSysAttributes, FileConfiguration): raise err else: - if not await self.sys_run_in_executor(repository.validate): + if not await repository.validate(): if add_with_errors: _LOGGER.error("%s is not a valid add-on repository", url) self.sys_resolution.create_issue( diff --git a/supervisor/store/git.py b/supervisor/store/git.py index 9e25da927..474a4a5fa 100644 --- a/supervisor/store/git.py +++ b/supervisor/store/git.py @@ -1,6 +1,5 @@ """Init file for Supervisor add-on Git.""" -from abc import ABC, abstractmethod import asyncio import errno import functools as ft @@ -16,17 +15,14 @@ from ..exceptions import StoreGitCloneError, StoreGitError, StoreJobError from ..jobs.decorator import Job, JobCondition from ..resolution.const import ContextType, IssueType, SuggestionType, UnhealthyReason from ..utils import remove_folder -from .utils import get_hash_from_repository -from .validate import RE_REPOSITORY, BuiltinRepository +from .validate import RE_REPOSITORY _LOGGER: logging.Logger = logging.getLogger(__name__) -class GitRepo(CoreSysAttributes, ABC): +class GitRepo(CoreSysAttributes): """Manage Add-on Git repository.""" - builtin: bool - def __init__(self, coresys: CoreSys, path: Path, url: str): """Initialize Git base wrapper.""" self.coresys: CoreSys = coresys @@ -239,38 +235,8 @@ class GitRepo(CoreSysAttributes, ABC): ) raise StoreGitError() from err - @abstractmethod async def remove(self) -> None: """Remove a repository.""" - - -class GitRepoBuiltin(GitRepo): - """Built-in add-ons repository.""" - - builtin: bool = True - - def __init__(self, coresys: CoreSys, repository: BuiltinRepository): - """Initialize Git Supervisor add-on repository.""" - super().__init__(coresys, repository.get_path(coresys), repository.url) - - async def remove(self) -> None: - """Raise. Cannot remove built-in repositories.""" - raise RuntimeError("Cannot remove built-in repositories!") - - -class GitRepoCustom(GitRepo): - """Custom add-ons repository.""" - - builtin: bool = False - - def __init__(self, coresys, url): - """Initialize custom Git Supervisor addo-n repository.""" - path = Path(coresys.config.path_addons_git, get_hash_from_repository(url)) - - super().__init__(coresys, path, url) - - async def remove(self) -> None: - """Remove a custom repository.""" if self.lock.locked(): _LOGGER.warning( "Cannot remove add-on repository %s, there is already a task in progress", diff --git a/supervisor/store/repository.py b/supervisor/store/repository.py index 0752f4f0b..5f873297f 100644 --- a/supervisor/store/repository.py +++ b/supervisor/store/repository.py @@ -1,5 +1,8 @@ """Represent a Supervisor repository.""" +from __future__ import annotations + +from abc import ABC, abstractmethod import logging from pathlib import Path @@ -12,7 +15,7 @@ from ..coresys import CoreSys, CoreSysAttributes from ..exceptions import ConfigurationFileError, StoreError from ..utils.common import read_json_or_yaml_file from .const import StoreType -from .git import GitRepo, GitRepoBuiltin, GitRepoCustom +from .git import GitRepo from .utils import get_hash_from_repository from .validate import SCHEMA_REPOSITORY_CONFIG, BuiltinRepository @@ -20,28 +23,24 @@ _LOGGER: logging.Logger = logging.getLogger(__name__) UNKNOWN = "unknown" -class Repository(CoreSysAttributes): +class Repository(CoreSysAttributes, ABC): """Add-on store repository in Supervisor.""" def __init__(self, coresys: CoreSys, repository: str): """Initialize add-on store repository object.""" + self._slug: str + self._type: StoreType self.coresys: CoreSys = coresys - self.git: GitRepo | None = None - self.source: str = repository + + @staticmethod + def create(coresys: CoreSys, repository: str) -> Repository: + """Create a repository instance.""" if repository == StoreType.LOCAL: - self._slug = repository - self._type = StoreType.LOCAL - self._latest_mtime: float | None = None - elif repository in BuiltinRepository: - builtin = BuiltinRepository(repository) - self.git = GitRepoBuiltin(coresys, builtin) - self._slug = builtin.id - self._type = builtin.type - else: - self.git = GitRepoCustom(coresys, repository) - self._slug = get_hash_from_repository(repository) - self._type = StoreType.GIT + return RepositoryLocal(coresys) + if repository in BuiltinRepository: + return RepositoryGitBuiltin(coresys, BuiltinRepository(repository)) + return RepositoryCustom(coresys, repository) def __repr__(self) -> str: """Return internal representation.""" @@ -77,52 +76,117 @@ class Repository(CoreSysAttributes): """Return url of repository.""" return self.data.get(ATTR_MAINTAINER, UNKNOWN) - def validate(self) -> bool: - """Check if store is valid. + @abstractmethod + async def validate(self) -> bool: + """Check if store is valid.""" - Must be run in executor. + @abstractmethod + async def load(self) -> None: + """Load addon repository.""" + + @abstractmethod + async def update(self) -> bool: + """Update add-on repository. + + Returns True if the repository was updated. """ - if not self.git or self.type == StoreType.CORE: - return True - # If exists? - for filetype in FILE_SUFFIX_CONFIGURATION: - repository_file = Path(self.git.path / f"repository{filetype}") - if repository_file.exists(): - break + @abstractmethod + async def remove(self) -> None: + """Remove add-on repository.""" - if not repository_file.exists(): - return False + @abstractmethod + async def reset(self) -> None: + """Reset add-on repository to fix corruption issue with files.""" - # If valid? - try: - SCHEMA_REPOSITORY_CONFIG(read_json_or_yaml_file(repository_file)) - except (ConfigurationFileError, vol.Invalid) as err: - _LOGGER.warning("Could not validate repository configuration %s", err) - return False +class RepositoryBuiltin(Repository, ABC): + """A built-in add-on repository.""" + + def __init__(self, coresys: CoreSys, builtin: BuiltinRepository) -> None: + """Initialize object.""" + super().__init__(coresys, builtin.value) + self._builtin = builtin + self._slug = builtin.id + self._type = builtin.type + + async def validate(self) -> bool: + """Assume built-in repositories are always valid.""" return True + async def remove(self) -> None: + """Raise. Not supported for built-in repositories.""" + raise StoreError("Can't remove built-in repositories!", _LOGGER.error) + + +class RepositoryGit(Repository, ABC): + """A git based add-on repository.""" + + _git: GitRepo + async def load(self) -> None: """Load addon repository.""" - if not self.git: - self._latest_mtime, _ = await self.sys_run_in_executor( - get_latest_mtime, self.sys_config.path_addons_local - ) - return - await self.git.load() + await self._git.load() async def update(self) -> bool: """Update add-on repository. Returns True if the repository was updated. """ - if not await self.sys_run_in_executor(self.validate): + if not await self.validate(): return False - if self.git: - return await self.git.pull() + return await self._git.pull() + async def validate(self) -> bool: + """Check if store is valid.""" + + def validate_file() -> bool: + # If exists? + for filetype in FILE_SUFFIX_CONFIGURATION: + repository_file = Path(self._git.path / f"repository{filetype}") + if repository_file.exists(): + break + + if not repository_file.exists(): + return False + + # If valid? + try: + SCHEMA_REPOSITORY_CONFIG(read_json_or_yaml_file(repository_file)) + except (ConfigurationFileError, vol.Invalid) as err: + _LOGGER.warning("Could not validate repository configuration %s", err) + return False + + return True + + return await self.sys_run_in_executor(validate_file) + + async def reset(self) -> None: + """Reset add-on repository to fix corruption issue with files.""" + await self._git.reset() + await self.load() + + +class RepositoryLocal(RepositoryBuiltin): + """A local add-on repository.""" + + def __init__(self, coresys: CoreSys) -> None: + """Initialize object.""" + super().__init__(coresys, BuiltinRepository.LOCAL) + self._latest_mtime: float | None = None + + async def load(self) -> None: + """Load addon repository.""" + self._latest_mtime, _ = await self.sys_run_in_executor( + get_latest_mtime, self.sys_config.path_addons_local + ) + + async def update(self) -> bool: + """Update add-on repository. + + Returns True if the repository was updated. + """ # Check local modifications latest_mtime, modified_path = await self.sys_run_in_executor( get_latest_mtime, self.sys_config.path_addons_local @@ -138,9 +202,32 @@ class Repository(CoreSysAttributes): return False + async def reset(self) -> None: + """Raise. Not supported for local repository.""" + raise StoreError( + "Can't reset local repository as it is not git based!", _LOGGER.error + ) + + +class RepositoryGitBuiltin(RepositoryBuiltin, RepositoryGit): + """A built-in add-on repository based on git.""" + + def __init__(self, coresys: CoreSys, builtin: BuiltinRepository) -> None: + """Initialize object.""" + super().__init__(coresys, builtin) + self._git = GitRepo(coresys, builtin.get_path(coresys), builtin.url) + + +class RepositoryCustom(RepositoryGit): + """A custom add-on repository.""" + + def __init__(self, coresys: CoreSys, url: str) -> None: + """Initialize object.""" + super().__init__(coresys, url) + self._slug = get_hash_from_repository(url) + self._type = StoreType.GIT + self._git = GitRepo(coresys, coresys.config.path_addons_git / self._slug, url) + async def remove(self) -> None: """Remove add-on repository.""" - if not self.git or self.git.builtin: - raise StoreError("Can't remove built-in repositories!", _LOGGER.error) - - await self.git.remove() + await self._git.remove() diff --git a/tests/addons/test_addon.py b/tests/addons/test_addon.py index 1d06bc1aa..e8fd4365d 100644 --- a/tests/addons/test_addon.py +++ b/tests/addons/test_addon.py @@ -820,7 +820,7 @@ async def test_paths_cache(coresys: CoreSys, install_addon_ssh: Addon): with ( patch("supervisor.addons.addon.Path.exists", return_value=True), - patch("supervisor.store.repository.Repository.update", return_value=True), + patch("supervisor.store.repository.RepositoryLocal.update", return_value=True), ): await coresys.store.reload(coresys.store.get("local")) diff --git a/tests/addons/test_manager.py b/tests/addons/test_manager.py index 2c026c1f4..1590fe3fe 100644 --- a/tests/addons/test_manager.py +++ b/tests/addons/test_manager.py @@ -29,7 +29,7 @@ from supervisor.plugins.dns import PluginDns from supervisor.resolution.const import ContextType, IssueType, SuggestionType from supervisor.resolution.data import Issue, Suggestion from supervisor.store.addon import AddonStore -from supervisor.store.repository import Repository +from supervisor.store.repository import RepositoryLocal from supervisor.utils import check_exception_chain from supervisor.utils.common import write_json_file @@ -442,7 +442,7 @@ async def test_store_data_changes_during_update( update_task = coresys.create_task(simulate_update()) await asyncio.sleep(0) - with patch.object(Repository, "update", return_value=True): + with patch.object(RepositoryLocal, "update", return_value=True): await coresys.store.reload() assert "image" not in coresys.store.data.addons["local_ssh"] diff --git a/tests/api/test_store.py b/tests/api/test_store.py index df327d44b..1f82e96b3 100644 --- a/tests/api/test_store.py +++ b/tests/api/test_store.py @@ -97,8 +97,8 @@ async def test_api_store_add_repository( ) -> None: """Test POST /store/repositories REST API.""" with ( - patch("supervisor.store.repository.Repository.load", return_value=None), - patch("supervisor.store.repository.Repository.validate", return_value=True), + patch("supervisor.store.repository.RepositoryGit.load", return_value=None), + patch("supervisor.store.repository.RepositoryGit.validate", return_value=True), ): response = await api_client.post( "/store/repositories", json={"repository": REPO_URL} diff --git a/tests/api/test_supervisor.py b/tests/api/test_supervisor.py index 07032d88b..c24fdaf72 100644 --- a/tests/api/test_supervisor.py +++ b/tests/api/test_supervisor.py @@ -42,8 +42,8 @@ async def test_api_supervisor_options_add_repository( coresys.store.get_from_url(REPO_URL) with ( - patch("supervisor.store.repository.Repository.load", return_value=None), - patch("supervisor.store.repository.Repository.validate", return_value=True), + patch("supervisor.store.repository.RepositoryGit.load", return_value=None), + patch("supervisor.store.repository.RepositoryGit.validate", return_value=True), ): response = await api_client.post( "/supervisor/options", json={"addons_repositories": [REPO_URL]} @@ -76,9 +76,9 @@ async def test_api_supervisor_options_repositories_skipped_on_error( ): """Test repositories skipped on error via POST /supervisor/options REST API.""" with ( - patch("supervisor.store.repository.Repository.load", side_effect=git_error), - patch("supervisor.store.repository.Repository.validate", return_value=False), - patch("supervisor.store.repository.Repository.remove"), + patch("supervisor.store.repository.RepositoryGit.load", side_effect=git_error), + patch("supervisor.store.repository.RepositoryGit.validate", return_value=False), + patch("supervisor.store.repository.RepositoryCustom.remove"), ): response = await api_client.post( "/supervisor/options", json={"addons_repositories": [REPO_URL]} @@ -98,7 +98,7 @@ async def test_api_supervisor_options_repo_error_with_config_change( assert not coresys.config.debug with patch( - "supervisor.store.repository.Repository.load", side_effect=StoreGitError() + "supervisor.store.repository.RepositoryGit.load", side_effect=StoreGitError() ): response = await api_client.post( "/supervisor/options", diff --git a/tests/conftest.py b/tests/conftest.py index e9fd01deb..bcbd5f27d 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -409,7 +409,7 @@ async def coresys( coresys_obj.init_websession = AsyncMock() # Don't remove files/folders related to addons and stores - with patch("supervisor.store.git.GitRepoCustom.remove"): + with patch("supervisor.store.git.GitRepo.remove"): yield coresys_obj await coresys_obj.dbus.unload() @@ -611,7 +611,7 @@ async def repository(coresys: CoreSys): ): await coresys.store.load() - repository_obj = Repository( + repository_obj = Repository.create( coresys, "https://github.com/awesome-developer/awesome-repo" ) diff --git a/tests/resolution/fixup/test_store_execute_reset.py b/tests/resolution/fixup/test_store_execute_reset.py index 361fa9d04..d2eafa709 100644 --- a/tests/resolution/fixup/test_store_execute_reset.py +++ b/tests/resolution/fixup/test_store_execute_reset.py @@ -67,7 +67,7 @@ async def test_fixup(coresys: CoreSys): path = path or obj.path await coresys.run_in_executor((path / ".git").mkdir) - coresys.store.repositories["94cfad5a"] = Repository( + coresys.store.repositories["94cfad5a"] = Repository.create( coresys, "https://github.com/home-assistant/addons-example" ) with ( @@ -97,7 +97,7 @@ async def test_fixup_clone_fail(coresys: CoreSys): assert test_repo.exists() assert corrupt_marker.exists() - coresys.store.repositories["94cfad5a"] = Repository( + coresys.store.repositories["94cfad5a"] = Repository.create( coresys, "https://github.com/home-assistant/addons-example" ) with ( @@ -129,7 +129,7 @@ async def test_fixup_move_fail(coresys: CoreSys, error_num: int, unhealthy: bool add_store_reset_suggestion(coresys) test_repo.mkdir(parents=True) - coresys.store.repositories["94cfad5a"] = Repository( + coresys.store.repositories["94cfad5a"] = Repository.create( coresys, "https://github.com/home-assistant/addons-example" ) with ( diff --git a/tests/store/test_custom_repository.py b/tests/store/test_custom_repository.py index cdabd2210..d94a527e5 100644 --- a/tests/store/test_custom_repository.py +++ b/tests/store/test_custom_repository.py @@ -33,7 +33,7 @@ async def test_add_valid_repository( """Test add custom repository.""" current = coresys.store.repository_urls with ( - patch("supervisor.store.repository.Repository.load", return_value=None), + patch("supervisor.store.repository.RepositoryGit.load", return_value=None), patch( "supervisor.utils.common.read_yaml_file", return_value={"name": "Awesome repository"}, @@ -54,7 +54,7 @@ async def test_add_invalid_repository(coresys: CoreSys, store_manager: StoreMana """Test add invalid custom repository.""" current = coresys.store.repository_urls with ( - patch("supervisor.store.repository.Repository.load", return_value=None), + patch("supervisor.store.repository.RepositoryGit.load", return_value=None), patch( "pathlib.Path.read_text", return_value="", @@ -64,9 +64,7 @@ async def test_add_invalid_repository(coresys: CoreSys, store_manager: StoreMana current + ["http://example.com"], add_with_errors=True ) - assert not await coresys.run_in_executor( - store_manager.get_from_url("http://example.com").validate - ) + assert not await store_manager.get_from_url("http://example.com").validate() assert "http://example.com" in coresys.store.repository_urls assert coresys.resolution.suggestions[-1].type == SuggestionType.EXECUTE_REMOVE @@ -79,7 +77,7 @@ async def test_error_on_invalid_repository( """Test invalid repository not added.""" current = coresys.store.repository_urls with ( - patch("supervisor.store.repository.Repository.load", return_value=None), + patch("supervisor.store.repository.RepositoryGit.load", return_value=None), patch( "pathlib.Path.read_text", return_value="", @@ -103,7 +101,7 @@ async def test_add_invalid_repository_file( """Test add invalid custom repository file.""" current = coresys.store.repository_urls with ( - patch("supervisor.store.repository.Repository.load", return_value=None), + patch("supervisor.store.repository.RepositoryGit.load", return_value=None), patch( "pathlib.Path.read_text", return_value=json.dumps({"name": "Awesome repository"}), @@ -114,7 +112,7 @@ async def test_add_invalid_repository_file( current + ["http://example.com"], add_with_errors=True ) - assert not store_manager.get_from_url("http://example.com").validate() + assert not await store_manager.get_from_url("http://example.com").validate() assert "http://example.com" in coresys.store.repository_urls assert coresys.resolution.suggestions[-1].type == SuggestionType.EXECUTE_REMOVE @@ -135,7 +133,7 @@ async def test_add_repository_with_git_error( ): """Test repo added with issue on git error.""" current = coresys.store.repository_urls - with patch("supervisor.store.repository.Repository.load", side_effect=git_error): + with patch("supervisor.store.repository.RepositoryGit.load", side_effect=git_error): await store_manager.update_repositories( current + ["http://example.com"], add_with_errors=True ) @@ -163,7 +161,7 @@ async def test_error_on_repository_with_git_error( """Test repo not added on git error.""" current = coresys.store.repository_urls with ( - patch("supervisor.store.repository.Repository.load", side_effect=git_error), + patch("supervisor.store.repository.RepositoryGit.load", side_effect=git_error), pytest.raises(StoreError), ): if use_update: @@ -182,7 +180,7 @@ async def test_preinstall_valid_repository( coresys: CoreSys, store_manager: StoreManager ): """Test add core repository valid.""" - with patch("supervisor.store.repository.Repository.load", return_value=None): + with patch("supervisor.store.repository.RepositoryGit.load", return_value=None): await store_manager.update_repositories(BUILTIN_REPOSITORIES) def validate(): @@ -244,8 +242,8 @@ async def test_remove_used_repository( async def test_update_partial_error(coresys: CoreSys, store_manager: StoreManager): """Test partial error on update does partial save and errors.""" - with patch("supervisor.store.repository.Repository.validate", return_value=True): - with patch("supervisor.store.repository.Repository.load", return_value=None): + with patch("supervisor.store.repository.RepositoryGit.validate", return_value=True): + with patch("supervisor.store.repository.RepositoryGit.load", return_value=None): await store_manager.update_repositories([]) store_manager.data.update.assert_called_once() @@ -256,7 +254,7 @@ async def test_update_partial_error(coresys: CoreSys, store_manager: StoreManage with ( patch( - "supervisor.store.repository.Repository.load", + "supervisor.store.repository.RepositoryGit.load", side_effect=[None, StoreGitError()], ), pytest.raises(StoreError), @@ -275,8 +273,8 @@ async def test_error_adding_duplicate( """Test adding a duplicate repository causes an error.""" assert repository.source in coresys.store.repository_urls with ( - patch("supervisor.store.repository.Repository.validate", return_value=True), - patch("supervisor.store.repository.Repository.load", return_value=None), + patch("supervisor.store.repository.RepositoryGit.validate", return_value=True), + patch("supervisor.store.repository.RepositoryGit.load", return_value=None), pytest.raises(StoreError), ): await store_manager.add_repository(repository.source) @@ -290,7 +288,7 @@ async def test_add_with_update_repositories( assert "http://example.com" not in coresys.store.repository_urls with ( - patch("supervisor.store.repository.Repository.load", return_value=None), + patch("supervisor.store.repository.RepositoryGit.load", return_value=None), patch( "supervisor.utils.common.read_yaml_file", return_value={"name": "Awesome repository"}, @@ -328,7 +326,7 @@ async def test_repositories_loaded_ignore_updates( ): """Test repositories loaded whether or not supervisor needs an update.""" with ( - patch("supervisor.store.repository.Repository.load", return_value=None), + patch("supervisor.store.repository.RepositoryGit.load", return_value=None), patch.object( type(coresys.supervisor), "need_update", diff --git a/tests/store/test_repository_git.py b/tests/store/test_repository_git.py index 8710f67eb..3bb444232 100644 --- a/tests/store/test_repository_git.py +++ b/tests/store/test_repository_git.py @@ -15,13 +15,6 @@ from supervisor.store.git import GitRepo REPO_URL = "https://github.com/awesome-developer/awesome-repo" -class GitRepoTest(GitRepo): - """Implementation of GitRepo for tests that allows direct setting of path.""" - - async def remove(self) -> None: - """Not implemented.""" - - @pytest.fixture(name="clone_from") async def fixture_clone_from(): """Mock git clone_from.""" @@ -35,7 +28,7 @@ async def test_git_clone( ): """Test git clone.""" fragment = f"#{branch}" if branch else "" - repo = GitRepoTest(coresys, tmp_path, f"{REPO_URL}{fragment}") + repo = GitRepo(coresys, tmp_path, f"{REPO_URL}{fragment}") await repo.clone.__wrapped__(repo) @@ -63,7 +56,7 @@ async def test_git_clone_error( coresys: CoreSys, tmp_path: Path, clone_from: AsyncMock, git_error: Exception ): """Test git clone error.""" - repo = GitRepoTest(coresys, tmp_path, REPO_URL) + repo = GitRepo(coresys, tmp_path, REPO_URL) clone_from.side_effect = git_error with pytest.raises(StoreGitCloneError): @@ -75,7 +68,7 @@ async def test_git_clone_error( async def test_git_load(coresys: CoreSys, tmp_path: Path): """Test git load.""" repo_dir = tmp_path / "repo" - repo = GitRepoTest(coresys, repo_dir, REPO_URL) + repo = GitRepo(coresys, repo_dir, REPO_URL) repo.clone = AsyncMock() # Test with non-existing git repo root directory @@ -113,7 +106,7 @@ async def test_git_load(coresys: CoreSys, tmp_path: Path): async def test_git_load_error(coresys: CoreSys, tmp_path: Path, git_errors: Exception): """Test git load error.""" coresys.hardware.disk.get_disk_free_space = lambda x: 5000 - repo = GitRepoTest(coresys, tmp_path, REPO_URL) + repo = GitRepo(coresys, tmp_path, REPO_URL) # Pretend we have a repo (tmp_path / ".git").mkdir() diff --git a/tests/store/test_store_manager.py b/tests/store/test_store_manager.py index e1643cd84..385229c43 100644 --- a/tests/store/test_store_manager.py +++ b/tests/store/test_store_manager.py @@ -32,7 +32,8 @@ async def test_default_load(coresys: CoreSys): refresh_cache_calls.add(obj.slug) with ( - patch("supervisor.store.repository.Repository.load", return_value=None), + patch("supervisor.store.repository.RepositoryGit.load", return_value=None), + patch("supervisor.store.repository.RepositoryLocal.load", return_value=None), patch.object(type(coresys.config), "addons_repositories", return_value=[]), patch("pathlib.Path.exists", return_value=True), patch.object(AddonStore, "refresh_path_cache", new=mock_refresh_cache), @@ -80,9 +81,13 @@ async def test_load_with_custom_repository(coresys: CoreSys): store_manager = await StoreManager(coresys).load_config() with ( - patch("supervisor.store.repository.Repository.load", return_value=None), + patch("supervisor.store.repository.RepositoryGit.load", return_value=None), + patch("supervisor.store.repository.RepositoryLocal.load", return_value=None), patch.object(type(coresys.config), "addons_repositories", return_value=[]), - patch("supervisor.store.repository.Repository.validate", return_value=True), + patch("supervisor.store.repository.RepositoryGit.validate", return_value=True), + patch( + "supervisor.store.repository.RepositoryLocal.validate", return_value=True + ), patch("pathlib.Path.exists", return_value=True), patch.object(AddonStore, "refresh_path_cache", new=mock_refresh_cache), ):