From 83e9d7c5233680238b2b3bfd68ed220068a70093 Mon Sep 17 00:00:00 2001 From: Evgenii Alekseev Date: Sun, 25 Dec 2022 01:10:38 +0200 Subject: [PATCH] write patches via gitremote push trigger (#79) * write patches via gitremote push trigger * implement context variables intead of custom database class --- docs/ahriman.models.rst | 8 ++ docs/architecture.rst | 9 ++ docs/triggers.rst | 34 +++++++ .../application/application_properties.py | 4 +- src/ahriman/core/__init__.py | 79 ++++++++++++++++ .../core/gitremote/remote_pull_trigger.py | 3 + src/ahriman/core/gitremote/remote_push.py | 22 +++-- .../core/gitremote/remote_push_trigger.py | 14 ++- src/ahriman/core/repository/repository.py | 49 +++++++++- .../core/repository/repository_properties.py | 3 +- src/ahriman/core/status/watcher.py | 2 +- src/ahriman/core/tree.py | 2 +- src/ahriman/core/triggers/trigger_loader.py | 2 +- src/ahriman/models/context_key.py | 37 ++++++++ .../application/application/conftest.py | 17 ++-- tests/ahriman/application/conftest.py | 6 +- .../application/handlers/test_handler_add.py | 15 +-- .../handlers/test_handler_clean.py | 6 +- .../application/handlers/test_handler_dump.py | 6 +- .../handlers/test_handler_key_import.py | 6 +- .../handlers/test_handler_patch.py | 21 +++-- .../handlers/test_handler_rebuild.py | 34 ++++--- .../handlers/test_handler_remove.py | 6 +- .../handlers/test_handler_remove_unknown.py | 13 +-- .../handlers/test_handler_search.py | 24 ++--- .../handlers/test_handler_setup.py | 7 +- .../handlers/test_handler_shell.py | 16 ++-- .../application/handlers/test_handler_sign.py | 6 +- .../handlers/test_handler_status.py | 41 +++++---- .../handlers/test_handler_status_update.py | 29 +++--- .../handlers/test_handler_triggers.py | 12 ++- .../handlers/test_handler_update.py | 23 +++-- .../application/handlers/test_handler_web.py | 6 +- tests/ahriman/conftest.py | 24 ++++- .../core/gitremote/test_remote_push.py | 33 +++++-- .../gitremote/test_remote_push_trigger.py | 6 +- tests/ahriman/core/repository/conftest.py | 24 +---- .../core/repository/test_repository.py | 31 +++++++ .../repository/test_repository_properties.py | 4 +- tests/ahriman/core/status/test_watcher.py | 5 +- tests/ahriman/core/test_context_init.py | 92 +++++++++++++++++++ tests/ahriman/models/test_context_key.py | 0 tests/ahriman/web/conftest.py | 16 ++-- 43 files changed, 616 insertions(+), 181 deletions(-) create mode 100644 src/ahriman/models/context_key.py create mode 100644 tests/ahriman/core/test_context_init.py create mode 100644 tests/ahriman/models/test_context_key.py diff --git a/docs/ahriman.models.rst b/docs/ahriman.models.rst index 87c62602..57fb3490 100644 --- a/docs/ahriman.models.rst +++ b/docs/ahriman.models.rst @@ -36,6 +36,14 @@ ahriman.models.build\_status module :no-undoc-members: :show-inheritance: +ahriman.models.context\_key module +---------------------------------- + +.. automodule:: ahriman.models.context_key + :members: + :no-undoc-members: + :show-inheritance: + ahriman.models.counters module ------------------------------ diff --git a/docs/architecture.rst b/docs/architecture.rst index 19df4592..9b4c3f47 100644 --- a/docs/architecture.rst +++ b/docs/architecture.rst @@ -169,6 +169,15 @@ Utils For every external command run (which is actually not recommended if possible) custom wrapper for ``subprocess`` is used. Additional functions ``ahriman.core.auth.helpers`` provide safe calls for ``aiohttp_security`` methods and are required to make this dependency optional. +Context variables +^^^^^^^^^^^^^^^^^ + +Package provides implicit global variables which can be accessed from ``ahriman.core`` package as ``context`` variable, wrapped by ``contextvars.ContextVar`` class. The value of the variable is defaulting to private ``_Context`` class which is defined in the same module. The default values - such as ``database`` and ``sign`` - are being set on the service initialization. + +The ``_Context`` class itself mimics default collection interface (as is Mapping) and can be modified by ``_Context.set`` method. The stored variables can be achieved by ``_Context.get`` method, which is unlike default ``Mapping`` interface also performs type and presence checks. + +In order to provide statically typed interface, the ``ahriman.models.context_key.ContextKey`` class is used for both ``_Content.get`` and ``_Content.set`` methods; the context instance itself, however, does not store information about types. + Submodules ^^^^^^^^^^ diff --git a/docs/triggers.rst b/docs/triggers.rst index 978b6227..3c3e084a 100644 --- a/docs/triggers.rst +++ b/docs/triggers.rst @@ -36,6 +36,40 @@ Trigger which can be used for reporting. It implements ``on_result`` method and This trigger takes build result (``on_result``) and performs syncing of the local packages to the remote mirror (e.g. S3 or just by rsync). +Context variables +----------------- + +By default, only configuration and architecture are passed to triggers. However, some triggers might want to have access to other high-level wrappers. In order to provide such ability and avoid (double) initialization, the service provides a global context variables, which can be accessed from ``ahriman.core`` package: + +.. code-block:: python + + from ahriman.core import context + + ctx = context.get() + +Just because context is wrapped inside ``contexvars.ContextVar``, you need to explicitly extract variable by ``get()`` method. Later you can extract any variable if it is set, e.g.: + +.. code-block:: python + + from ahriman.core.database import SQLite + from ahriman.models.context_key import ContextKey + + database = ctx.get(ContextKey("database", SQLite)) + +In order to provide typed API, all variables are stored together with their type. The ``get(ContextKey)`` method will throw ``KeyError`` in case if key is missing. Alternatively you can set your own variable inside context: + +.. code-block:: python + + ctx.set(ContextKey("answer", int), 42) + context.set(ctx) + +Note, however, that there are several limitations: + +* Context variables are immutable, thus you cannot override value if the key already presented. +* The ``return_type`` of ``ContextKey`` should match the value type, otherwise exception will be thrown. + +The ``context`` also implements collection methods such as ``__iter__`` and ``__len__``. + Trigger example --------------- diff --git a/src/ahriman/application/application/application_properties.py b/src/ahriman/application/application/application_properties.py index 30a43357..9c523afb 100644 --- a/src/ahriman/application/application/application_properties.py +++ b/src/ahriman/application/application/application_properties.py @@ -50,5 +50,5 @@ class ApplicationProperties(LazyLogging): self.configuration = configuration self.architecture = architecture self.database = SQLite.load(configuration) - self.repository = Repository(architecture, configuration, self.database, - report=report, unsafe=unsafe, refresh_pacman_database=refresh_pacman_database) + self.repository = Repository.load(architecture, configuration, self.database, report=report, unsafe=unsafe, + refresh_pacman_database=refresh_pacman_database) diff --git a/src/ahriman/core/__init__.py b/src/ahriman/core/__init__.py index 680676f1..a75f51b5 100644 --- a/src/ahriman/core/__init__.py +++ b/src/ahriman/core/__init__.py @@ -17,3 +17,82 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # +from contextvars import ContextVar +from typing import Any, Dict, Iterator, TypeVar + +from ahriman.models.context_key import ContextKey + + +T = TypeVar("T") + + +class _Context: + """ + simple ahriman global context implementation + """ + + def __init__(self) -> None: + """ + default constructor. Must not be used directly + """ + self._content: Dict[str, Any] = {} + + def get(self, key: ContextKey[T]) -> T: + """ + get value for the specified key + + Args: + key(ContextKey[T]): context key name + + Returns: + T: value associated with the key + + Raises: + KeyError: in case if the specified context variable was not found + ValueError: in case if type of value is not an instance of specified return type + """ + if key.key not in self._content: + raise KeyError(key.key) + value = self._content[key.key] + if not isinstance(value, key.return_type): + raise ValueError(f"Value {value} is not an instance of {key.return_type}") + return value + + def set(self, key: ContextKey[T], value: T) -> None: + """ + set value for the specified key + + Args: + key(ContextKey[T]): context key name + value(T): context value associated with the specified key + + Raises: + KeyError: in case if the specified context variable already exists + ValueError: in case if type of value is not an instance of specified return type + """ + if key.key in self._content: + raise KeyError(key.key) + if not isinstance(value, key.return_type): + raise ValueError(f"Value {value} is not an instance of {key.return_type}") + self._content[key.key] = value + + def __iter__(self) -> Iterator[str]: + """ + iterate over keys in local storage + + Returns: + str: context key iterator + """ + return iter(self._content) + + def __len__(self) -> int: + """ + get count of the context variables set + + Returns: + int: count of stored context variables + """ + return len(self._content) + + +context = ContextVar("context", default=_Context()) diff --git a/src/ahriman/core/gitremote/remote_pull_trigger.py b/src/ahriman/core/gitremote/remote_pull_trigger.py index aa0532ff..cef08a67 100644 --- a/src/ahriman/core/gitremote/remote_pull_trigger.py +++ b/src/ahriman/core/gitremote/remote_pull_trigger.py @@ -25,6 +25,9 @@ from ahriman.core.triggers import Trigger class RemotePullTrigger(Trigger): """ trigger based on pulling PKGBUILDs before the actions + + Attributes: + targets(List[str]): git remote target list """ def __init__(self, architecture: str, configuration: Configuration) -> None: diff --git a/src/ahriman/core/gitremote/remote_push.py b/src/ahriman/core/gitremote/remote_push.py index 32d96f10..b66228b6 100644 --- a/src/ahriman/core/gitremote/remote_push.py +++ b/src/ahriman/core/gitremote/remote_push.py @@ -25,6 +25,7 @@ from typing import Generator from ahriman.core.build_tools.sources import Sources from ahriman.core.configuration import Configuration +from ahriman.core.database import SQLite from ahriman.core.exceptions import GitRemoteError from ahriman.core.log import LazyLogging from ahriman.models.package import Package @@ -39,17 +40,20 @@ class RemotePush(LazyLogging): Attributes: commit_author(Optional[str]): optional commit author in form of git config (i.e. ``user ``) + database(SQLite): database instance remote_source(RemoteSource): repository remote source (remote pull url and branch) """ - def __init__(self, configuration: Configuration, section: str) -> None: + def __init__(self, configuration: Configuration, database: SQLite, section: str) -> None: """ default constructor Args: configuration(Configuration): configuration instance - remote_push_trigger.py + database(SQLite): database instance + section(str): settings section name """ + self.database = database self.commit_author = configuration.get(section, "commit_author", fallback=None) self.remote_source = RemoteSource( git_url=configuration.get(section, "push_url"), @@ -59,8 +63,7 @@ class RemotePush(LazyLogging): source=PackageSource.Local, ) - @staticmethod - def package_update(package: Package, target_dir: Path) -> str: + def package_update(self, package: Package, target_dir: Path) -> str: """ clone specified package and update its content in cloned PKGBUILD repository @@ -79,11 +82,14 @@ class RemotePush(LazyLogging): Sources.fetch(package_target_dir, package.remote) # ...and last, but not least, we remove the dot-git directory... shutil.rmtree(package_target_dir / ".git", ignore_errors=True) + # ...copy all patches... + for patch in self.database.patches_get(package.base): + filename = f"ahriman-{package.base}.patch" if patch.key is None else f"ahriman-{patch.key}.patch" + patch.write(package_target_dir / filename) # ...and finally return path to the copied directory return package.base - @staticmethod - def packages_update(result: Result, target_dir: Path) -> Generator[str, None, None]: + def packages_update(self, result: Result, target_dir: Path) -> Generator[str, None, None]: """ update all packages from the build result @@ -95,7 +101,7 @@ class RemotePush(LazyLogging): str: path to updated files """ for package in result.success: - yield RemotePush.package_update(package, target_dir) + yield self.package_update(package, target_dir) def run(self, result: Result) -> None: """ @@ -107,7 +113,7 @@ class RemotePush(LazyLogging): try: with TemporaryDirectory(ignore_cleanup_errors=True) as dir_name, (clone_dir := Path(dir_name)): Sources.fetch(clone_dir, self.remote_source) - Sources.push(clone_dir, self.remote_source, *RemotePush.packages_update(result, clone_dir), + Sources.push(clone_dir, self.remote_source, *self.packages_update(result, clone_dir), commit_author=self.commit_author) except Exception: self.logger.exception("git push failed") diff --git a/src/ahriman/core/gitremote/remote_push_trigger.py b/src/ahriman/core/gitremote/remote_push_trigger.py index aea0896e..b3edb560 100644 --- a/src/ahriman/core/gitremote/remote_push_trigger.py +++ b/src/ahriman/core/gitremote/remote_push_trigger.py @@ -19,9 +19,12 @@ # from typing import Iterable +from ahriman.core import context from ahriman.core.configuration import Configuration +from ahriman.core.database import SQLite from ahriman.core.gitremote.remote_push import RemotePush from ahriman.core.triggers import Trigger +from ahriman.models.context_key import ContextKey from ahriman.models.package import Package from ahriman.models.result import Result @@ -29,6 +32,9 @@ from ahriman.models.result import Result class RemotePushTrigger(Trigger): """ trigger for syncing PKGBUILDs to remote repository + + Attributes: + targets(List[str]): git remote target list """ def __init__(self, architecture: str, configuration: Configuration) -> None: @@ -49,8 +55,14 @@ class RemotePushTrigger(Trigger): Args: result(Result): build result packages(Iterable[Package]): list of all available packages + + Raises: + GitRemoteError: if database is not set in context """ + ctx = context.get() + database = ctx.get(ContextKey("database", SQLite)) + for target in self.targets: section, _ = self.configuration.gettype(target, self.architecture) - runner = RemotePush(self.configuration, section) + runner = RemotePush(self.configuration, database, section) runner.run(result) diff --git a/src/ahriman/core/repository/repository.py b/src/ahriman/core/repository/repository.py index c984186a..acd8d9a0 100644 --- a/src/ahriman/core/repository/repository.py +++ b/src/ahriman/core/repository/repository.py @@ -17,12 +17,20 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # -from pathlib import Path -from typing import Dict, Iterable, List, Optional +from __future__ import annotations +from pathlib import Path +from typing import Dict, Iterable, List, Optional, Type + +from ahriman.core import context +from ahriman.core.alpm.pacman import Pacman +from ahriman.core.configuration import Configuration +from ahriman.core.database import SQLite from ahriman.core.repository.executor import Executor from ahriman.core.repository.update_handler import UpdateHandler +from ahriman.core.sign.gpg import GPG from ahriman.core.util import package_like +from ahriman.models.context_key import ContextKey from ahriman.models.package import Package @@ -39,7 +47,7 @@ class Repository(Executor, UpdateHandler): >>> >>> configuration = Configuration() >>> database = SQLite.load(configuration) - >>> repository = Repository("x86_64", configuration, database, report=True, unsafe=False) + >>> repository = Repository.load("x86_64", configuration, database, report=True, unsafe=False) >>> known_packages = repository.packages() >>> >>> build_result = repository.process_build(known_packages) @@ -49,6 +57,41 @@ class Repository(Executor, UpdateHandler): >>> repository.triggers.on_result(update_result, repository.packages()) """ + @classmethod + def load(cls: Type[Repository], architecture: str, configuration: Configuration, database: SQLite, *, + report: bool, unsafe: bool, refresh_pacman_database: int = 0) -> Repository: + """ + load instance from argument list + + Args: + architecture(str): repository architecture + configuration(Configuration): configuration instance + database(SQLite): database instance + report(bool): force enable or disable reporting + unsafe(bool): if set no user check will be performed before path creation + refresh_pacman_database(int, optional): pacman database syncronization level, ``0`` is disabled + (Default value = 0) + """ + instance = cls(architecture, configuration, database, + report=report, unsafe=unsafe, refresh_pacman_database=refresh_pacman_database) + instance._set_context() + return instance + + def _set_context(self) -> None: + """ + set context variables + """ + ctx = context.get() + + ctx.set(ContextKey("database", SQLite), self.database) + ctx.set(ContextKey("configuration", Configuration), self.configuration) + ctx.set(ContextKey("pacman", Pacman), self.pacman) + ctx.set(ContextKey("sign", GPG), self.sign) + + ctx.set(ContextKey("repository", type(self)), self) + + context.set(ctx) + def load_archives(self, packages: Iterable[Path]) -> List[Package]: """ load packages from list of archives diff --git a/src/ahriman/core/repository/repository_properties.py b/src/ahriman/core/repository/repository_properties.py index 5e2ebd55..d4d25274 100644 --- a/src/ahriman/core/repository/repository_properties.py +++ b/src/ahriman/core/repository/repository_properties.py @@ -48,7 +48,7 @@ class RepositoryProperties(LazyLogging): """ def __init__(self, architecture: str, configuration: Configuration, database: SQLite, *, - report: bool, unsafe: bool, refresh_pacman_database: int = 0) -> None: + report: bool, unsafe: bool, refresh_pacman_database: int) -> None: """ default constructor @@ -59,7 +59,6 @@ class RepositoryProperties(LazyLogging): report(bool): force enable or disable reporting unsafe(bool): if set no user check will be performed before path creation refresh_pacman_database(int, optional): pacman database syncronization level, ``0`` is disabled - (Default value = 0) """ self.architecture = architecture self.configuration = configuration diff --git a/src/ahriman/core/status/watcher.py b/src/ahriman/core/status/watcher.py index 328661c3..6c0df139 100644 --- a/src/ahriman/core/status/watcher.py +++ b/src/ahriman/core/status/watcher.py @@ -55,7 +55,7 @@ class Watcher(LazyLogging): """ self.architecture = architecture self.database = database - self.repository = Repository(architecture, configuration, database, report=False, unsafe=False) + self.repository = Repository.load(architecture, configuration, database, report=False, unsafe=False) self.known: Dict[str, Tuple[Package, BuildStatus]] = {} self.status = BuildStatus() diff --git a/src/ahriman/core/tree.py b/src/ahriman/core/tree.py index b2b136f5..209f5c30 100644 --- a/src/ahriman/core/tree.py +++ b/src/ahriman/core/tree.py @@ -110,7 +110,7 @@ class Tree: >>> >>> configuration = Configuration() >>> database = SQLite.load(configuration) - >>> repository = Repository("x86_64", configuration, database, report=True, unsafe=False) + >>> repository = Repository.load("x86_64", configuration, database, report=True, unsafe=False) >>> packages = repository.packages() >>> >>> tree = Tree.load(packages, configuration.repository_paths, database) diff --git a/src/ahriman/core/triggers/trigger_loader.py b/src/ahriman/core/triggers/trigger_loader.py index 8e64b7a7..ab833bb6 100644 --- a/src/ahriman/core/triggers/trigger_loader.py +++ b/src/ahriman/core/triggers/trigger_loader.py @@ -69,11 +69,11 @@ class TriggerLoader(LazyLogging): self.architecture = architecture self.configuration = configuration + self._on_stop_requested = False self.triggers = [ self.load_trigger(trigger) for trigger in configuration.getlist("build", "triggers") ] - self._on_stop_requested = False def __del__(self) -> None: """ diff --git a/src/ahriman/models/context_key.py b/src/ahriman/models/context_key.py new file mode 100644 index 00000000..043efba6 --- /dev/null +++ b/src/ahriman/models/context_key.py @@ -0,0 +1,37 @@ +# +# Copyright (c) 2021-2022 ahriman team. +# +# This file is part of ahriman +# (see https://github.com/arcan1s/ahriman). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +from dataclasses import dataclass +from typing import Generic, Type, TypeVar + + +T = TypeVar("T") + + +@dataclass(frozen=True) +class ContextKey(Generic[T]): + """ + ahriman context key for typing purposes + + Attributes: + key(str): context key to lookup + return_type(Type[T]): return type used for the specified context key + """ + key: str + return_type: Type[T] diff --git a/tests/ahriman/application/application/conftest.py b/tests/ahriman/application/application/conftest.py index 109dbe10..fe351df7 100644 --- a/tests/ahriman/application/application/conftest.py +++ b/tests/ahriman/application/application/conftest.py @@ -7,28 +7,31 @@ from ahriman.application.application.application_properties import ApplicationPr from ahriman.application.application.application_repository import ApplicationRepository from ahriman.core.configuration import Configuration from ahriman.core.database import SQLite +from ahriman.core.repository import Repository @pytest.fixture -def application_packages(configuration: Configuration, database: SQLite, mocker: MockerFixture) -> ApplicationPackages: +def application_packages(configuration: Configuration, database: SQLite, repository: Repository, + mocker: MockerFixture) -> ApplicationPackages: """ fixture for application with package functions Args: configuration(Configuration): configuration fixture database(SQLite): database fixture + repository(Repository): repository fixture mocker(MockerFixture): mocker object Returns: ApplicationPackages: application test instance """ - mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") + mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) mocker.patch("ahriman.core.database.SQLite.load", return_value=database) return ApplicationPackages("x86_64", configuration, report=False, unsafe=False) @pytest.fixture -def application_properties(configuration: Configuration, database: SQLite, +def application_properties(configuration: Configuration, database: SQLite, repository: Repository, mocker: MockerFixture) -> ApplicationProperties: """ fixture for application with properties only @@ -36,18 +39,19 @@ def application_properties(configuration: Configuration, database: SQLite, Args: configuration(Configuration): configuration fixture database(SQLite): database fixture + repository(Repository): repository fixture mocker(MockerFixture): mocker object Returns: ApplicationProperties: application test instance """ - mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") + mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) mocker.patch("ahriman.core.database.SQLite.load", return_value=database) return ApplicationProperties("x86_64", configuration, report=False, unsafe=False) @pytest.fixture -def application_repository(configuration: Configuration, database: SQLite, +def application_repository(configuration: Configuration, database: SQLite, repository: Repository, mocker: MockerFixture) -> ApplicationRepository: """ fixture for application with repository functions @@ -55,11 +59,12 @@ def application_repository(configuration: Configuration, database: SQLite, Args: configuration(Configuration): configuration fixture database(SQLite): database fixture + repository(Repository): repository fixture mocker(MockerFixture): mocker object Returns: ApplicationRepository: application test instance """ - mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") + mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) mocker.patch("ahriman.core.database.SQLite.load", return_value=database) return ApplicationRepository("x86_64", configuration, report=False, unsafe=False) diff --git a/tests/ahriman/application/conftest.py b/tests/ahriman/application/conftest.py index 48b968d2..49c309ea 100644 --- a/tests/ahriman/application/conftest.py +++ b/tests/ahriman/application/conftest.py @@ -8,16 +8,19 @@ from ahriman.application.application import Application from ahriman.application.lock import Lock from ahriman.core.configuration import Configuration from ahriman.core.database import SQLite +from ahriman.core.repository import Repository @pytest.fixture -def application(configuration: Configuration, database: SQLite, mocker: MockerFixture) -> Application: +def application(configuration: Configuration, repository: Repository, database: SQLite, + mocker: MockerFixture) -> Application: """ fixture for application Args: configuration(Configuration): configuration fixture database(SQLite): database fixture + repository(Repository): repository fixture mocker(MockerFixture): mocker object Returns: @@ -25,6 +28,7 @@ def application(configuration: Configuration, database: SQLite, mocker: MockerFi """ mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") mocker.patch("ahriman.core.database.SQLite.load", return_value=database) + mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) return Application("x86_64", configuration, report=False, unsafe=False) diff --git a/tests/ahriman/application/handlers/test_handler_add.py b/tests/ahriman/application/handlers/test_handler_add.py index 333f92f9..cf1234ce 100644 --- a/tests/ahriman/application/handlers/test_handler_add.py +++ b/tests/ahriman/application/handlers/test_handler_add.py @@ -5,6 +5,7 @@ from pytest_mock import MockerFixture from ahriman.application.handlers import Add from ahriman.core.configuration import Configuration +from ahriman.core.repository import Repository from ahriman.models.package import Package from ahriman.models.package_source import PackageSource from ahriman.models.result import Result @@ -29,12 +30,13 @@ def _default_args(args: argparse.Namespace) -> argparse.Namespace: return args -def test_run(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None: +def test_run(args: argparse.Namespace, configuration: Configuration, repository: Repository, + mocker: MockerFixture) -> None: """ must run command """ args = _default_args(args) - mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") + mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) application_mock = mocker.patch("ahriman.application.application.Application.add") on_start_mock = mocker.patch("ahriman.application.application.Application.on_start") @@ -43,7 +45,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc on_start_mock.assert_called_once_with() -def test_run_with_updates(args: argparse.Namespace, configuration: Configuration, +def test_run_with_updates(args: argparse.Namespace, configuration: Configuration, repository: Repository, package_ahriman: Package, mocker: MockerFixture) -> None: """ must run command with updates after @@ -53,7 +55,7 @@ def test_run_with_updates(args: argparse.Namespace, configuration: Configuration result = Result() result.add_success(package_ahriman) mocker.patch("ahriman.application.application.Application.add") - mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") + mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) application_mock = mocker.patch("ahriman.application.application.Application.update", return_value=result) check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty") updates_mock = mocker.patch("ahriman.application.application.Application.updates", return_value=[package_ahriman]) @@ -65,7 +67,8 @@ def test_run_with_updates(args: argparse.Namespace, configuration: Configuration check_mock.assert_called_once_with(False, False) -def test_run_empty_exception(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None: +def test_run_empty_exception(args: argparse.Namespace, configuration: Configuration, repository: Repository, + mocker: MockerFixture) -> None: """ must raise ExitCode exception on empty result """ @@ -73,7 +76,7 @@ def test_run_empty_exception(args: argparse.Namespace, configuration: Configurat args.now = True args.exit_code = True mocker.patch("ahriman.application.application.Application.add") - mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") + mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) mocker.patch("ahriman.application.application.Application.update", return_value=Result()) mocker.patch("ahriman.application.application.Application.updates") check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty") diff --git a/tests/ahriman/application/handlers/test_handler_clean.py b/tests/ahriman/application/handlers/test_handler_clean.py index daf8247f..82d2f92b 100644 --- a/tests/ahriman/application/handlers/test_handler_clean.py +++ b/tests/ahriman/application/handlers/test_handler_clean.py @@ -4,6 +4,7 @@ from pytest_mock import MockerFixture from ahriman.application.handlers import Clean from ahriman.core.configuration import Configuration +from ahriman.core.repository import Repository def _default_args(args: argparse.Namespace) -> argparse.Namespace: @@ -24,12 +25,13 @@ def _default_args(args: argparse.Namespace) -> argparse.Namespace: return args -def test_run(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None: +def test_run(args: argparse.Namespace, configuration: Configuration, repository: Repository, + mocker: MockerFixture) -> None: """ must run command """ args = _default_args(args) - mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") + mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) application_mock = mocker.patch("ahriman.application.application.Application.clean") on_start_mock = mocker.patch("ahriman.application.application.Application.on_start") diff --git a/tests/ahriman/application/handlers/test_handler_dump.py b/tests/ahriman/application/handlers/test_handler_dump.py index 27135099..d046ebfd 100644 --- a/tests/ahriman/application/handlers/test_handler_dump.py +++ b/tests/ahriman/application/handlers/test_handler_dump.py @@ -4,13 +4,15 @@ from pytest_mock import MockerFixture from ahriman.application.handlers import Dump from ahriman.core.configuration import Configuration +from ahriman.core.repository import Repository -def test_run(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None: +def test_run(args: argparse.Namespace, configuration: Configuration, repository: Repository, + mocker: MockerFixture) -> None: """ must run command """ - mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") + mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) print_mock = mocker.patch("ahriman.core.formatters.Printer.print") application_mock = mocker.patch("ahriman.core.configuration.Configuration.dump", return_value=configuration.dump()) diff --git a/tests/ahriman/application/handlers/test_handler_key_import.py b/tests/ahriman/application/handlers/test_handler_key_import.py index 39e4ed0f..70cfda3b 100644 --- a/tests/ahriman/application/handlers/test_handler_key_import.py +++ b/tests/ahriman/application/handlers/test_handler_key_import.py @@ -4,6 +4,7 @@ from pytest_mock import MockerFixture from ahriman.application.handlers import KeyImport from ahriman.core.configuration import Configuration +from ahriman.core.repository import Repository def _default_args(args: argparse.Namespace) -> argparse.Namespace: @@ -21,12 +22,13 @@ def _default_args(args: argparse.Namespace) -> argparse.Namespace: return args -def test_run(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None: +def test_run(args: argparse.Namespace, configuration: Configuration, repository: Repository, + mocker: MockerFixture) -> None: """ must run command """ args = _default_args(args) - mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") + mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) application_mock = mocker.patch("ahriman.core.sign.gpg.GPG.key_import") KeyImport.run(args, "x86_64", configuration, report=False, unsafe=False) diff --git a/tests/ahriman/application/handlers/test_handler_patch.py b/tests/ahriman/application/handlers/test_handler_patch.py index 3ec86769..89b6d07d 100644 --- a/tests/ahriman/application/handlers/test_handler_patch.py +++ b/tests/ahriman/application/handlers/test_handler_patch.py @@ -8,6 +8,7 @@ from pytest_mock import MockerFixture from ahriman.application.application import Application from ahriman.application.handlers import Patch from ahriman.core.configuration import Configuration +from ahriman.core.repository import Repository from ahriman.models.action import Action from ahriman.models.package import Package from ahriman.models.pkgbuild_patch import PkgbuildPatch @@ -31,13 +32,14 @@ def _default_args(args: argparse.Namespace) -> argparse.Namespace: return args -def test_run(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None: +def test_run(args: argparse.Namespace, configuration: Configuration, repository: Repository, + mocker: MockerFixture) -> None: """ must run command """ args = _default_args(args) args.action = Action.Update - mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") + mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) patch_mock = mocker.patch("ahriman.application.handlers.Patch.patch_create_from_diff", return_value=(args.package, PkgbuildPatch(None, "patch"))) application_mock = mocker.patch("ahriman.application.handlers.Patch.patch_set_create") @@ -47,7 +49,8 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc application_mock.assert_called_once_with(pytest.helpers.anyvar(int), args.package, PkgbuildPatch(None, "patch")) -def test_run_function(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None: +def test_run_function(args: argparse.Namespace, configuration: Configuration, repository: Repository, + mocker: MockerFixture) -> None: """ must run command with patch function flag """ @@ -56,7 +59,7 @@ def test_run_function(args: argparse.Namespace, configuration: Configuration, mo args.patch = "patch" args.variable = "version" patch = PkgbuildPatch(args.variable, args.patch) - mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") + mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) patch_mock = mocker.patch("ahriman.application.handlers.Patch.patch_create_from_function", return_value=patch) application_mock = mocker.patch("ahriman.application.handlers.Patch.patch_set_create") @@ -65,28 +68,30 @@ def test_run_function(args: argparse.Namespace, configuration: Configuration, mo application_mock.assert_called_once_with(pytest.helpers.anyvar(int), args.package, patch) -def test_run_list(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None: +def test_run_list(args: argparse.Namespace, configuration: Configuration, repository: Repository, + mocker: MockerFixture) -> None: """ must run command with list flag """ args = _default_args(args) args.action = Action.List args.variable = ["version"] - mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") + mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) application_mock = mocker.patch("ahriman.application.handlers.Patch.patch_set_list") Patch.run(args, "x86_64", configuration, report=False, unsafe=False) application_mock.assert_called_once_with(pytest.helpers.anyvar(int), args.package, ["version"], False) -def test_run_remove(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None: +def test_run_remove(args: argparse.Namespace, configuration: Configuration, repository: Repository, + mocker: MockerFixture) -> None: """ must run command with remove flag """ args = _default_args(args) args.action = Action.Remove args.variable = ["version"] - mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") + mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) application_mock = mocker.patch("ahriman.application.handlers.Patch.patch_set_remove") Patch.run(args, "x86_64", configuration, report=False, unsafe=False) diff --git a/tests/ahriman/application/handlers/test_handler_rebuild.py b/tests/ahriman/application/handlers/test_handler_rebuild.py index 9d43342c..7f46706b 100644 --- a/tests/ahriman/application/handlers/test_handler_rebuild.py +++ b/tests/ahriman/application/handlers/test_handler_rebuild.py @@ -7,6 +7,7 @@ from unittest.mock import call as MockCall from ahriman.application.application import Application from ahriman.application.handlers import Rebuild from ahriman.core.configuration import Configuration +from ahriman.core.repository import Repository from ahriman.models.package import Package from ahriman.models.result import Result @@ -28,15 +29,15 @@ def _default_args(args: argparse.Namespace) -> argparse.Namespace: return args -def test_run(args: argparse.Namespace, package_ahriman: Package, - configuration: Configuration, mocker: MockerFixture) -> None: +def test_run(args: argparse.Namespace, package_ahriman: Package, configuration: Configuration, + repository: Repository, mocker: MockerFixture) -> None: """ must run command """ args = _default_args(args) result = Result() result.add_success(package_ahriman) - mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") + mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) extract_mock = mocker.patch("ahriman.application.handlers.Rebuild.extract_packages", return_value=[package_ahriman]) application_packages_mock = mocker.patch("ahriman.core.repository.repository.Repository.packages_depend_on", return_value=[package_ahriman]) @@ -52,14 +53,15 @@ def test_run(args: argparse.Namespace, package_ahriman: Package, on_start_mock.assert_called_once_with() -def test_run_extract_packages(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None: +def test_run_extract_packages(args: argparse.Namespace, configuration: Configuration, repository: Repository, + mocker: MockerFixture) -> None: """ must run command """ args = _default_args(args) args.from_database = True args.dry_run = True - mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") + mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) mocker.patch("ahriman.application.application.Application.add") extract_mock = mocker.patch("ahriman.application.handlers.Rebuild.extract_packages", return_value=[]) @@ -67,14 +69,14 @@ def test_run_extract_packages(args: argparse.Namespace, configuration: Configura extract_mock.assert_called_once_with(pytest.helpers.anyvar(int), from_database=args.from_database) -def test_run_dry_run(args: argparse.Namespace, configuration: Configuration, +def test_run_dry_run(args: argparse.Namespace, configuration: Configuration, repository: Repository, package_ahriman: Package, mocker: MockerFixture) -> None: """ must run command without update itself """ args = _default_args(args) args.dry_run = True - mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") + mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) mocker.patch("ahriman.application.handlers.Rebuild.extract_packages", return_value=[package_ahriman]) application_mock = mocker.patch("ahriman.application.application.Application.update") check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty") @@ -84,14 +86,15 @@ def test_run_dry_run(args: argparse.Namespace, configuration: Configuration, check_mock.assert_called_once_with(False, False) -def test_run_filter(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None: +def test_run_filter(args: argparse.Namespace, configuration: Configuration, repository: Repository, + mocker: MockerFixture) -> None: """ must run command with depends on filter """ args = _default_args(args) args.depends_on = ["python-aur"] mocker.patch("ahriman.application.application.Application.update") - mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") + mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) mocker.patch("ahriman.application.handlers.Rebuild.extract_packages", return_value=[]) application_packages_mock = mocker.patch("ahriman.core.repository.repository.Repository.packages_depend_on") @@ -99,13 +102,14 @@ def test_run_filter(args: argparse.Namespace, configuration: Configuration, mock application_packages_mock.assert_called_once_with([], {"python-aur"}) -def test_run_without_filter(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None: +def test_run_without_filter(args: argparse.Namespace, configuration: Configuration, repository: Repository, + mocker: MockerFixture) -> None: """ must run command for all packages if no filter supplied """ args = _default_args(args) mocker.patch("ahriman.application.application.Application.update") - mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") + mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) mocker.patch("ahriman.application.handlers.Rebuild.extract_packages", return_value=[]) application_packages_mock = mocker.patch("ahriman.core.repository.repository.Repository.packages_depend_on") @@ -113,7 +117,7 @@ def test_run_without_filter(args: argparse.Namespace, configuration: Configurati application_packages_mock.assert_called_once_with([], None) -def test_run_update_empty_exception(args: argparse.Namespace, configuration: Configuration, +def test_run_update_empty_exception(args: argparse.Namespace, configuration: Configuration, repository: Repository, mocker: MockerFixture) -> None: """ must raise ExitCode exception on empty update list @@ -121,7 +125,7 @@ def test_run_update_empty_exception(args: argparse.Namespace, configuration: Con args = _default_args(args) args.exit_code = True args.dry_run = True - mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") + mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) mocker.patch("ahriman.application.handlers.Rebuild.extract_packages") mocker.patch("ahriman.core.repository.repository.Repository.packages_depend_on", return_value=[]) check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty") @@ -130,14 +134,14 @@ def test_run_update_empty_exception(args: argparse.Namespace, configuration: Con check_mock.assert_called_once_with(True, True) -def test_run_build_empty_exception(args: argparse.Namespace, configuration: Configuration, +def test_run_build_empty_exception(args: argparse.Namespace, configuration: Configuration, repository: Repository, package_ahriman: Package, mocker: MockerFixture) -> None: """ must raise ExitCode exception on empty update result """ args = _default_args(args) args.exit_code = True - mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") + mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) mocker.patch("ahriman.application.handlers.Rebuild.extract_packages") mocker.patch("ahriman.core.repository.repository.Repository.packages_depend_on", return_value=[package_ahriman]) mocker.patch("ahriman.application.application.Application.update", return_value=Result()) diff --git a/tests/ahriman/application/handlers/test_handler_remove.py b/tests/ahriman/application/handlers/test_handler_remove.py index a91bd314..e793eb0e 100644 --- a/tests/ahriman/application/handlers/test_handler_remove.py +++ b/tests/ahriman/application/handlers/test_handler_remove.py @@ -4,6 +4,7 @@ from pytest_mock import MockerFixture from ahriman.application.handlers import Remove from ahriman.core.configuration import Configuration +from ahriman.core.repository import Repository def _default_args(args: argparse.Namespace) -> argparse.Namespace: @@ -20,12 +21,13 @@ def _default_args(args: argparse.Namespace) -> argparse.Namespace: return args -def test_run(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None: +def test_run(args: argparse.Namespace, configuration: Configuration, repository: Repository, + mocker: MockerFixture) -> None: """ must run command """ args = _default_args(args) - mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") + mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) application_mock = mocker.patch("ahriman.application.application.Application.remove") on_start_mock = mocker.patch("ahriman.application.application.Application.on_start") diff --git a/tests/ahriman/application/handlers/test_handler_remove_unknown.py b/tests/ahriman/application/handlers/test_handler_remove_unknown.py index 95f2fa32..5ce5ed7f 100644 --- a/tests/ahriman/application/handlers/test_handler_remove_unknown.py +++ b/tests/ahriman/application/handlers/test_handler_remove_unknown.py @@ -4,6 +4,7 @@ from pytest_mock import MockerFixture from ahriman.application.handlers import RemoveUnknown from ahriman.core.configuration import Configuration +from ahriman.core.repository import Repository from ahriman.models.package import Package @@ -21,13 +22,13 @@ def _default_args(args: argparse.Namespace) -> argparse.Namespace: return args -def test_run(args: argparse.Namespace, package_ahriman: Package, - configuration: Configuration, mocker: MockerFixture) -> None: +def test_run(args: argparse.Namespace, package_ahriman: Package, configuration: Configuration, + repository: Repository, mocker: MockerFixture) -> None: """ must run command """ args = _default_args(args) - mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") + mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) application_mock = mocker.patch("ahriman.application.application.Application.unknown", return_value=[package_ahriman]) remove_mock = mocker.patch("ahriman.application.application.Application.remove") @@ -39,14 +40,14 @@ def test_run(args: argparse.Namespace, package_ahriman: Package, on_start_mock.assert_called_once_with() -def test_run_dry_run(args: argparse.Namespace, configuration: Configuration, package_ahriman: Package, - mocker: MockerFixture) -> None: +def test_run_dry_run(args: argparse.Namespace, configuration: Configuration, repository: Repository, + package_ahriman: Package, mocker: MockerFixture) -> None: """ must run simplified command """ args = _default_args(args) args.dry_run = True - mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") + mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) application_mock = mocker.patch("ahriman.application.application.Application.unknown", return_value=[package_ahriman]) remove_mock = mocker.patch("ahriman.application.application.Application.remove") diff --git a/tests/ahriman/application/handlers/test_handler_search.py b/tests/ahriman/application/handlers/test_handler_search.py index 8127bd5e..f1373056 100644 --- a/tests/ahriman/application/handlers/test_handler_search.py +++ b/tests/ahriman/application/handlers/test_handler_search.py @@ -8,6 +8,7 @@ from unittest.mock import call as MockCall from ahriman.application.handlers import Search from ahriman.core.configuration import Configuration from ahriman.core.exceptions import OptionError +from ahriman.core.repository import Repository from ahriman.models.aur_package import AURPackage @@ -28,13 +29,13 @@ def _default_args(args: argparse.Namespace) -> argparse.Namespace: return args -def test_run(args: argparse.Namespace, configuration: Configuration, aur_package_ahriman: AURPackage, - mocker: MockerFixture) -> None: +def test_run(args: argparse.Namespace, configuration: Configuration, repository: Repository, + aur_package_ahriman: AURPackage, mocker: MockerFixture) -> None: """ must run command """ args = _default_args(args) - mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") + mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) aur_search_mock = mocker.patch("ahriman.core.alpm.remote.AUR.multisearch", return_value=[aur_package_ahriman]) official_search_mock = mocker.patch("ahriman.core.alpm.remote.Official.multisearch", return_value=[aur_package_ahriman]) @@ -48,7 +49,8 @@ def test_run(args: argparse.Namespace, configuration: Configuration, aur_package print_mock.assert_has_calls([MockCall(False), MockCall(False)]) -def test_run_empty_exception(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None: +def test_run_empty_exception(args: argparse.Namespace, configuration: Configuration, repository: Repository, + mocker: MockerFixture) -> None: """ must raise ExitCode exception on empty result list """ @@ -57,22 +59,22 @@ def test_run_empty_exception(args: argparse.Namespace, configuration: Configurat mocker.patch("ahriman.core.alpm.remote.AUR.multisearch", return_value=[]) mocker.patch("ahriman.core.alpm.remote.Official.multisearch", return_value=[]) mocker.patch("ahriman.core.formatters.Printer.print") - mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") + mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty") Search.run(args, "x86_64", configuration, report=False, unsafe=False) check_mock.assert_called_once_with(True, True) -def test_run_sort(args: argparse.Namespace, configuration: Configuration, aur_package_ahriman: AURPackage, - mocker: MockerFixture) -> None: +def test_run_sort(args: argparse.Namespace, configuration: Configuration, repository: Repository, + aur_package_ahriman: AURPackage, mocker: MockerFixture) -> None: """ must run command with sorting """ args = _default_args(args) mocker.patch("ahriman.core.alpm.remote.AUR.multisearch", return_value=[aur_package_ahriman]) mocker.patch("ahriman.core.alpm.remote.Official.multisearch", return_value=[]) - mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") + mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) sort_mock = mocker.patch("ahriman.application.handlers.Search.sort") Search.run(args, "x86_64", configuration, report=False, unsafe=False) @@ -82,8 +84,8 @@ def test_run_sort(args: argparse.Namespace, configuration: Configuration, aur_pa ]) -def test_run_sort_by(args: argparse.Namespace, configuration: Configuration, aur_package_ahriman: AURPackage, - mocker: MockerFixture) -> None: +def test_run_sort_by(args: argparse.Namespace, configuration: Configuration, repository: Repository, + aur_package_ahriman: AURPackage, mocker: MockerFixture) -> None: """ must run command with sorting by specified field """ @@ -91,7 +93,7 @@ def test_run_sort_by(args: argparse.Namespace, configuration: Configuration, aur args.sort_by = "field" mocker.patch("ahriman.core.alpm.remote.AUR.multisearch", return_value=[aur_package_ahriman]) mocker.patch("ahriman.core.alpm.remote.Official.multisearch", return_value=[]) - mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") + mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) sort_mock = mocker.patch("ahriman.application.handlers.Search.sort") Search.run(args, "x86_64", configuration, report=False, unsafe=False) diff --git a/tests/ahriman/application/handlers/test_handler_setup.py b/tests/ahriman/application/handlers/test_handler_setup.py index e2204479..f65f72ed 100644 --- a/tests/ahriman/application/handlers/test_handler_setup.py +++ b/tests/ahriman/application/handlers/test_handler_setup.py @@ -8,6 +8,7 @@ from unittest.mock import call as MockCall from ahriman.application.handlers import Setup from ahriman.core.configuration import Configuration +from ahriman.core.repository import Repository from ahriman.models.repository_paths import RepositoryPaths from ahriman.models.sign_settings import SignSettings @@ -36,13 +37,13 @@ def _default_args(args: argparse.Namespace) -> argparse.Namespace: return args -def test_run(args: argparse.Namespace, configuration: Configuration, repository_paths: RepositoryPaths, - mocker: MockerFixture) -> None: +def test_run(args: argparse.Namespace, configuration: Configuration, repository: Repository, + repository_paths: RepositoryPaths, mocker: MockerFixture) -> None: """ must run command """ args = _default_args(args) - mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") + mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) ahriman_configuration_mock = mocker.patch("ahriman.application.handlers.Setup.configuration_create_ahriman") devtools_configuration_mock = mocker.patch("ahriman.application.handlers.Setup.configuration_create_devtools") makepkg_configuration_mock = mocker.patch("ahriman.application.handlers.Setup.configuration_create_makepkg") diff --git a/tests/ahriman/application/handlers/test_handler_shell.py b/tests/ahriman/application/handlers/test_handler_shell.py index d7426a23..ad05e7b5 100644 --- a/tests/ahriman/application/handlers/test_handler_shell.py +++ b/tests/ahriman/application/handlers/test_handler_shell.py @@ -5,6 +5,7 @@ from pytest_mock import MockerFixture from ahriman.application.handlers import Shell from ahriman.core.configuration import Configuration +from ahriman.core.repository import Repository def _default_args(args: argparse.Namespace) -> argparse.Namespace: @@ -22,38 +23,41 @@ def _default_args(args: argparse.Namespace) -> argparse.Namespace: return args -def test_run(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None: +def test_run(args: argparse.Namespace, configuration: Configuration, repository: Repository, + mocker: MockerFixture) -> None: """ must run command """ args = _default_args(args) - mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") + mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) application_mock = mocker.patch("code.interact") Shell.run(args, "x86_64", configuration, report=False, unsafe=False) application_mock.assert_called_once_with(local=pytest.helpers.anyvar(int)) -def test_run_eval(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None: +def test_run_eval(args: argparse.Namespace, configuration: Configuration, repository: Repository, + mocker: MockerFixture) -> None: """ must run command """ args = _default_args(args) args.code = """print("hello world")""" - mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") + mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) application_mock = mocker.patch("code.InteractiveConsole.runcode") Shell.run(args, "x86_64", configuration, report=False, unsafe=False) application_mock.assert_called_once_with(args.code) -def test_run_verbose(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None: +def test_run_verbose(args: argparse.Namespace, configuration: Configuration, repository: Repository, + mocker: MockerFixture) -> None: """ must run command with verbose option """ args = _default_args(args) args.verbose = True - mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") + mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) print_mock = mocker.patch("ahriman.core.formatters.Printer.print") application_mock = mocker.patch("code.interact") diff --git a/tests/ahriman/application/handlers/test_handler_sign.py b/tests/ahriman/application/handlers/test_handler_sign.py index e1a10841..07fa1736 100644 --- a/tests/ahriman/application/handlers/test_handler_sign.py +++ b/tests/ahriman/application/handlers/test_handler_sign.py @@ -4,6 +4,7 @@ from pytest_mock import MockerFixture from ahriman.application.handlers import Sign from ahriman.core.configuration import Configuration +from ahriman.core.repository import Repository def _default_args(args: argparse.Namespace) -> argparse.Namespace: @@ -20,12 +21,13 @@ def _default_args(args: argparse.Namespace) -> argparse.Namespace: return args -def test_run(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None: +def test_run(args: argparse.Namespace, configuration: Configuration, repository: Repository, + mocker: MockerFixture) -> None: """ must run command """ args = _default_args(args) - mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") + mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) application_mock = mocker.patch("ahriman.application.application.Application.sign") Sign.run(args, "x86_64", configuration, report=False, unsafe=False) diff --git a/tests/ahriman/application/handlers/test_handler_status.py b/tests/ahriman/application/handlers/test_handler_status.py index ead701fa..f6c8a58e 100644 --- a/tests/ahriman/application/handlers/test_handler_status.py +++ b/tests/ahriman/application/handlers/test_handler_status.py @@ -5,6 +5,8 @@ from unittest.mock import call as MockCall from ahriman.application.handlers import Status from ahriman.core.configuration import Configuration +from ahriman.core.database import SQLite +from ahriman.core.repository import Repository from ahriman.models.build_status import BuildStatus, BuildStatusEnum from ahriman.models.package import Package @@ -27,13 +29,13 @@ def _default_args(args: argparse.Namespace) -> argparse.Namespace: return args -def test_run(args: argparse.Namespace, configuration: Configuration, package_ahriman: Package, - package_python_schedule: Package, mocker: MockerFixture) -> None: +def test_run(args: argparse.Namespace, configuration: Configuration, repository: Repository, + package_ahriman: Package, package_python_schedule: Package, mocker: MockerFixture) -> None: """ must run command """ args = _default_args(args) - mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") + mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) application_mock = mocker.patch("ahriman.core.status.client.Client.get_internal") packages_mock = mocker.patch("ahriman.core.status.client.Client.get", return_value=[(package_ahriman, BuildStatus(BuildStatusEnum.Success)), @@ -48,13 +50,14 @@ def test_run(args: argparse.Namespace, configuration: Configuration, package_ahr print_mock.assert_has_calls([MockCall(False) for _ in range(3)]) -def test_run_empty_exception(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None: +def test_run_empty_exception(args: argparse.Namespace, configuration: Configuration, repository: Repository, + mocker: MockerFixture) -> None: """ must raise ExitCode exception on empty status result """ args = _default_args(args) args.exit_code = True - mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") + mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) mocker.patch("ahriman.core.status.client.Client.get_internal") mocker.patch("ahriman.core.status.client.Client.get", return_value=[]) check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty") @@ -63,14 +66,14 @@ def test_run_empty_exception(args: argparse.Namespace, configuration: Configurat check_mock.assert_called_once_with(True, True) -def test_run_verbose(args: argparse.Namespace, configuration: Configuration, package_ahriman: Package, - mocker: MockerFixture) -> None: +def test_run_verbose(args: argparse.Namespace, configuration: Configuration, repository: Repository, + package_ahriman: Package, mocker: MockerFixture) -> None: """ must run command with detailed info """ args = _default_args(args) args.info = True - mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") + mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) mocker.patch("ahriman.core.status.client.Client.get", return_value=[(package_ahriman, BuildStatus(BuildStatusEnum.Success))]) print_mock = mocker.patch("ahriman.core.formatters.Printer.print") @@ -79,14 +82,14 @@ def test_run_verbose(args: argparse.Namespace, configuration: Configuration, pac print_mock.assert_has_calls([MockCall(True) for _ in range(2)]) -def test_run_with_package_filter(args: argparse.Namespace, configuration: Configuration, package_ahriman: Package, - mocker: MockerFixture) -> None: +def test_run_with_package_filter(args: argparse.Namespace, configuration: Configuration, repository: Repository, + package_ahriman: Package, mocker: MockerFixture) -> None: """ must run command with package filter """ args = _default_args(args) args.package = [package_ahriman.base] - mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") + mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) packages_mock = mocker.patch("ahriman.core.status.client.Client.get", return_value=[(package_ahriman, BuildStatus(BuildStatusEnum.Success))]) @@ -94,8 +97,8 @@ def test_run_with_package_filter(args: argparse.Namespace, configuration: Config packages_mock.assert_called_once_with(package_ahriman.base) -def test_run_by_status(args: argparse.Namespace, configuration: Configuration, package_ahriman: Package, - package_python_schedule: Package, mocker: MockerFixture) -> None: +def test_run_by_status(args: argparse.Namespace, configuration: Configuration, repository: Repository, + package_ahriman: Package, package_python_schedule: Package, mocker: MockerFixture) -> None: """ must filter packages by status """ @@ -104,23 +107,25 @@ def test_run_by_status(args: argparse.Namespace, configuration: Configuration, p mocker.patch("ahriman.core.status.client.Client.get", return_value=[(package_ahriman, BuildStatus(BuildStatusEnum.Success)), (package_python_schedule, BuildStatus(BuildStatusEnum.Failed))]) - mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") + mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) print_mock = mocker.patch("ahriman.core.formatters.Printer.print") Status.run(args, "x86_64", configuration, report=False, unsafe=False) print_mock.assert_has_calls([MockCall(False) for _ in range(2)]) -def test_imply_with_report(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None: +def test_imply_with_report(args: argparse.Namespace, configuration: Configuration, database: SQLite, + mocker: MockerFixture) -> None: """ must create application object with native reporting """ args = _default_args(args) - mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") - load_mock = mocker.patch("ahriman.core.status.client.Client.load") + mocker.patch("ahriman.core.database.SQLite.load", return_value=database) + load_mock = mocker.patch("ahriman.core.repository.Repository.load") Status.run(args, "x86_64", configuration, report=False, unsafe=False) - load_mock.assert_called_once_with(configuration, report=True) + load_mock.assert_called_once_with("x86_64", configuration, database, + report=True, unsafe=False, refresh_pacman_database=0) def test_disallow_auto_architecture_run() -> None: diff --git a/tests/ahriman/application/handlers/test_handler_status_update.py b/tests/ahriman/application/handlers/test_handler_status_update.py index 1d9072b8..d5c000c5 100644 --- a/tests/ahriman/application/handlers/test_handler_status_update.py +++ b/tests/ahriman/application/handlers/test_handler_status_update.py @@ -4,6 +4,8 @@ from pytest_mock import MockerFixture from ahriman.application.handlers import StatusUpdate from ahriman.core.configuration import Configuration +from ahriman.core.database import SQLite +from ahriman.core.repository import Repository from ahriman.models.action import Action from ahriman.models.build_status import BuildStatusEnum from ahriman.models.package import Package @@ -25,57 +27,60 @@ def _default_args(args: argparse.Namespace) -> argparse.Namespace: return args -def test_run(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None: +def test_run(args: argparse.Namespace, configuration: Configuration, repository: Repository, + mocker: MockerFixture) -> None: """ must run command """ args = _default_args(args) - mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") + mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) update_self_mock = mocker.patch("ahriman.core.status.client.Client.update_self") StatusUpdate.run(args, "x86_64", configuration, report=False, unsafe=False) update_self_mock.assert_called_once_with(args.status) -def test_run_packages(args: argparse.Namespace, configuration: Configuration, package_ahriman: Package, - mocker: MockerFixture) -> None: +def test_run_packages(args: argparse.Namespace, configuration: Configuration, repository: Repository, + package_ahriman: Package, mocker: MockerFixture) -> None: """ must run command with specified packages """ args = _default_args(args) args.package = [package_ahriman.base] - mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") + mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) update_mock = mocker.patch("ahriman.core.status.client.Client.update") StatusUpdate.run(args, "x86_64", configuration, report=False, unsafe=False) update_mock.assert_called_once_with(package_ahriman.base, args.status) -def test_run_remove(args: argparse.Namespace, configuration: Configuration, package_ahriman: Package, - mocker: MockerFixture) -> None: +def test_run_remove(args: argparse.Namespace, configuration: Configuration, repository: Repository, + package_ahriman: Package, mocker: MockerFixture) -> None: """ must remove package from status page """ args = _default_args(args) args.package = [package_ahriman.base] args.action = Action.Remove - mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") + mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) update_mock = mocker.patch("ahriman.core.status.client.Client.remove") StatusUpdate.run(args, "x86_64", configuration, report=False, unsafe=False) update_mock.assert_called_once_with(package_ahriman.base) -def test_imply_with_report(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None: +def test_imply_with_report(args: argparse.Namespace, configuration: Configuration, database: SQLite, + mocker: MockerFixture) -> None: """ must create application object with native reporting """ args = _default_args(args) - mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") - load_mock = mocker.patch("ahriman.core.status.client.Client.load") + mocker.patch("ahriman.core.database.SQLite.load", return_value=database) + load_mock = mocker.patch("ahriman.core.repository.Repository.load") StatusUpdate.run(args, "x86_64", configuration, report=False, unsafe=False) - load_mock.assert_called_once_with(configuration, report=True) + load_mock.assert_called_once_with("x86_64", configuration, database, + report=True, unsafe=False, refresh_pacman_database=0) def test_disallow_auto_architecture_run() -> None: diff --git a/tests/ahriman/application/handlers/test_handler_triggers.py b/tests/ahriman/application/handlers/test_handler_triggers.py index 801f35ea..7b115903 100644 --- a/tests/ahriman/application/handlers/test_handler_triggers.py +++ b/tests/ahriman/application/handlers/test_handler_triggers.py @@ -4,6 +4,7 @@ from pytest_mock import MockerFixture from ahriman.application.handlers import Triggers from ahriman.core.configuration import Configuration +from ahriman.core.repository import Repository from ahriman.models.package import Package from ahriman.models.result import Result @@ -22,12 +23,13 @@ def _default_args(args: argparse.Namespace) -> argparse.Namespace: return args -def test_run(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None: +def test_run(args: argparse.Namespace, configuration: Configuration, repository: Repository, + mocker: MockerFixture) -> None: """ must run command """ args = _default_args(args) - mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") + mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) application_mock = mocker.patch("ahriman.application.application.Application.on_result") on_start_mock = mocker.patch("ahriman.application.application.Application.on_start") @@ -36,15 +38,15 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc on_start_mock.assert_called_once_with() -def test_run_trigger(args: argparse.Namespace, configuration: Configuration, package_ahriman: Package, - mocker: MockerFixture) -> None: +def test_run_trigger(args: argparse.Namespace, configuration: Configuration, repository: Repository, + package_ahriman: Package, mocker: MockerFixture) -> None: """ must run triggers specified by command line """ args = _default_args(args) args.trigger = ["ahriman.core.report.ReportTrigger"] mocker.patch("ahriman.core.repository.Repository.packages", return_value=[package_ahriman]) - mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") + mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) report_mock = mocker.patch("ahriman.core.report.ReportTrigger.on_result") upload_mock = mocker.patch("ahriman.core.upload.UploadTrigger.on_result") diff --git a/tests/ahriman/application/handlers/test_handler_update.py b/tests/ahriman/application/handlers/test_handler_update.py index 365a6f76..6cca8f47 100644 --- a/tests/ahriman/application/handlers/test_handler_update.py +++ b/tests/ahriman/application/handlers/test_handler_update.py @@ -7,6 +7,7 @@ from unittest.mock import call as MockCall from ahriman.application.application import Application from ahriman.application.handlers import Update from ahriman.core.configuration import Configuration +from ahriman.core.repository import Repository from ahriman.models.package import Package from ahriman.models.result import Result @@ -32,15 +33,15 @@ def _default_args(args: argparse.Namespace) -> argparse.Namespace: return args -def test_run(args: argparse.Namespace, package_ahriman: Package, - configuration: Configuration, mocker: MockerFixture) -> None: +def test_run(args: argparse.Namespace, package_ahriman: Package, configuration: Configuration, repository: Repository, + mocker: MockerFixture) -> None: """ must run command """ args = _default_args(args) result = Result() result.add_success(package_ahriman) - mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") + mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) application_mock = mocker.patch("ahriman.application.application.Application.update", return_value=result) check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty") updates_mock = mocker.patch("ahriman.application.application.Application.updates", return_value=[package_ahriman]) @@ -54,14 +55,15 @@ def test_run(args: argparse.Namespace, package_ahriman: Package, on_start_mock.assert_called_once_with() -def test_run_empty_exception(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None: +def test_run_empty_exception(args: argparse.Namespace, configuration: Configuration, repository: Repository, + mocker: MockerFixture) -> None: """ must raise ExitCode exception on empty update list """ args = _default_args(args) args.exit_code = True args.dry_run = True - mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") + mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) mocker.patch("ahriman.application.application.Application.updates", return_value=[]) check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty") @@ -69,14 +71,14 @@ def test_run_empty_exception(args: argparse.Namespace, configuration: Configurat check_mock.assert_called_once_with(True, True) -def test_run_update_empty_exception(args: argparse.Namespace, package_ahriman: Package, - configuration: Configuration, mocker: MockerFixture) -> None: +def test_run_update_empty_exception(args: argparse.Namespace, package_ahriman: Package, configuration: Configuration, + repository: Repository, mocker: MockerFixture) -> None: """ must raise ExitCode exception on empty build result """ args = _default_args(args) args.exit_code = True - mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") + mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) mocker.patch("ahriman.application.application.Application.update", return_value=Result()) mocker.patch("ahriman.application.application.Application.updates", return_value=[package_ahriman]) check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty") @@ -85,13 +87,14 @@ def test_run_update_empty_exception(args: argparse.Namespace, package_ahriman: P check_mock.assert_has_calls([MockCall(True, False), MockCall(True, True)]) -def test_run_dry_run(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None: +def test_run_dry_run(args: argparse.Namespace, configuration: Configuration, repository: Repository, + mocker: MockerFixture) -> None: """ must run simplified command """ args = _default_args(args) args.dry_run = True - mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") + mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) application_mock = mocker.patch("ahriman.application.application.Application.update") check_mock = mocker.patch("ahriman.application.handlers.Handler.check_if_empty") updates_mock = mocker.patch("ahriman.application.application.Application.updates") diff --git a/tests/ahriman/application/handlers/test_handler_web.py b/tests/ahriman/application/handlers/test_handler_web.py index 6228a5aa..91d4698a 100644 --- a/tests/ahriman/application/handlers/test_handler_web.py +++ b/tests/ahriman/application/handlers/test_handler_web.py @@ -5,6 +5,7 @@ from pytest_mock import MockerFixture from ahriman.application.handlers import Web from ahriman.core.configuration import Configuration +from ahriman.core.repository import Repository def _default_args(args: argparse.Namespace) -> argparse.Namespace: @@ -21,13 +22,14 @@ def _default_args(args: argparse.Namespace) -> argparse.Namespace: return args -def test_run(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None: +def test_run(args: argparse.Namespace, configuration: Configuration, repository: Repository, + mocker: MockerFixture) -> None: """ must run command """ args = _default_args(args) mocker.patch("ahriman.core.spawn.Spawn.start") - mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") + mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) setup_mock = mocker.patch("ahriman.web.web.setup_service") run_mock = mocker.patch("ahriman.web.web.run_server") diff --git a/tests/ahriman/conftest.py b/tests/ahriman/conftest.py index 1f8ed85d..113358a7 100644 --- a/tests/ahriman/conftest.py +++ b/tests/ahriman/conftest.py @@ -10,6 +10,7 @@ from ahriman.core.alpm.pacman import Pacman from ahriman.core.auth import Auth from ahriman.core.configuration import Configuration from ahriman.core.database import SQLite +from ahriman.core.repository import Repository from ahriman.core.spawn import Spawn from ahriman.core.status.watcher import Watcher from ahriman.models.aur_package import AURPackage @@ -388,6 +389,24 @@ def remote_source() -> RemoteSource: return RemoteSource.from_source(PackageSource.AUR, "ahriman", "aur") +@pytest.fixture +def repository(configuration: Configuration, database: SQLite, mocker: MockerFixture) -> Repository: + """ + fixture for repository + + Args: + configuration(Configuration): configuration fixture + database(SQLite): database fixture + mocker(MockerFixture): mocker object + + Returns: + Repository: repository test instance + """ + mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") + mocker.patch("ahriman.core.repository.Repository._set_context") + return Repository.load("x86_64", configuration, database, report=False, unsafe=False) + + @pytest.fixture def repository_paths(configuration: Configuration) -> RepositoryPaths: """ @@ -444,17 +463,18 @@ def user() -> User: @pytest.fixture -def watcher(configuration: Configuration, database: SQLite, mocker: MockerFixture) -> Watcher: +def watcher(configuration: Configuration, database: SQLite, repository: Repository, mocker: MockerFixture) -> Watcher: """ package status watcher fixture Args: configuration(Configuration): configuration fixture database(SQLite): database fixture + repository(Repository): repository fixture mocker(MockerFixture): mocker object Returns: Watcher: package status watcher test instance """ - mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") + mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) return Watcher("x86_64", configuration, database) diff --git a/tests/ahriman/core/gitremote/test_remote_push.py b/tests/ahriman/core/gitremote/test_remote_push.py index 8bdff757..fb971b3c 100644 --- a/tests/ahriman/core/gitremote/test_remote_push.py +++ b/tests/ahriman/core/gitremote/test_remote_push.py @@ -5,48 +5,65 @@ from pytest_mock import MockerFixture from unittest.mock import call as MockCall from ahriman.core.configuration import Configuration +from ahriman.core.database import SQLite from ahriman.core.exceptions import GitRemoteError from ahriman.core.gitremote.remote_push import RemotePush from ahriman.models.package import Package +from ahriman.models.pkgbuild_patch import PkgbuildPatch from ahriman.models.result import Result -def test_package_update(package_ahriman: Package, mocker: MockerFixture) -> None: +def test_package_update(database: SQLite, configuration: Configuration, package_ahriman: Package, + mocker: MockerFixture) -> None: """ must update single package """ + patch1 = PkgbuildPatch(None, "patch") + patch2 = PkgbuildPatch("key", "value") + rmtree_mock = mocker.patch("shutil.rmtree") fetch_mock = mocker.patch("ahriman.core.build_tools.sources.Sources.fetch") + patches_mock = mocker.patch("ahriman.core.database.SQLite.patches_get", return_value=[patch1, patch2]) + patches_write_mock = mocker.patch("ahriman.models.pkgbuild_patch.PkgbuildPatch.write") + runner = RemotePush(configuration, database, "gitremote") local = Path("local") - RemotePush.package_update(package_ahriman, local) + assert runner.package_update(package_ahriman, local) == package_ahriman.base rmtree_mock.assert_has_calls([ MockCall(local / package_ahriman.base, ignore_errors=True), MockCall(local / package_ahriman.base / ".git", ignore_errors=True), ]) fetch_mock.assert_called_once_with(pytest.helpers.anyvar(int), package_ahriman.remote) + patches_mock.assert_called_once_with(package_ahriman.base) + patches_write_mock.assert_has_calls([ + MockCall(local / package_ahriman.base / f"ahriman-{package_ahriman.base}.patch"), + MockCall(local / package_ahriman.base / f"ahriman-{patch2.key}.patch"), + ]) -def test_packages_update(result: Result, package_ahriman: Package, mocker: MockerFixture) -> None: +def test_packages_update(database: SQLite, configuration: Configuration, result: Result, package_ahriman: Package, + mocker: MockerFixture) -> None: """ must generate packages update """ update_mock = mocker.patch("ahriman.core.gitremote.remote_push.RemotePush.package_update", return_value=[package_ahriman.base]) + runner = RemotePush(configuration, database, "gitremote") local = Path("local") - assert list(RemotePush.packages_update(result, local)) + assert list(runner.packages_update(result, local)) update_mock.assert_called_once_with(package_ahriman, local) -def test_run(configuration: Configuration, result: Result, package_ahriman: Package, mocker: MockerFixture) -> None: +def test_run(database: SQLite, configuration: Configuration, result: Result, package_ahriman: Package, + mocker: MockerFixture) -> None: """ must push changes on result """ mocker.patch("ahriman.core.gitremote.remote_push.RemotePush.packages_update", return_value=[package_ahriman.base]) fetch_mock = mocker.patch("ahriman.core.build_tools.sources.Sources.fetch") push_mock = mocker.patch("ahriman.core.build_tools.sources.Sources.push") - runner = RemotePush(configuration, "gitremote") + runner = RemotePush(configuration, database, "gitremote") runner.run(result) fetch_mock.assert_called_once_with(pytest.helpers.anyvar(int), runner.remote_source) @@ -55,12 +72,12 @@ def test_run(configuration: Configuration, result: Result, package_ahriman: Pack ) -def test_run_failed(configuration: Configuration, result: Result, mocker: MockerFixture) -> None: +def test_run_failed(database: SQLite, configuration: Configuration, result: Result, mocker: MockerFixture) -> None: """ must reraise exception on error occurred """ mocker.patch("ahriman.core.build_tools.sources.Sources.fetch", side_effect=Exception()) - runner = RemotePush(configuration, "gitremote") + runner = RemotePush(configuration, database, "gitremote") with pytest.raises(GitRemoteError): runner.run(result) diff --git a/tests/ahriman/core/gitremote/test_remote_push_trigger.py b/tests/ahriman/core/gitremote/test_remote_push_trigger.py index b9a0fd10..0ea9a728 100644 --- a/tests/ahriman/core/gitremote/test_remote_push_trigger.py +++ b/tests/ahriman/core/gitremote/test_remote_push_trigger.py @@ -1,18 +1,22 @@ from pytest_mock import MockerFixture from ahriman.core.configuration import Configuration +from ahriman.core.database import SQLite from ahriman.core.gitremote import RemotePushTrigger +from ahriman.models.context_key import ContextKey from ahriman.models.package import Package from ahriman.models.result import Result def test_on_result(configuration: Configuration, result: Result, package_ahriman: Package, - mocker: MockerFixture) -> None: + database: SQLite, mocker: MockerFixture) -> None: """ must push changes on result """ + database_mock = mocker.patch("ahriman.core._Context.get", return_value=database) run_mock = mocker.patch("ahriman.core.gitremote.remote_push.RemotePush.run") trigger = RemotePushTrigger("x86_64", configuration) trigger.on_result(result, [package_ahriman]) + database_mock.assert_called_once_with(ContextKey("database", SQLite)) run_mock.assert_called_once_with(result) diff --git a/tests/ahriman/core/repository/conftest.py b/tests/ahriman/core/repository/conftest.py index f81c87ca..041aca36 100644 --- a/tests/ahriman/core/repository/conftest.py +++ b/tests/ahriman/core/repository/conftest.py @@ -4,7 +4,6 @@ from pytest_mock import MockerFixture from ahriman.core.configuration import Configuration from ahriman.core.database import SQLite -from ahriman.core.repository import Repository from ahriman.core.repository.cleaner import Cleaner from ahriman.core.repository.executor import Executor from ahriman.core.repository.update_handler import UpdateHandler @@ -24,7 +23,7 @@ def cleaner(configuration: Configuration, database: SQLite, mocker: MockerFixtur Cleaner: cleaner test instance """ mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") - return Cleaner("x86_64", configuration, database, report=False, unsafe=False) + return Cleaner("x86_64", configuration, database, report=False, unsafe=False, refresh_pacman_database=0) @pytest.fixture @@ -45,24 +44,7 @@ def executor(configuration: Configuration, database: SQLite, mocker: MockerFixtu mocker.patch("ahriman.core.repository.cleaner.Cleaner.clear_packages") mocker.patch("ahriman.core.repository.cleaner.Cleaner.clear_queue") mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") - return Executor("x86_64", configuration, database, report=False, unsafe=False) - - -@pytest.fixture -def repository(configuration: Configuration, database: SQLite, mocker: MockerFixture) -> Repository: - """ - fixture for repository - - Args: - configuration(Configuration): configuration fixture - database(SQLite): database fixture - mocker(MockerFixture): mocker object - - Returns: - Repository: repository test instance - """ - mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") - return Repository("x86_64", configuration, database, report=False, unsafe=False) + return Executor("x86_64", configuration, database, report=False, unsafe=False, refresh_pacman_database=0) @pytest.fixture @@ -83,4 +65,4 @@ def update_handler(configuration: Configuration, database: SQLite, mocker: Mocke mocker.patch("ahriman.core.repository.cleaner.Cleaner.clear_packages") mocker.patch("ahriman.core.repository.cleaner.Cleaner.clear_queue") mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") - return UpdateHandler("x86_64", configuration, database, report=False, unsafe=False) + return UpdateHandler("x86_64", configuration, database, report=False, unsafe=False, refresh_pacman_database=0) diff --git a/tests/ahriman/core/repository/test_repository.py b/tests/ahriman/core/repository/test_repository.py index 7f4dd175..1827cee6 100644 --- a/tests/ahriman/core/repository/test_repository.py +++ b/tests/ahriman/core/repository/test_repository.py @@ -2,11 +2,42 @@ import pytest from pathlib import Path from pytest_mock import MockerFixture +from unittest.mock import call as MockCall +from ahriman.core.alpm.pacman import Pacman +from ahriman.core.configuration import Configuration +from ahriman.core.database import SQLite from ahriman.core.repository import Repository +from ahriman.core.sign.gpg import GPG +from ahriman.models.context_key import ContextKey from ahriman.models.package import Package +def test_load(configuration: Configuration, database: SQLite, mocker: MockerFixture) -> None: + """ + must correctly load instance + """ + context_mock = mocker.patch("ahriman.core.repository.Repository._set_context") + Repository.load("x86_64", configuration, database, report=False, unsafe=False) + context_mock.assert_called_once_with() + + +def test_set_context(configuration: Configuration, database: SQLite, mocker: MockerFixture) -> None: + """ + must set context variables + """ + set_mock = mocker.patch("ahriman.core._Context.set") + + instance = Repository.load("x86_64", configuration, database, report=False, unsafe=False) + set_mock.assert_has_calls([ + MockCall(ContextKey("database", SQLite), instance.database), + MockCall(ContextKey("configuration", Configuration), instance.configuration), + MockCall(ContextKey("pacman", Pacman), instance.pacman), + MockCall(ContextKey("sign", GPG), instance.sign), + MockCall(ContextKey("repository", Repository), instance), + ]) + + def test_load_archives(package_ahriman: Package, package_python_schedule: Package, repository: Repository, mocker: MockerFixture) -> None: """ diff --git a/tests/ahriman/core/repository/test_repository_properties.py b/tests/ahriman/core/repository/test_repository_properties.py index 61c745a9..552df736 100644 --- a/tests/ahriman/core/repository/test_repository_properties.py +++ b/tests/ahriman/core/repository/test_repository_properties.py @@ -12,7 +12,7 @@ def test_create_tree_on_load(configuration: Configuration, database: SQLite, moc """ mocker.patch("ahriman.core.repository.repository_properties.check_user") tree_create_mock = mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") - RepositoryProperties("x86_64", configuration, database, report=False, unsafe=False) + RepositoryProperties("x86_64", configuration, database, report=False, unsafe=False, refresh_pacman_database=0) tree_create_mock.assert_called_once_with() @@ -23,6 +23,6 @@ def test_create_tree_on_load_unsafe(configuration: Configuration, database: SQLi """ mocker.patch("ahriman.core.repository.repository_properties.check_user", side_effect=UnsafeRunError(0, 1)) tree_create_mock = mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") - RepositoryProperties("x86_64", configuration, database, report=False, unsafe=False) + RepositoryProperties("x86_64", configuration, database, report=False, unsafe=False, refresh_pacman_database=0) tree_create_mock.assert_not_called() diff --git a/tests/ahriman/core/status/test_watcher.py b/tests/ahriman/core/status/test_watcher.py index a35b9b12..dfadcb6c 100644 --- a/tests/ahriman/core/status/test_watcher.py +++ b/tests/ahriman/core/status/test_watcher.py @@ -6,7 +6,6 @@ from ahriman.core.configuration import Configuration from ahriman.core.database import SQLite from ahriman.core.exceptions import UnknownPackageError from ahriman.core.status.watcher import Watcher -from ahriman.core.status.web_client import WebClient from ahriman.models.build_status import BuildStatus, BuildStatusEnum from ahriman.models.log_record_id import LogRecordId from ahriman.models.package import Package @@ -17,10 +16,10 @@ def test_force_no_report(configuration: Configuration, database: SQLite, mocker: must force dummy report client """ configuration.set_option("web", "port", "8080") - mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") + load_mock = mocker.patch("ahriman.core.repository.Repository.load") watcher = Watcher("x86_64", configuration, database) - assert not isinstance(watcher.repository.reporter, WebClient) + load_mock.assert_called_once_with("x86_64", configuration, database, report=False, unsafe=False) def test_get(watcher: Watcher, package_ahriman: Package) -> None: diff --git a/tests/ahriman/core/test_context_init.py b/tests/ahriman/core/test_context_init.py new file mode 100644 index 00000000..ba4425f2 --- /dev/null +++ b/tests/ahriman/core/test_context_init.py @@ -0,0 +1,92 @@ +import pytest + +from ahriman.core import _Context +from ahriman.models.context_key import ContextKey + + +def test_get_set() -> None: + """ + must set and get variable + """ + key, value = ContextKey("key", int), 42 + ctx = _Context() + + ctx.set(key, value) + assert ctx.get(key) == value + + +def test_get_key_exception() -> None: + """ + must raise KeyError in case if key was not found + """ + ctx = _Context() + with pytest.raises(KeyError): + ctx.get(ContextKey("key", int)) + + +def test_get_value_exception() -> None: + """ + must raise ValueError in case if key type differs from existing value + """ + key, value = ContextKey("key", int), 42 + ctx = _Context() + ctx.set(key, value) + + with pytest.raises(ValueError): + ctx.get(ContextKey("key", str)) + + +def test_set_key_exception() -> None: + """ + must raise KeyError in case if key already exists + """ + key, value = ContextKey("key", int), 42 + ctx = _Context() + ctx.set(key, value) + + with pytest.raises(KeyError): + ctx.set(key, value) + + +def test_set_value_exception() -> None: + """ + must raise ValueError in case if key type differs from new value + """ + ctx = _Context() + with pytest.raises(ValueError): + ctx.set(ContextKey("key", str), 42) + + +def test_contains() -> None: + """ + must correctly check if element is in list + """ + key, value = ContextKey("key", int), 42 + ctx = _Context() + ctx.set(key, value) + + assert key not in ctx + assert key.key in ctx + assert "random-key" not in ctx + + +def test_iter() -> None: + """ + must return keys iterator + """ + key, value = ContextKey("key", int), 42 + ctx = _Context() + ctx.set(key, value) + + assert set(iter(ctx)) == set(iter({key.key: value})) + + +def test_len() -> None: + """ + must correctly define collection length + """ + ctx = _Context() + ctx.set(ContextKey("str", str), "str") + ctx.set(ContextKey("int", int), 42) + + assert len(ctx) == 2 diff --git a/tests/ahriman/models/test_context_key.py b/tests/ahriman/models/test_context_key.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/ahriman/web/conftest.py b/tests/ahriman/web/conftest.py index 1f9fde8f..c1ee8172 100644 --- a/tests/ahriman/web/conftest.py +++ b/tests/ahriman/web/conftest.py @@ -12,6 +12,7 @@ import ahriman.core.auth.helpers from ahriman.core.auth import OAuth from ahriman.core.configuration import Configuration from ahriman.core.database import SQLite +from ahriman.core.repository import Repository from ahriman.core.spawn import Spawn from ahriman.models.user import User from ahriman.web.web import setup_service @@ -48,7 +49,7 @@ def request(app: web.Application, path: str, method: str, json: Any = None, data @pytest.fixture -def application(configuration: Configuration, spawner: Spawn, database: SQLite, +def application(configuration: Configuration, spawner: Spawn, database: SQLite, repository: Repository, mocker: MockerFixture) -> web.Application: """ application fixture @@ -57,20 +58,21 @@ def application(configuration: Configuration, spawner: Spawn, database: SQLite, configuration(Configuration): configuration fixture spawner(Spawn): spawner fixture database(SQLite): database fixture + repository(Repository): repository fixture mocker(MockerFixture): mocker object Returns: web.Application: application test instance """ mocker.patch("ahriman.core.database.SQLite.load", return_value=database) - mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") + mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) mocker.patch.object(ahriman.core.auth.helpers, "_has_aiohttp_security", False) return setup_service("x86_64", configuration, spawner) @pytest.fixture def application_with_auth(configuration: Configuration, user: User, spawner: Spawn, database: SQLite, - mocker: MockerFixture) -> web.Application: + repository: Repository, mocker: MockerFixture) -> web.Application: """ application fixture with auth enabled @@ -79,6 +81,7 @@ def application_with_auth(configuration: Configuration, user: User, spawner: Spa user(User): user descriptor fixture spawner(Spawn): spawner fixture database(SQLite): database fixture + repository(Repository): repository fixture mocker(MockerFixture): mocker object Returns: @@ -86,7 +89,7 @@ def application_with_auth(configuration: Configuration, user: User, spawner: Spa """ configuration.set_option("auth", "target", "configuration") mocker.patch("ahriman.core.database.SQLite.load", return_value=database) - mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") + mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) mocker.patch.object(ahriman.core.auth.helpers, "_has_aiohttp_security", True) application = setup_service("x86_64", configuration, spawner) @@ -98,7 +101,7 @@ def application_with_auth(configuration: Configuration, user: User, spawner: Spa @pytest.fixture def application_with_debug(configuration: Configuration, user: User, spawner: Spawn, database: SQLite, - mocker: MockerFixture) -> web.Application: + repository: Repository, mocker: MockerFixture) -> web.Application: """ application fixture with debug enabled @@ -107,6 +110,7 @@ def application_with_debug(configuration: Configuration, user: User, spawner: Sp user(User): user descriptor fixture spawner(Spawn): spawner fixture database(SQLite): database fixture + repository(Repository): repository fixture mocker(MockerFixture): mocker object Returns: @@ -114,7 +118,7 @@ def application_with_debug(configuration: Configuration, user: User, spawner: Sp """ configuration.set_option("web", "debug", "yes") mocker.patch("ahriman.core.database.SQLite.load", return_value=database) - mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") + mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) mocker.patch.object(ahriman.core.auth.helpers, "_has_aiohttp_security", False) return setup_service("x86_64", configuration, spawner)