Compare commits

...

8 Commits

Author SHA1 Message Date
10798b9ba3 fix: correctly process trigger repo specific settings in validator (see #154) 2025-08-01 16:53:15 +03:00
358e3dc4d2 feat: expose repository name and architecure in configuration if available
In some cases there are reference to current repository settings. In
order to handle it correctly two ro options have been added

Related to #154
2025-07-31 14:14:22 +03:00
c13cd029bc feat: fully readable configuration from environment 2025-07-23 14:49:38 +03:00
ae32cc8fbb type: use custom comparable for comparable functions 2025-07-15 21:20:49 +03:00
dff5b775a9 refactor: move logs rotation to separated trigger which is enabled by default
Previous solution, well, worked kinda fine-ish, though we have much
better mechanisms to do so
2025-07-15 11:26:00 +03:00
db3f20546e fix: do not update datalist if search substring hasn't changed 2025-07-14 21:30:27 +03:00
53368468a4 fix: block autoupdate on any modal opened 2025-07-14 21:12:33 +03:00
228c2cce51 style: use parebtgeses-less exceptions in side effects (tests only) 2025-07-14 20:33:54 +03:00
66 changed files with 533 additions and 209 deletions

View File

@ -0,0 +1,21 @@
ahriman.core.housekeeping package
=================================
Submodules
----------
ahriman.core.housekeeping.logs\_rotation\_trigger module
--------------------------------------------------------
.. automodule:: ahriman.core.housekeeping.logs_rotation_trigger
:members:
:no-undoc-members:
:show-inheritance:
Module contents
---------------
.. automodule:: ahriman.core.housekeeping
:members:
:no-undoc-members:
:show-inheritance:

View File

@ -15,6 +15,7 @@ Subpackages
ahriman.core.distributed
ahriman.core.formatters
ahriman.core.gitremote
ahriman.core.housekeeping
ahriman.core.http
ahriman.core.log
ahriman.core.report

View File

@ -40,6 +40,7 @@ This package contains everything required for the most of application actions an
* ``ahriman.core.distributed`` package with triggers and helpers for distributed build system.
* ``ahriman.core.formatters`` package provides ``Printer`` sub-classes for printing data (e.g. package properties) to stdout which are used by some handlers.
* ``ahriman.core.gitremote`` is a package with remote PKGBUILD triggers. Should not be called directly.
* ``ahriman.core.housekeeping`` package provides few triggers for removing old data.
* ``ahriman.core.http`` package provides HTTP clients which can be used later by other classes.
* ``ahriman.core.log`` is a log utils package. It includes logger loader class, custom HTTP based logger and some wrappers.
* ``ahriman.core.report`` is a package with reporting triggers. Should not be called directly.

View File

@ -65,6 +65,8 @@ will try to read value from ``SECRET`` environment variable. In case if the requ
will eventually lead ``key`` option in section ``section1`` to be set to the value of ``HOME`` environment variable (if available).
Moreover, configuration can be read from environment variables directly by following the same naming convention, e.g. in the example above, one can have environment variable named ``section1:key`` (e.g. ``section1:key=$HOME``) and it will be substituted to the configuration with the highest priority.
There is also additional subcommand which will allow to validate configuration and print found errors. In order to do so, run ``service-config-validate`` subcommand, e.g.:
.. code-block:: shell
@ -81,7 +83,6 @@ Base configuration settings.
* ``apply_migrations`` - perform database migrations on the application start, boolean, optional, default ``yes``. Useful if you are using git version. Note, however, that this option must be changed only if you know what to do and going to handle migrations manually.
* ``database`` - path to the application SQLite database, string, required.
* ``include`` - path to directory with configuration files overrides, string, optional. Files will be read in alphabetical order.
* ``keep_last_logs`` - amount of build logs to be kept for each package, integer, optional ,default ``0``. Logs will be cleared at the end of each process.
* ``logging`` - path to logging configuration, string, required. Check ``logging.ini`` for reference.
``alpm:*`` groups
@ -138,6 +139,8 @@ Build related configuration. Group name can refer to architecture, e.g. ``build:
Base repository settings.
* ``architecture`` - repository architecture, string. This field is read-only and generated automatically from run options if possible.
* ``name`` - repository name, string. This field is read-only and generated automatically from run options if possible.
* ``root`` - root path for application, string, required.
``sign:*`` groups
@ -180,7 +183,7 @@ Web server settings. This feature requires ``aiohttp`` libraries to be installed
* ``wait_timeout`` - wait timeout in seconds, maximum amount of time to be waited before lock will be free, integer, optional.
``keyring`` group
--------------------
-----------------
Keyring package generator plugin.
@ -198,6 +201,13 @@ Keyring generator plugin
* ``revoked`` - list of revoked packagers keys, space separated list of strings, optional.
* ``trusted`` - list of master keys, space separated list of strings, optional, if not set, the ``key`` option from ``sign`` group will be used.
``housekeeping`` group
----------------------
This section describes settings for the ``ahriman.core.housekeeping.LogsRotationTrigger`` plugin.
* ``keep_last_logs`` - amount of build logs to be kept for each package, integer, optional ,default ``0``. Logs will be cleared at the end of each process.
``mirrorlist`` group
--------------------

View File

@ -40,6 +40,7 @@ package_ahriman-core() {
'rsync: sync by using rsync')
install="$pkgbase.install"
backup=('etc/ahriman.ini'
'etc/ahriman.ini.d/00-housekeeping.ini'
'etc/ahriman.ini.d/logging.ini')
cd "$pkgbase-$pkgver"
@ -49,6 +50,7 @@ package_ahriman-core() {
# keep usr/share configs as reference and copy them to /etc
install -Dm644 "$pkgdir/usr/share/$pkgbase/settings/ahriman.ini" "$pkgdir/etc/ahriman.ini"
install -Dm644 "$pkgdir/usr/share/$pkgbase/settings/ahriman.ini.d/00-housekeeping.ini" "$pkgdir/etc/ahriman.ini.d/00-housekeeping.ini"
install -Dm644 "$pkgdir/usr/share/$pkgbase/settings/ahriman.ini.d/logging.ini" "$pkgdir/etc/ahriman.ini.d/logging.ini"
install -Dm644 "$srcdir/$pkgbase.sysusers" "$pkgdir/usr/lib/sysusers.d/$pkgbase.conf"

View File

@ -7,8 +7,6 @@ logging = ahriman.ini.d/logging.ini
;apply_migrations = yes
; Path to the application SQLite database.
database = ${repository:root}/ahriman.db
; Keep last build logs for each package
keep_last_logs = 5
[alpm]
; Path to pacman system database cache.
@ -45,9 +43,11 @@ triggers[] = ahriman.core.gitremote.RemotePullTrigger
triggers[] = ahriman.core.report.ReportTrigger
triggers[] = ahriman.core.upload.UploadTrigger
triggers[] = ahriman.core.gitremote.RemotePushTrigger
triggers[] = ahriman.core.housekeeping.LogsRotationTrigger
; List of well-known triggers. Used only for configuration purposes.
triggers_known[] = ahriman.core.gitremote.RemotePullTrigger
triggers_known[] = ahriman.core.gitremote.RemotePushTrigger
triggers_known[] = ahriman.core.housekeeping.LogsRotationTrigger
triggers_known[] = ahriman.core.report.ReportTrigger
triggers_known[] = ahriman.core.upload.UploadTrigger
; Maximal age in seconds of the VCS packages before their version will be updated with its remote source.

View File

@ -0,0 +1,3 @@
[logs-rotation]
; Keep last build logs for each package
keep_last_logs = 5

View File

@ -148,8 +148,19 @@
packageAddInput.addEventListener("keyup", _ => {
clearTimeout(packageAddInput.requestTimeout);
// do not update datalist if search string didn't change yet
const value = packageAddInput.value;
const previousValue = packageAddInput.dataset.previousValue;
if (value === previousValue) {
return;
}
// store current search string in attributes
packageAddInput.dataset.previousValue = value;
// perform data list update
packageAddInput.requestTimeout = setTimeout(_ => {
const value = packageAddInput.value;
if (value.length >= 3) {
makeRequest(

View File

@ -164,7 +164,7 @@
function toggleTableAutoReload(interval) {
clearInterval(tableAutoReloadTask);
tableAutoReloadTask = toggleAutoReload(tableAutoReloadButton, interval, tableAutoReloadInput, _ => {
if (!dashboardModal.classList.contains("show") &&
if (!hasActiveModal() &&
!hasActiveDropdown()) {
packagesLoad();
statusLoad();

View File

@ -68,6 +68,11 @@
.some(el => el.classList.contains("show"));
}
function hasActiveModal() {
return Array.from(document.querySelectorAll(".modal"))
.some(el => el.classList.contains("show"));
}
function headerClass(status) {
if (status === "pending") return ["bg-warning"];
if (status === "building") return ["bg-warning"];

View File

@ -28,6 +28,7 @@ from ahriman.core.alpm.remote import AUR, Official
from ahriman.core.configuration import Configuration
from ahriman.core.exceptions import OptionError
from ahriman.core.formatters import AurPrinter
from ahriman.core.types import Comparable
from ahriman.models.aur_package import AURPackage
from ahriman.models.repository_id import RepositoryId
@ -115,7 +116,7 @@ class Search(Handler):
raise OptionError(sort_by)
# always sort by package name at the last
# well technically it is not a string, but we can deal with it
comparator: Callable[[AURPackage], tuple[str, str]] =\
comparator: Callable[[AURPackage], Comparable] = \
lambda package: (getattr(package, sort_by), package.name)
return sorted(packages, key=comparator)

View File

@ -25,6 +25,7 @@ from ahriman.application.application import Application
from ahriman.application.handlers.handler import Handler, SubParserAction
from ahriman.core.configuration import Configuration
from ahriman.core.formatters import PackagePrinter, StatusPrinter
from ahriman.core.types import Comparable
from ahriman.core.utils import enum_values
from ahriman.models.build_status import BuildStatus, BuildStatusEnum
from ahriman.models.package import Package
@ -64,7 +65,7 @@ class Status(Handler):
Status.check_status(args.exit_code, packages)
comparator: Callable[[tuple[Package, BuildStatus]], str] = lambda item: item[0].base
comparator: Callable[[tuple[Package, BuildStatus]], Comparable] = lambda item: item[0].base
filter_fn: Callable[[tuple[Package, BuildStatus]], bool] =\
lambda item: args.status is None or item[1].status == args.status
for package, package_status in sorted(filter(filter_fn, packages), key=comparator):

View File

@ -52,7 +52,7 @@ class Validate(Handler):
"""
from ahriman.core.configuration.validator import Validator
schema = Validate.schema(repository_id, configuration)
schema = Validate.schema(configuration)
validator = Validator(configuration=configuration, schema=schema)
if validator.validate(configuration.dump()):
@ -83,12 +83,11 @@ class Validate(Handler):
return parser
@staticmethod
def schema(repository_id: RepositoryId, configuration: Configuration) -> ConfigurationSchema:
def schema(configuration: Configuration) -> ConfigurationSchema:
"""
get schema with triggers
Args:
repository_id(RepositoryId): repository unique identifier
configuration(Configuration): configuration instance
Returns:
@ -107,12 +106,12 @@ class Validate(Handler):
continue
# default settings if any
for schema_name, schema in trigger_class.configuration_schema(repository_id, None).items():
for schema_name, schema in trigger_class.configuration_schema(None).items():
erased = Validate.schema_erase_required(copy.deepcopy(schema))
root[schema_name] = Validate.schema_merge(root.get(schema_name, {}), erased)
# settings according to enabled triggers
for schema_name, schema in trigger_class.configuration_schema(repository_id, configuration).items():
for schema_name, schema in trigger_class.configuration_schema(configuration).items():
root[schema_name] = Validate.schema_merge(root.get(schema_name, {}), copy.deepcopy(schema))
return root

View File

@ -19,6 +19,7 @@
#
# pylint: disable=too-many-public-methods
import configparser
import os
import shlex
import sys
@ -42,7 +43,6 @@ class Configuration(configparser.RawConfigParser):
SYSTEM_CONFIGURATION_PATH(Path): (class attribute) default system configuration path distributed by package
includes(list[Path]): list of includes which were read
path(Path | None): path to root configuration file
repository_id(RepositoryId | None): repository unique identifier
Examples:
Configuration class provides additional method in order to handle application configuration. Since this class is
@ -93,7 +93,7 @@ class Configuration(configparser.RawConfigParser):
},
)
self.repository_id: RepositoryId | None = None
self._repository_id: RepositoryId | None = None
self.path: Path | None = None
self.includes: list[Path] = []
@ -128,6 +128,32 @@ class Configuration(configparser.RawConfigParser):
"""
return self.getpath("settings", "logging")
@property
def repository_id(self) -> RepositoryId | None:
"""
repository identifier
Returns:
RepositoryId: repository unique identifier
"""
return self._repository_id
@repository_id.setter
def repository_id(self, repository_id: RepositoryId | None) -> None:
"""
setter for repository identifier
Args:
repository_id(RepositoryId | None): repository unique identifier
"""
self._repository_id = repository_id
if repository_id is None or repository_id.is_empty:
self.remove_option("repository", "name")
self.remove_option("repository", "architecture")
else:
self.set_option("repository", "name", repository_id.name)
self.set_option("repository", "architecture", repository_id.architecture)
@property
def repository_name(self) -> str:
"""
@ -164,6 +190,7 @@ class Configuration(configparser.RawConfigParser):
"""
configuration = cls()
configuration.load(path)
configuration.load_environment()
configuration.merge_sections(repository_id)
return configuration
@ -288,6 +315,16 @@ class Configuration(configparser.RawConfigParser):
self.read(self.path)
self.load_includes() # load includes
def load_environment(self) -> None:
"""
load environment variables into configuration
"""
for name, value in os.environ.items():
if ":" not in name:
continue
section, key = name.rsplit(":", maxsplit=1)
self.set_option(section, key, value)
def load_includes(self, path: Path | None = None) -> None:
"""
load configuration includes from specified path
@ -356,11 +393,16 @@ class Configuration(configparser.RawConfigParser):
"""
reload configuration if possible or raise exception otherwise
"""
# get current properties and validate input
path, repository_id = self.check_loaded()
for section in self.sections(): # clear current content
# clear current content
for section in self.sections():
self.remove_section(section)
self.load(path)
self.merge_sections(repository_id)
# create another instance and copy values from there
instance = self.from_path(path, repository_id)
self.copy_from(instance)
def set_option(self, section: str, option: str, value: str) -> None:
"""

View File

@ -45,11 +45,6 @@ CONFIGURATION_SCHEMA: ConfigurationSchema = {
"path_exists": True,
"path_type": "dir",
},
"keep_last_logs": {
"type": "integer",
"coerce": "integer",
"min": 0,
},
"logging": {
"type": "path",
"coerce": "absolute_path",
@ -254,6 +249,10 @@ CONFIGURATION_SCHEMA: ConfigurationSchema = {
"repository": {
"type": "dict",
"schema": {
"architecture": {
"type": "string",
"empty": False,
},
"name": {
"type": "string",
"empty": False,

View File

@ -0,0 +1,20 @@
#
# Copyright (c) 2021-2025 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 <http://www.gnu.org/licenses/>.
#
from ahriman.core.housekeeping.logs_rotation_trigger import LogsRotationTrigger

View File

@ -0,0 +1,87 @@
#
# Copyright (c) 2021-2025 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 <http://www.gnu.org/licenses/>.
#
from ahriman.core import context
from ahriman.core.configuration import Configuration
from ahriman.core.status import Client
from ahriman.core.triggers import Trigger
from ahriman.models.package import Package
from ahriman.models.repository_id import RepositoryId
from ahriman.models.result import Result
class LogsRotationTrigger(Trigger):
"""
rotate logs after build processes
Attributes:
keep_last_records(int): number of last records to keep
"""
CONFIGURATION_SCHEMA = {
"logs-rotation": {
"type": "dict",
"schema": {
"keep_last_logs": {
"type": "integer",
"required": True,
"coerce": "integer",
"min": 0,
},
},
},
}
def __init__(self, repository_id: RepositoryId, configuration: Configuration) -> None:
"""
Args:
repository_id(RepositoryId): repository unique identifier
configuration(Configuration): configuration instance
"""
Trigger.__init__(self, repository_id, configuration)
section = next(iter(self.configuration_sections(configuration)))
self.keep_last_records = configuration.getint( # read old-style first and then fallback to new style
"settings", "keep_last_logs",
fallback=configuration.getint(section, "keep_last_logs"))
@classmethod
def configuration_sections(cls, configuration: Configuration) -> list[str]:
"""
extract configuration sections from configuration
Args:
configuration(Configuration): configuration instance
Returns:
list[str]: read configuration sections belong to this trigger
"""
return list(cls.CONFIGURATION_SCHEMA.keys())
def on_result(self, result: Result, packages: list[Package]) -> None:
"""
run trigger
Args:
result(Result): build result
packages(list[Package]): list of all available packages
"""
ctx = context.get()
reporter = ctx.get(Client)
reporter.logs_rotate(self.keep_last_records)

View File

@ -17,7 +17,6 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
import atexit
import logging
import uuid
@ -37,7 +36,6 @@ class HttpLogHandler(logging.Handler):
method
Attributes:
keep_last_records(int): number of last records to keep
reporter(Client): build status reporter instance
suppress_errors(bool): suppress logging errors (e.g. if no web server available)
"""
@ -56,7 +54,6 @@ class HttpLogHandler(logging.Handler):
self.reporter = Client.load(repository_id, configuration, report=report)
self.suppress_errors = suppress_errors
self.keep_last_records = configuration.getint("settings", "keep_last_logs", fallback=0)
@classmethod
def load(cls, repository_id: RepositoryId, configuration: Configuration, *, report: bool) -> Self:
@ -83,7 +80,6 @@ class HttpLogHandler(logging.Handler):
root.addHandler(handler)
LogRecordId.DEFAULT_PROCESS_ID = str(uuid.uuid4()) # assign default process identifier for log records
atexit.register(handler.rotate)
return handler
@ -104,9 +100,3 @@ class HttpLogHandler(logging.Handler):
if self.suppress_errors:
return
self.handleError(record)
def rotate(self) -> None:
"""
rotate log records, removing older ones
"""
self.reporter.logs_rotate(self.keep_last_records)

View File

@ -26,6 +26,7 @@ from typing import Any
from ahriman.core.configuration import Configuration
from ahriman.core.sign.gpg import GPG
from ahriman.core.types import Comparable
from ahriman.core.utils import pretty_datetime, pretty_size, utcnow
from ahriman.models.repository_id import RepositoryId
from ahriman.models.result import Result
@ -111,7 +112,7 @@ class JinjaTemplate:
Returns:
list[dict[str, str]]: sorted content according to comparator defined
"""
comparator: Callable[[dict[str, str]], str] = lambda item: item["filename"]
comparator: Callable[[dict[str, str]], Comparable] = lambda item: item["filename"]
return sorted(content, key=comparator)
def make_html(self, result: Result, template_name: Path | str) -> str:

View File

@ -28,6 +28,7 @@ from ahriman.core.configuration import Configuration
from ahriman.core.report.jinja_template import JinjaTemplate
from ahriman.core.report.report import Report
from ahriman.core.status import Client
from ahriman.core.types import Comparable
from ahriman.models.event import EventType
from ahriman.models.package import Package
from ahriman.models.repository_id import RepositoryId
@ -86,7 +87,7 @@ class RSS(Report, JinjaTemplate):
Returns:
list[dict[str, str]]: sorted content according to comparator defined
"""
comparator: Callable[[dict[str, str]], datetime.datetime] = \
comparator: Callable[[dict[str, str]], Comparable] = \
lambda item: parsedate_to_datetime(item["build_date"])
return sorted(content, key=comparator, reverse=True)

View File

@ -80,8 +80,7 @@ class Trigger(LazyLogging):
return self.repository_id.architecture
@classmethod
def configuration_schema(cls, repository_id: RepositoryId,
configuration: Configuration | None) -> ConfigurationSchema:
def configuration_schema(cls, configuration: Configuration | None) -> ConfigurationSchema:
"""
configuration schema based on supplied service configuration
@ -89,7 +88,6 @@ class Trigger(LazyLogging):
Schema must be in cerberus format, for details and examples you can check built-in triggers.
Args:
repository_id(str): repository unique identifier
configuration(Configuration | None): configuration instance. If set to None, the default schema
should be returned
@ -101,13 +99,15 @@ class Trigger(LazyLogging):
result: ConfigurationSchema = {}
for target in cls.configuration_sections(configuration):
if not configuration.has_section(target):
continue
section, schema_name = configuration.gettype(
target, repository_id, fallback=cls.CONFIGURATION_SCHEMA_FALLBACK)
if schema_name not in cls.CONFIGURATION_SCHEMA:
continue
result[section] = cls.CONFIGURATION_SCHEMA[schema_name]
for section in configuration.sections():
if not (section == target or section.startswith(f"{target}:")):
# either repository specific or exact name
continue
schema_name = configuration.get(section, "type", fallback=section)
if schema_name not in cls.CONFIGURATION_SCHEMA:
continue
result[section] = cls.CONFIGURATION_SCHEMA[schema_name]
return result

View File

@ -17,7 +17,15 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
from typing import Protocol
from typing import Any, Protocol
class Comparable(Protocol):
"""
class which supports :func:`__lt__` operation`
"""
def __lt__(self, other: Any) -> bool: ...
class HasBool(Protocol):

View File

@ -21,6 +21,7 @@ from aiohttp.web import HTTPBadRequest, HTTPNoContent, Response, json_response
from collections.abc import Callable
from typing import ClassVar
from ahriman.core.types import Comparable
from ahriman.models.user_access import UserAccess
from ahriman.models.worker import Worker
from ahriman.web.apispec.decorators import apidocs
@ -74,7 +75,7 @@ class WorkersView(BaseView):
"""
workers = self.workers.workers
comparator: Callable[[Worker], str] = lambda item: item.identifier
comparator: Callable[[Worker], Comparable] = lambda item: item.identifier
response = [worker.view() for worker in sorted(workers, key=comparator)]
return json_response(response)

View File

@ -23,6 +23,7 @@ from aiohttp.web import HTTPNoContent, Response, json_response
from collections.abc import Callable
from typing import ClassVar
from ahriman.core.types import Comparable
from ahriman.models.build_status import BuildStatus
from ahriman.models.package import Package
from ahriman.models.user_access import UserAccess
@ -68,7 +69,7 @@ class PackagesView(StatusViewGuard, BaseView):
repository_id = self.repository_id()
packages = self.service(repository_id).packages
comparator: Callable[[tuple[Package, BuildStatus]], str] = lambda items: items[0].base
comparator: Callable[[tuple[Package, BuildStatus]], Comparable] = lambda items: items[0].base
response = [
{
"package": package.view(),

View File

@ -22,6 +22,7 @@ from collections.abc import Callable
from typing import ClassVar
from ahriman.core.alpm.remote import AUR
from ahriman.core.types import Comparable
from ahriman.models.aur_package import AURPackage
from ahriman.models.user_access import UserAccess
from ahriman.web.apispec.decorators import apidocs
@ -70,10 +71,11 @@ class SearchView(BaseView):
if not packages:
raise HTTPNotFound(reason=f"No packages found for terms: {search}")
comparator: Callable[[AURPackage], tuple[bool, bool, str]] = lambda item: (
item.package_base not in search, # inverted because False < True
not any(item.package_base.startswith(term) for term in search), # same as above
item.package_base,
comparator: Callable[[AURPackage], Comparable] = \
lambda item: (
item.package_base not in search, # inverted because False < True
not any(item.package_base.startswith(term) for term in search), # same as above
item.package_base,
)
response = [
{

View File

@ -141,7 +141,7 @@ def test_add_remote_missing(application_packages: ApplicationPackages, mocker: M
"""
must raise UnknownPackageError if remote package wasn't found
"""
mocker.patch("requests.get", side_effect=Exception())
mocker.patch("requests.get", side_effect=Exception)
with pytest.raises(UnknownPackageError):
application_packages._add_remote("url")

View File

@ -135,7 +135,7 @@ def test_unknown_no_aur(application_repository: ApplicationRepository, package_a
must return empty list in case if there is locally stored PKGBUILD
"""
mocker.patch("ahriman.core.repository.repository.Repository.packages", return_value=[package_ahriman])
mocker.patch("ahriman.models.package.Package.from_aur", side_effect=Exception())
mocker.patch("ahriman.models.package.Package.from_aur", side_effect=Exception)
mocker.patch("ahriman.models.package.Package.from_build", return_value=package_ahriman)
mocker.patch("pathlib.Path.is_dir", return_value=True)
mocker.patch("ahriman.core.build_tools.sources.Sources.has_remotes", return_value=False)
@ -149,7 +149,7 @@ def test_unknown_no_aur_no_local(application_repository: ApplicationRepository,
must return list of packages missing in aur and in local storage
"""
mocker.patch("ahriman.core.repository.repository.Repository.packages", return_value=[package_ahriman])
mocker.patch("ahriman.models.package.Package.from_aur", side_effect=Exception())
mocker.patch("ahriman.models.package.Package.from_aur", side_effect=Exception)
mocker.patch("pathlib.Path.is_dir", return_value=False)
packages = application_repository.unknown()

View File

@ -46,7 +46,7 @@ def test_call_exception(args: argparse.Namespace, configuration: Configuration,
"""
args.configuration = Path("")
args.quiet = False
mocker.patch("ahriman.core.configuration.Configuration.from_path", side_effect=Exception())
mocker.patch("ahriman.core.configuration.Configuration.from_path", side_effect=Exception)
logging_mock = mocker.patch("logging.Logger.exception")
_, repository_id = configuration.check_loaded()
@ -60,7 +60,7 @@ def test_call_exit_code(args: argparse.Namespace, configuration: Configuration,
"""
args.configuration = Path("")
args.quiet = False
mocker.patch("ahriman.core.configuration.Configuration.from_path", side_effect=ExitCode())
mocker.patch("ahriman.core.configuration.Configuration.from_path", side_effect=ExitCode)
logging_mock = mocker.patch("logging.Logger.exception")
_, repository_id = configuration.check_loaded()

View File

@ -2,6 +2,7 @@ import argparse
import json
import pytest
from pathlib import Path
from pytest_mock import MockerFixture
from ahriman.application.handlers.validate import Validate
@ -53,12 +54,50 @@ def test_run_skip(args: argparse.Namespace, configuration: Configuration, mocker
print_mock.assert_not_called()
def test_run_default(args: argparse.Namespace, configuration: Configuration) -> None:
"""
must run on default configuration without errors
"""
args.exit_code = True
_, repository_id = configuration.check_loaded()
default = Configuration.from_path(Configuration.SYSTEM_CONFIGURATION_PATH, repository_id)
# copy autogenerated values
for section, key in (("build", "build_command"), ("repository", "root")):
value = configuration.get(section, key)
default.set_option(section, key, value)
Validate.run(args, repository_id, default, report=False)
def test_run_repo_specific_triggers(args: argparse.Namespace, configuration: Configuration,
resource_path_root: Path) -> None:
"""
must correctly insert repo specific triggers
"""
args.exit_code = True
_, repository_id = configuration.check_loaded()
# remove unused sections
for section in ("customs3", "github:x86_64", "logs-rotation", "mirrorlist"):
configuration.remove_section(section)
configuration.set_option("report", "target", "test")
for section in ("test", "test:i686", "test:another-repo:x86_64"):
configuration.set_option(section, "type", "html")
configuration.set_option(section, "link_path", "http://link_path")
configuration.set_option(section, "path", "path")
configuration.set_option(section, "template", "template")
configuration.set_option(section, "templates", str(resource_path_root))
Validate.run(args, repository_id, configuration, report=False)
def test_schema(configuration: Configuration) -> None:
"""
must generate full schema correctly
"""
_, repository_id = configuration.check_loaded()
schema = Validate.schema(repository_id, configuration)
schema = Validate.schema(configuration)
# defaults
assert schema.pop("console")
@ -91,9 +130,7 @@ def test_schema_invalid_trigger(configuration: Configuration) -> None:
"""
configuration.set_option("build", "triggers", "some.invalid.trigger.path.Trigger")
configuration.remove_option("build", "triggers_known")
_, repository_id = configuration.check_loaded()
assert Validate.schema(repository_id, configuration) == CONFIGURATION_SCHEMA
assert Validate.schema(configuration) == CONFIGURATION_SCHEMA
def test_schema_erase_required() -> None:

View File

@ -230,7 +230,7 @@ def test_clear_close_exception(lock: Lock) -> None:
must suppress IO exception on file closure
"""
close_mock = lock._pid_file = MagicMock()
close_mock.close.side_effect = IOError()
close_mock.close.side_effect = IOError
lock.clear()

View File

@ -108,7 +108,7 @@ def test_aur_request_failed(aur: AUR, mocker: MockerFixture) -> None:
"""
must reraise generic exception
"""
mocker.patch("requests.Session.request", side_effect=Exception())
mocker.patch("requests.Session.request", side_effect=Exception)
with pytest.raises(Exception):
aur.aur_request("info", "ahriman")
@ -116,7 +116,7 @@ def test_aur_request_failed(aur: AUR, mocker: MockerFixture) -> None:
def test_aur_request_failed_http_error(aur: AUR, mocker: MockerFixture) -> None:
""" must reraise http exception
"""
mocker.patch("requests.Session.request", side_effect=requests.HTTPError())
mocker.patch("requests.Session.request", side_effect=requests.HTTPError)
with pytest.raises(requests.HTTPError):
aur.aur_request("info", "ahriman")

View File

@ -80,7 +80,7 @@ def test_arch_request_failed(official: Official, mocker: MockerFixture) -> None:
"""
must reraise generic exception
"""
mocker.patch("requests.Session.request", side_effect=Exception())
mocker.patch("requests.Session.request", side_effect=Exception)
with pytest.raises(Exception):
official.arch_request("akonadi", by="q")
@ -89,7 +89,7 @@ def test_arch_request_failed_http_error(official: Official, mocker: MockerFixtur
"""
must reraise http exception
"""
mocker.patch("requests.Session.request", side_effect=requests.HTTPError())
mocker.patch("requests.Session.request", side_effect=requests.HTTPError)
with pytest.raises(requests.HTTPError):
official.arch_request("akonadi", by="q")

View File

@ -242,7 +242,7 @@ def test_files_no_entry(pacman: Pacman, pyalpm_package_ahriman: pyalpm.Package,
pacman.handle = handle_mock
tar_mock = MagicMock()
tar_mock.extractfile.side_effect = KeyError()
tar_mock.extractfile.side_effect = KeyError
open_mock = MagicMock()
open_mock.__enter__.return_value = tar_mock

View File

@ -131,7 +131,7 @@ def test_sync_exception(pacman_database: PacmanDatabase, mocker: MockerFixture)
"""
must suppress all exceptions on failure
"""
mocker.patch("ahriman.core.alpm.pacman_database.PacmanDatabase.sync_packages", side_effect=Exception())
mocker.patch("ahriman.core.alpm.pacman_database.PacmanDatabase.sync_packages", side_effect=Exception)
pacman_database.sync(force=True)

View File

@ -52,7 +52,7 @@ def test_repo_remove_fail_no_file(repo: Repo, mocker: MockerFixture) -> None:
must fail on missing file
"""
mocker.patch("pathlib.Path.glob", return_value=[Path("package.pkg.tar.xz")])
mocker.patch("pathlib.Path.unlink", side_effect=FileNotFoundError())
mocker.patch("pathlib.Path.unlink", side_effect=FileNotFoundError)
with pytest.raises(FileNotFoundError):
repo.remove("package", Path("package.pkg.tar.xz"))

View File

@ -90,7 +90,7 @@ async def test_get_oauth_username_exception_1(oauth: OAuth, mocker: MockerFixtur
"""
must return None in case of OAuth request error (get_access_token)
"""
mocker.patch("aioauth_client.GoogleClient.get_access_token", side_effect=Exception())
mocker.patch("aioauth_client.GoogleClient.get_access_token", side_effect=Exception)
user_info_mock = mocker.patch("aioauth_client.GoogleClient.user_info")
email = await oauth.get_oauth_username("code")
@ -103,7 +103,7 @@ async def test_get_oauth_username_exception_2(oauth: OAuth, mocker: MockerFixtur
must return None in case of OAuth request error (user_info)
"""
mocker.patch("aioauth_client.GoogleClient.get_access_token", return_value=("token", ""))
mocker.patch("aioauth_client.GoogleClient.user_info", side_effect=Exception())
mocker.patch("aioauth_client.GoogleClient.user_info", side_effect=Exception)
email = await oauth.get_oauth_username("code")
assert email is None

View File

@ -1,8 +1,8 @@
import configparser
from io import StringIO
import pytest
import os
from io import StringIO
from pathlib import Path
from pytest_mock import MockerFixture
from unittest.mock import call as MockCall
@ -20,6 +20,40 @@ def test_architecture(configuration: Configuration) -> None:
assert configuration.architecture == "x86_64"
def test_repository_id(configuration: Configuration, repository_id: RepositoryId) -> None:
"""
must return repository identifier
"""
assert configuration.repository_id == repository_id
assert configuration.get("repository", "name") == repository_id.name
assert configuration.get("repository", "architecture") == repository_id.architecture
def test_repository_id_erase(configuration: Configuration) -> None:
"""
must remove repository identifier properties if empty identifier supplied
"""
configuration.repository_id = None
assert configuration.get("repository", "name", fallback=None) is None
assert configuration.get("repository", "architecture", fallback=None) is None
configuration.repository_id = RepositoryId("", "")
assert configuration.get("repository", "name", fallback=None) is None
assert configuration.get("repository", "architecture", fallback=None) is None
def test_repository_id_update(configuration: Configuration, repository_id: RepositoryId) -> None:
"""
must update repository identifier and related configuration options
"""
repository_id = RepositoryId("i686", repository_id.name)
configuration.repository_id = repository_id
assert configuration.repository_id == repository_id
assert configuration.get("repository", "name") == repository_id.name
assert configuration.get("repository", "architecture") == repository_id.architecture
def test_repository_name(configuration: Configuration) -> None:
"""
must return valid repository name
@ -42,12 +76,16 @@ def test_from_path(repository_id: RepositoryId, mocker: MockerFixture) -> None:
mocker.patch("ahriman.core.configuration.Configuration.get", return_value="ahriman.ini.d")
read_mock = mocker.patch("ahriman.core.configuration.Configuration.read")
load_includes_mock = mocker.patch("ahriman.core.configuration.Configuration.load_includes")
merge_mock = mocker.patch("ahriman.core.configuration.Configuration.merge_sections")
environment_mock = mocker.patch("ahriman.core.configuration.Configuration.load_environment")
path = Path("path")
configuration = Configuration.from_path(path, repository_id)
assert configuration.path == path
read_mock.assert_called_once_with(path)
load_includes_mock.assert_called_once_with()
merge_mock.assert_called_once_with(repository_id)
environment_mock.assert_called_once_with()
def test_from_path_file_missing(repository_id: RepositoryId, mocker: MockerFixture) -> None:
@ -324,6 +362,18 @@ def test_gettype_from_section_no_section(configuration: Configuration) -> None:
configuration.gettype("rsync:x86_64", configuration.repository_id)
def test_load_environment(configuration: Configuration) -> None:
"""
must load environment variables
"""
os.environ["section:key"] = "value1"
os.environ["section:identifier:key"] = "value2"
configuration.load_environment()
assert configuration.get("section", "key") == "value1"
assert configuration.get("section:identifier", "key") == "value2"
def test_load_includes(mocker: MockerFixture) -> None:
"""
must load includes
@ -444,10 +494,12 @@ def test_reload(configuration: Configuration, mocker: MockerFixture) -> None:
"""
load_mock = mocker.patch("ahriman.core.configuration.Configuration.load")
merge_mock = mocker.patch("ahriman.core.configuration.Configuration.merge_sections")
environment_mock = mocker.patch("ahriman.core.configuration.Configuration.load_environment")
configuration.reload()
load_mock.assert_called_once_with(configuration.path)
merge_mock.assert_called_once_with(configuration.repository_id)
environment_mock.assert_called_once_with()
def test_reload_clear(configuration: Configuration, mocker: MockerFixture) -> None:

View File

@ -42,7 +42,7 @@ def test_apply_migration_exception(migrations: Migrations, mocker: MockerFixture
must roll back and close cursor on exception during migration
"""
cursor = MagicMock()
mocker.patch("logging.Logger.info", side_effect=Exception())
mocker.patch("logging.Logger.info", side_effect=Exception)
migrations.connection.cursor.return_value = cursor
with pytest.raises(Exception):
@ -59,7 +59,7 @@ def test_apply_migration_sql_exception(migrations: Migrations) -> None:
must close cursor on general migration error
"""
cursor = MagicMock()
cursor.execute.side_effect = Exception()
cursor.execute.side_effect = Exception
migrations.connection.cursor.return_value = cursor
with pytest.raises(Exception):

View File

@ -37,7 +37,7 @@ def test_register_failed(distributed_system: DistributedSystem, mocker: MockerFi
"""
must suppress any exception happened during worker registration
"""
mocker.patch("requests.Session.request", side_effect=Exception())
mocker.patch("requests.Session.request", side_effect=Exception)
distributed_system.register()
@ -45,7 +45,7 @@ def test_register_failed_http_error(distributed_system: DistributedSystem, mocke
"""
must suppress HTTP exception happened during worker registration
"""
mocker.patch("requests.Session.request", side_effect=requests.HTTPError())
mocker.patch("requests.Session.request", side_effect=requests.HTTPError)
distributed_system.register()
@ -70,7 +70,7 @@ def test_workers_failed(distributed_system: DistributedSystem, mocker: MockerFix
"""
must suppress any exception happened during worker extraction
"""
mocker.patch("requests.Session.request", side_effect=Exception())
mocker.patch("requests.Session.request", side_effect=Exception)
distributed_system.workers()
@ -78,5 +78,5 @@ def test_workers_failed_http_error(distributed_system: DistributedSystem, mocker
"""
must suppress HTTP exception happened during worker extraction
"""
mocker.patch("requests.Session.request", side_effect=requests.HTTPError())
mocker.patch("requests.Session.request", side_effect=requests.HTTPError)
distributed_system.workers()

View File

@ -85,7 +85,7 @@ def test_run_failed(configuration: Configuration, mocker: MockerFixture) -> None
"""
must reraise exception on error occurred
"""
mocker.patch("ahriman.core.gitremote.remote_pull.RemotePull.repo_clone", side_effect=Exception())
mocker.patch("ahriman.core.gitremote.remote_pull.RemotePull.repo_clone", side_effect=Exception)
_, repository_id = configuration.check_loaded()
runner = RemotePull(repository_id, configuration, "gitremote")

View File

@ -82,7 +82,7 @@ def test_run_failed(local_client: Client, configuration: Configuration, result:
"""
must reraise exception on error occurred
"""
mocker.patch("ahriman.core.build_tools.sources.Sources.fetch", side_effect=Exception())
mocker.patch("ahriman.core.build_tools.sources.Sources.fetch", side_effect=Exception)
runner = RemotePush(local_client, configuration, "gitremote")
with pytest.raises(GitRemoteError):

View File

@ -0,0 +1,19 @@
import pytest
from ahriman.core.configuration import Configuration
from ahriman.core.housekeeping import LogsRotationTrigger
@pytest.fixture
def logs_rotation_trigger(configuration: Configuration) -> LogsRotationTrigger:
"""
logs roration trigger fixture
Args:
configuration(Configuration): configuration fixture
Returns:
LogsRotationTrigger: logs rotation trigger test instance
"""
_, repository_id = configuration.check_loaded()
return LogsRotationTrigger(repository_id, configuration)

View File

@ -0,0 +1,26 @@
from pytest_mock import MockerFixture
from unittest.mock import MagicMock
from ahriman.core.configuration import Configuration
from ahriman.core.housekeeping import LogsRotationTrigger
from ahriman.core.status import Client
from ahriman.models.result import Result
def test_configuration_sections(configuration: Configuration) -> None:
"""
must correctly parse target list
"""
assert LogsRotationTrigger.configuration_sections(configuration) == ["logs-rotation"]
def test_rotate(logs_rotation_trigger: LogsRotationTrigger, mocker: MockerFixture) -> None:
"""
must rotate logs
"""
client_mock = MagicMock()
context_mock = mocker.patch("ahriman.core._Context.get", return_value=client_mock)
logs_rotation_trigger.on_result(Result(), [])
context_mock.assert_called_once_with(Client)
client_mock.logs_rotate.assert_called_once_with(logs_rotation_trigger.keep_last_records)

View File

@ -51,7 +51,7 @@ def test_login_failed(ahriman_client: SyncAhrimanClient, user: User, mocker: Moc
must suppress any exception happened during login
"""
ahriman_client.user = user
mocker.patch("requests.Session.request", side_effect=Exception())
mocker.patch("requests.Session.request", side_effect=Exception)
ahriman_client._login(requests.Session())
@ -60,7 +60,7 @@ def test_login_failed_http_error(ahriman_client: SyncAhrimanClient, user: User,
must suppress HTTP exception happened during login
"""
ahriman_client.user = user
mocker.patch("requests.Session.request", side_effect=requests.HTTPError())
mocker.patch("requests.Session.request", side_effect=requests.HTTPError)
ahriman_client._login(requests.Session())

View File

@ -124,7 +124,7 @@ def test_make_request_failed(mocker: MockerFixture) -> None:
"""
must process request errors
"""
mocker.patch("requests.Session.request", side_effect=Exception())
mocker.patch("requests.Session.request", side_effect=Exception)
logging_mock = mocker.patch("logging.Logger.exception")
with pytest.raises(Exception):
@ -136,7 +136,7 @@ def test_make_request_suppress_errors(mocker: MockerFixture) -> None:
"""
must suppress request errors correctly
"""
mocker.patch("requests.Session.request", side_effect=Exception())
mocker.patch("requests.Session.request", side_effect=Exception)
logging_mock = mocker.patch("logging.Logger.exception")
with pytest.raises(Exception):

View File

@ -20,14 +20,12 @@ def test_load(configuration: Configuration, mocker: MockerFixture) -> None:
add_mock = mocker.patch("logging.Logger.addHandler")
load_mock = mocker.patch("ahriman.core.status.Client.load")
atexit_mock = mocker.patch("atexit.register")
_, repository_id = configuration.check_loaded()
handler = HttpLogHandler.load(repository_id, configuration, report=False)
assert handler
add_mock.assert_called_once_with(handler)
load_mock.assert_called_once_with(repository_id, configuration, report=False)
atexit_mock.assert_called_once_with(handler.rotate)
def test_load_exist(configuration: Configuration) -> None:
@ -61,7 +59,7 @@ def test_emit_failed(configuration: Configuration, log_record: logging.LogRecord
must call handle error on exception
"""
log_record.package_id = LogRecordId(package_ahriman.base, package_ahriman.version)
mocker.patch("ahriman.core.status.Client.package_logs_add", side_effect=Exception())
mocker.patch("ahriman.core.status.Client.package_logs_add", side_effect=Exception)
handle_error_mock = mocker.patch("logging.Handler.handleError")
_, repository_id = configuration.check_loaded()
handler = HttpLogHandler(repository_id, configuration, report=False, suppress_errors=False)
@ -76,7 +74,7 @@ def test_emit_suppress_failed(configuration: Configuration, log_record: logging.
must not call handle error on exception if suppress flag is set
"""
log_record.package_id = LogRecordId(package_ahriman.base, package_ahriman.version)
mocker.patch("ahriman.core.status.Client.package_logs_add", side_effect=Exception())
mocker.patch("ahriman.core.status.Client.package_logs_add", side_effect=Exception)
handle_error_mock = mocker.patch("logging.Handler.handleError")
_, repository_id = configuration.check_loaded()
handler = HttpLogHandler(repository_id, configuration, report=False, suppress_errors=True)
@ -96,16 +94,3 @@ def test_emit_skip(configuration: Configuration, log_record: logging.LogRecord,
handler.emit(log_record)
log_mock.assert_not_called()
def test_rotate(configuration: Configuration, mocker: MockerFixture) -> None:
"""
must rotate logs
"""
rotate_mock = mocker.patch("ahriman.core.status.Client.logs_rotate")
_, repository_id = configuration.check_loaded()
handler = HttpLogHandler(repository_id, configuration, report=False, suppress_errors=False)
handler.rotate()
rotate_mock.assert_called_once_with(handler.keep_last_records)

View File

@ -61,7 +61,7 @@ def test_load_fallback(configuration: Configuration, mocker: MockerFixture) -> N
"""
must fall back to stderr without errors
"""
mocker.patch("ahriman.core.log.log_loader.fileConfig", side_effect=PermissionError())
mocker.patch("ahriman.core.log.log_loader.fileConfig", side_effect=PermissionError)
_, repository_id = configuration.check_loaded()
LogLoader.load(repository_id, configuration, LogHandler.Journald, quiet=False, report=False)

View File

@ -13,7 +13,7 @@ def test_report_failure(configuration: Configuration, mocker: MockerFixture) ->
"""
must raise ReportFailed on errors
"""
mocker.patch("ahriman.core.report.html.HTML.generate", side_effect=Exception())
mocker.patch("ahriman.core.report.html.HTML.generate", side_effect=Exception)
_, repository_id = configuration.check_loaded()
with pytest.raises(ReportError):

View File

@ -41,7 +41,7 @@ def test_send_failed(telegram: Telegram, mocker: MockerFixture) -> None:
"""
must reraise generic exception
"""
mocker.patch("requests.Session.request", side_effect=Exception())
mocker.patch("requests.Session.request", side_effect=Exception)
with pytest.raises(Exception):
telegram._send("a text")
@ -50,7 +50,7 @@ def test_send_failed_http_error(telegram: Telegram, mocker: MockerFixture) -> No
"""
must reraise http exception
"""
mocker.patch("requests.Session.request", side_effect=requests.HTTPError())
mocker.patch("requests.Session.request", side_effect=requests.HTTPError)
with pytest.raises(requests.HTTPError):
telegram._send("a text")

View File

@ -67,7 +67,7 @@ def test_process_build_failure(executor: Executor, package_ahriman: Package, moc
mocker.patch("ahriman.core.repository.executor.Executor.packages_built")
mocker.patch("ahriman.core.build_tools.task.Task.build", return_value=[Path(package_ahriman.base)])
mocker.patch("ahriman.core.build_tools.task.Task.init")
mocker.patch("shutil.move", side_effect=Exception())
mocker.patch("shutil.move", side_effect=Exception)
status_client_mock = mocker.patch("ahriman.core.status.Client.set_failed")
executor.process_build([package_ahriman])
@ -151,7 +151,7 @@ def test_process_remove_failed(executor: Executor, package_ahriman: Package, moc
must suppress tree clear errors during package base removal
"""
mocker.patch("ahriman.core.repository.executor.Executor.packages", return_value=[package_ahriman])
mocker.patch("ahriman.core.status.local_client.LocalClient.package_remove", side_effect=Exception())
mocker.patch("ahriman.core.status.local_client.LocalClient.package_remove", side_effect=Exception)
executor.process_remove([package_ahriman.base])
@ -160,7 +160,7 @@ def test_process_remove_tree_clear_failed(executor: Executor, package_ahriman: P
must suppress remove errors
"""
mocker.patch("ahriman.core.repository.executor.Executor.packages", return_value=[package_ahriman])
mocker.patch("ahriman.core.alpm.repo.Repo.remove", side_effect=Exception())
mocker.patch("ahriman.core.alpm.repo.Repo.remove", side_effect=Exception)
executor.process_remove([package_ahriman.base])
@ -277,7 +277,7 @@ def test_process_update_failed(executor: Executor, package_ahriman: Package, moc
"""
must process update for failed package
"""
mocker.patch("shutil.move", side_effect=Exception())
mocker.patch("shutil.move", side_effect=Exception)
mocker.patch("ahriman.core.repository.executor.Executor.load_archives", return_value=[package_ahriman])
mocker.patch("ahriman.core.repository.executor.Executor.packages", return_value=[package_ahriman])
status_client_mock = mocker.patch("ahriman.core.status.Client.set_failed")

View File

@ -40,7 +40,7 @@ def test_load_archives_failed(package_info: PackageInfo, mocker: MockerFixture)
"""
must skip packages which cannot be loaded
"""
mocker.patch("ahriman.models.package.Package.from_archive", side_effect=Exception())
mocker.patch("ahriman.models.package.Package.from_archive", side_effect=Exception)
assert not package_info.load_archives([Path("a.pkg.tar.xz")])

View File

@ -59,7 +59,7 @@ def test_updates_aur_failed(update_handler: UpdateHandler, package_ahriman: Pack
must update status via client for failed load
"""
mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.packages", return_value=[package_ahriman])
mocker.patch("ahriman.models.package.Package.from_aur", side_effect=Exception())
mocker.patch("ahriman.models.package.Package.from_aur", side_effect=Exception)
status_client_mock = mocker.patch("ahriman.core.status.Client.set_failed")
update_handler.updates_aur([], vcs=True)
@ -281,7 +281,7 @@ def test_updates_local_with_failures(update_handler: UpdateHandler, package_ahri
"""
mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.packages")
mocker.patch("pathlib.Path.iterdir", return_value=[Path(package_ahriman.base)])
mocker.patch("ahriman.core.build_tools.sources.Sources.fetch", side_effect=Exception())
mocker.patch("ahriman.core.build_tools.sources.Sources.fetch", side_effect=Exception)
assert not update_handler.updates_local(vcs=True)
@ -336,6 +336,6 @@ def test_updates_manual_with_failures(update_handler: UpdateHandler, package_ahr
"""
must process manual through the packages with failure
"""
mocker.patch("ahriman.core.database.SQLite.build_queue_get", side_effect=Exception())
mocker.patch("ahriman.core.database.SQLite.build_queue_get", side_effect=Exception)
mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.packages", return_value=[package_ahriman])
assert update_handler.updates_manual() == []

View File

@ -83,7 +83,7 @@ def test_key_download_failure(gpg: GPG, mocker: MockerFixture) -> None:
"""
must download the key from public server and log error if any (and raise it again)
"""
mocker.patch("requests.Session.request", side_effect=requests.HTTPError())
mocker.patch("requests.Session.request", side_effect=requests.HTTPError)
with pytest.raises(requests.HTTPError):
gpg.key_download("keyserver.ubuntu.com", "0xE989490C")

View File

@ -120,7 +120,7 @@ def test_configuration_reload_failed(web_client: WebClient, mocker: MockerFixtur
"""
must suppress any exception happened during configuration reload
"""
mocker.patch("requests.Session.request", side_effect=Exception())
mocker.patch("requests.Session.request", side_effect=Exception)
web_client.configuration_reload()
@ -128,7 +128,7 @@ def test_configuration_reload_failed_http_error(web_client: WebClient, mocker: M
"""
must suppress HTTP exception happened during configuration reload
"""
mocker.patch("requests.Session.request", side_effect=requests.HTTPError())
mocker.patch("requests.Session.request", side_effect=requests.HTTPError)
web_client.configuration_reload()
@ -137,7 +137,7 @@ def test_configuration_reload_failed_suppress(web_client: WebClient, mocker: Moc
must suppress any exception happened during configuration reload and don't log
"""
web_client.suppress_errors = True
mocker.patch("requests.Session.request", side_effect=Exception())
mocker.patch("requests.Session.request", side_effect=Exception)
logging_mock = mocker.patch("logging.exception")
web_client.configuration_reload()
@ -149,7 +149,7 @@ def test_configuration_reload_failed_http_error_suppress(web_client: WebClient,
must suppress HTTP exception happened during configuration reload and don't log
"""
web_client.suppress_errors = True
mocker.patch("requests.Session.request", side_effect=requests.HTTPError())
mocker.patch("requests.Session.request", side_effect=requests.HTTPError)
logging_mock = mocker.patch("logging.exception")
web_client.configuration_reload()
@ -172,7 +172,7 @@ def test_event_add_failed(web_client: WebClient, mocker: MockerFixture) -> None:
"""
must suppress any exception happened during events creation
"""
mocker.patch("requests.Session.request", side_effect=Exception())
mocker.patch("requests.Session.request", side_effect=Exception)
web_client.event_add(Event("", ""))
@ -180,7 +180,7 @@ def test_event_add_failed_http_error(web_client: WebClient, mocker: MockerFixtur
"""
must suppress HTTP exception happened during events creation
"""
mocker.patch("requests.Session.request", side_effect=requests.HTTPError())
mocker.patch("requests.Session.request", side_effect=requests.HTTPError)
web_client.event_add(Event("", ""))
@ -189,7 +189,7 @@ def test_event_add_failed_suppress(web_client: WebClient, mocker: MockerFixture)
must suppress any exception happened during events creation and don't log
"""
web_client.suppress_errors = True
mocker.patch("requests.Session.request", side_effect=Exception())
mocker.patch("requests.Session.request", side_effect=Exception)
logging_mock = mocker.patch("logging.exception")
web_client.event_add(Event("", ""))
@ -201,7 +201,7 @@ def test_event_add_failed_http_error_suppress(web_client: WebClient, mocker: Moc
must suppress HTTP exception happened during events creation and don't log
"""
web_client.suppress_errors = True
mocker.patch("requests.Session.request", side_effect=requests.HTTPError())
mocker.patch("requests.Session.request", side_effect=requests.HTTPError)
logging_mock = mocker.patch("logging.exception")
web_client.event_add(Event("", ""))
@ -271,7 +271,7 @@ def test_event_get_failed(web_client: WebClient, mocker: MockerFixture) -> None:
"""
must suppress any exception happened during events fetch
"""
mocker.patch("requests.Session.request", side_effect=Exception())
mocker.patch("requests.Session.request", side_effect=Exception)
web_client.event_get(None, None)
@ -279,7 +279,7 @@ def test_event_get_failed_http_error(web_client: WebClient, mocker: MockerFixtur
"""
must suppress HTTP exception happened during events fetch
"""
mocker.patch("requests.Session.request", side_effect=requests.HTTPError())
mocker.patch("requests.Session.request", side_effect=requests.HTTPError)
web_client.event_get(None, None)
@ -288,7 +288,7 @@ def test_event_get_failed_suppress(web_client: WebClient, mocker: MockerFixture)
must suppress any exception happened during events fetch and don't log
"""
web_client.suppress_errors = True
mocker.patch("requests.Session.request", side_effect=Exception())
mocker.patch("requests.Session.request", side_effect=Exception)
logging_mock = mocker.patch("logging.exception")
web_client.event_get(None, None)
@ -300,7 +300,7 @@ def test_event_get_failed_http_error_suppress(web_client: WebClient, mocker: Moc
must suppress HTTP exception happened during events fetch and don't log
"""
web_client.suppress_errors = True
mocker.patch("requests.Session.request", side_effect=requests.HTTPError())
mocker.patch("requests.Session.request", side_effect=requests.HTTPError)
logging_mock = mocker.patch("logging.exception")
web_client.event_get(None, None)
@ -322,7 +322,7 @@ def test_logs_rotate_failed(web_client: WebClient, mocker: MockerFixture) -> Non
"""
must suppress any exception happened during logs rotation
"""
mocker.patch("requests.Session.request", side_effect=Exception())
mocker.patch("requests.Session.request", side_effect=Exception)
web_client.logs_rotate(42)
@ -330,7 +330,7 @@ def test_logs_rotate_failed_http_error(web_client: WebClient, mocker: MockerFixt
"""
must suppress HTTP exception happened during logs rotation
"""
mocker.patch("requests.Session.request", side_effect=requests.HTTPError())
mocker.patch("requests.Session.request", side_effect=requests.HTTPError)
web_client.logs_rotate(42)
@ -339,7 +339,7 @@ def test_logs_rotate_failed_suppress(web_client: WebClient, mocker: MockerFixtur
must suppress any exception happened during logs rotation and don't log
"""
web_client.suppress_errors = True
mocker.patch("requests.Session.request", side_effect=Exception())
mocker.patch("requests.Session.request", side_effect=Exception)
logging_mock = mocker.patch("logging.exception")
web_client.logs_rotate(42)
@ -351,7 +351,7 @@ def test_logs_rotate_failed_http_error_suppress(web_client: WebClient, mocker: M
must suppress HTTP exception happened during logs rotation and don't log
"""
web_client.suppress_errors = True
mocker.patch("requests.Session.request", side_effect=requests.HTTPError())
mocker.patch("requests.Session.request", side_effect=requests.HTTPError)
logging_mock = mocker.patch("logging.exception")
web_client.logs_rotate(42)
@ -379,7 +379,7 @@ def test_package_changes_get_failed(web_client: WebClient, package_ahriman: Pack
"""
must suppress any exception happened during changes fetch
"""
mocker.patch("requests.Session.request", side_effect=Exception())
mocker.patch("requests.Session.request", side_effect=Exception)
web_client.package_changes_get(package_ahriman.base)
@ -388,7 +388,7 @@ def test_package_changes_get_failed_http_error(web_client: WebClient, package_ah
"""
must suppress HTTP exception happened during changes fetch
"""
mocker.patch("requests.Session.request", side_effect=requests.HTTPError())
mocker.patch("requests.Session.request", side_effect=requests.HTTPError)
web_client.package_changes_get(package_ahriman.base)
@ -398,7 +398,7 @@ def test_package_changes_get_failed_suppress(web_client: WebClient, package_ahri
must suppress any exception happened during changes fetch and don't log
"""
web_client.suppress_errors = True
mocker.patch("requests.Session.request", side_effect=Exception())
mocker.patch("requests.Session.request", side_effect=Exception)
logging_mock = mocker.patch("logging.exception")
web_client.package_changes_get(package_ahriman.base)
@ -411,7 +411,7 @@ def test_package_changes_get_failed_http_error_suppress(web_client: WebClient, p
must suppress HTTP exception happened during changes fetch and don't log
"""
web_client.suppress_errors = True
mocker.patch("requests.Session.request", side_effect=requests.HTTPError())
mocker.patch("requests.Session.request", side_effect=requests.HTTPError)
logging_mock = mocker.patch("logging.exception")
web_client.package_changes_get(package_ahriman.base)
@ -434,7 +434,7 @@ def test_package_changes_update_failed(web_client: WebClient, package_ahriman: P
"""
must suppress any exception happened during changes update
"""
mocker.patch("requests.Session.request", side_effect=Exception())
mocker.patch("requests.Session.request", side_effect=Exception)
web_client.package_changes_update(package_ahriman.base, Changes())
@ -443,7 +443,7 @@ def test_package_changes_update_failed_http_error(web_client: WebClient, package
"""
must suppress HTTP exception happened during changes update
"""
mocker.patch("requests.Session.request", side_effect=requests.HTTPError())
mocker.patch("requests.Session.request", side_effect=requests.HTTPError)
web_client.package_changes_update(package_ahriman.base, Changes())
@ -453,7 +453,7 @@ def test_package_changes_update_failed_suppress(web_client: WebClient, package_a
must suppress any exception happened during changes update and don't log
"""
web_client.suppress_errors = True
mocker.patch("requests.Session.request", side_effect=Exception())
mocker.patch("requests.Session.request", side_effect=Exception)
logging_mock = mocker.patch("logging.exception")
web_client.package_changes_update(package_ahriman.base, Changes())
@ -466,7 +466,7 @@ def test_package_changes_update_failed_http_error_suppress(web_client: WebClient
must suppress HTTP exception happened during changes update and don't log
"""
web_client.suppress_errors = True
mocker.patch("requests.Session.request", side_effect=requests.HTTPError())
mocker.patch("requests.Session.request", side_effect=requests.HTTPError)
logging_mock = mocker.patch("logging.exception")
web_client.package_changes_update(package_ahriman.base, Changes())
@ -495,7 +495,7 @@ def test_package_dependencies_get_failed(web_client: WebClient, package_ahriman:
"""
must suppress any exception happened during dependencies fetch
"""
mocker.patch("requests.Session.request", side_effect=Exception())
mocker.patch("requests.Session.request", side_effect=Exception)
web_client.package_dependencies_get(package_ahriman.base)
@ -504,7 +504,7 @@ def test_package_dependencies_get_failed_http_error(web_client: WebClient, packa
"""
must suppress HTTP exception happened during dependencies fetch
"""
mocker.patch("requests.Session.request", side_effect=requests.HTTPError())
mocker.patch("requests.Session.request", side_effect=requests.HTTPError)
web_client.package_dependencies_get(package_ahriman.base)
@ -514,7 +514,7 @@ def test_package_dependencies_get_failed_suppress(web_client: WebClient, package
must suppress any exception happened during dependencies fetch and don't log
"""
web_client.suppress_errors = True
mocker.patch("requests.Session.request", side_effect=Exception())
mocker.patch("requests.Session.request", side_effect=Exception)
logging_mock = mocker.patch("logging.exception")
web_client.package_dependencies_get(package_ahriman.base)
@ -527,7 +527,7 @@ def test_package_dependencies_get_failed_http_error_suppress(web_client: WebClie
must suppress HTTP exception happened during dependencies fetch and don't log
"""
web_client.suppress_errors = True
mocker.patch("requests.Session.request", side_effect=requests.HTTPError())
mocker.patch("requests.Session.request", side_effect=requests.HTTPError)
logging_mock = mocker.patch("logging.exception")
web_client.package_dependencies_get(package_ahriman.base)
@ -551,7 +551,7 @@ def test_package_dependencies_update_failed(web_client: WebClient, package_ahrim
"""
must suppress any exception happened during dependencies update
"""
mocker.patch("requests.Session.request", side_effect=Exception())
mocker.patch("requests.Session.request", side_effect=Exception)
web_client.package_dependencies_update(package_ahriman.base, Dependencies())
@ -560,7 +560,7 @@ def test_package_dependencies_update_failed_http_error(web_client: WebClient, pa
"""
must suppress HTTP exception happened during dependencies update
"""
mocker.patch("requests.Session.request", side_effect=requests.HTTPError())
mocker.patch("requests.Session.request", side_effect=requests.HTTPError)
web_client.package_dependencies_update(package_ahriman.base, Dependencies())
@ -570,7 +570,7 @@ def test_package_dependencies_update_failed_suppress(web_client: WebClient, pack
must suppress any exception happened during dependencies update and don't log
"""
web_client.suppress_errors = True
mocker.patch("requests.Session.request", side_effect=Exception())
mocker.patch("requests.Session.request", side_effect=Exception)
logging_mock = mocker.patch("logging.exception")
web_client.package_dependencies_update(package_ahriman.base, Dependencies())
@ -583,7 +583,7 @@ def test_package_dependencies_update_failed_http_error_suppress(web_client: WebC
must suppress HTTP exception happened during dependencies update and don't log
"""
web_client.suppress_errors = True
mocker.patch("requests.Session.request", side_effect=requests.HTTPError())
mocker.patch("requests.Session.request", side_effect=requests.HTTPError)
logging_mock = mocker.patch("logging.exception")
web_client.package_dependencies_update(package_ahriman.base, Dependencies())
@ -612,7 +612,7 @@ def test_package_get_failed(web_client: WebClient, mocker: MockerFixture) -> Non
"""
must suppress any exception happened during status getting
"""
mocker.patch("requests.Session.request", side_effect=Exception())
mocker.patch("requests.Session.request", side_effect=Exception)
assert web_client.package_get(None) == []
@ -620,7 +620,7 @@ def test_package_get_failed_http_error(web_client: WebClient, mocker: MockerFixt
"""
must suppress HTTP exception happened during status getting
"""
mocker.patch("requests.Session.request", side_effect=requests.HTTPError())
mocker.patch("requests.Session.request", side_effect=requests.HTTPError)
assert web_client.package_get(None) == []
@ -668,7 +668,7 @@ def test_package_logs_add_failed(web_client: WebClient, log_record: logging.LogR
"""
must pass exception during log post
"""
mocker.patch("requests.Session.request", side_effect=Exception())
mocker.patch("requests.Session.request", side_effect=Exception)
log_record.package_base = package_ahriman.base
record = LogRecord(LogRecordId(package_ahriman.base, package_ahriman.version),
log_record.created, log_record.getMessage())
@ -682,7 +682,7 @@ def test_package_logs_add_failed_http_error(web_client: WebClient, log_record: l
"""
must pass HTTP exception during log post
"""
mocker.patch("requests.Session.request", side_effect=requests.HTTPError())
mocker.patch("requests.Session.request", side_effect=requests.HTTPError)
log_record.package_base = package_ahriman.base
record = LogRecord(LogRecordId(package_ahriman.base, package_ahriman.version),
log_record.created, log_record.getMessage())
@ -734,7 +734,7 @@ def test_package_logs_get_failed(web_client: WebClient, package_ahriman: Package
"""
must suppress any exception happened during logs fetch
"""
mocker.patch("requests.Session.request", side_effect=Exception())
mocker.patch("requests.Session.request", side_effect=Exception)
web_client.package_logs_get(package_ahriman.base)
@ -743,7 +743,7 @@ def test_package_logs_get_failed_http_error(web_client: WebClient, package_ahrim
"""
must suppress HTTP exception happened during logs fetch
"""
mocker.patch("requests.Session.request", side_effect=requests.HTTPError())
mocker.patch("requests.Session.request", side_effect=requests.HTTPError)
web_client.package_logs_get(package_ahriman.base)
@ -753,7 +753,7 @@ def test_package_logs_get_failed_suppress(web_client: WebClient, package_ahriman
must suppress any exception happened during logs fetch and don't log
"""
web_client.suppress_errors = True
mocker.patch("requests.Session.request", side_effect=Exception())
mocker.patch("requests.Session.request", side_effect=Exception)
logging_mock = mocker.patch("logging.exception")
web_client.package_logs_get(package_ahriman.base)
@ -766,7 +766,7 @@ def test_package_logs_get_failed_http_error_suppress(web_client: WebClient, pack
must suppress HTTP exception happened during logs fetch and don't log
"""
web_client.suppress_errors = True
mocker.patch("requests.Session.request", side_effect=requests.HTTPError())
mocker.patch("requests.Session.request", side_effect=requests.HTTPError)
logging_mock = mocker.patch("logging.exception")
web_client.package_logs_get(package_ahriman.base)
@ -788,7 +788,7 @@ def test_package_logs_remove_failed(web_client: WebClient, package_ahriman: Pack
"""
must suppress any exception happened during logs removal
"""
mocker.patch("requests.Session.request", side_effect=Exception())
mocker.patch("requests.Session.request", side_effect=Exception)
web_client.package_logs_remove(package_ahriman.base, "42")
@ -797,7 +797,7 @@ def test_package_logs_remove_failed_http_error(web_client: WebClient, package_ah
"""
must suppress HTTP exception happened during logs removal
"""
mocker.patch("requests.Session.request", side_effect=requests.HTTPError())
mocker.patch("requests.Session.request", side_effect=requests.HTTPError)
web_client.package_logs_remove(package_ahriman.base, "42")
@ -807,7 +807,7 @@ def test_package_logs_remove_failed_suppress(web_client: WebClient, package_ahri
must suppress any exception happened during logs removal and don't log
"""
web_client.suppress_errors = True
mocker.patch("requests.Session.request", side_effect=Exception())
mocker.patch("requests.Session.request", side_effect=Exception)
logging_mock = mocker.patch("logging.exception")
web_client.package_logs_remove(package_ahriman.base, "42")
@ -820,7 +820,7 @@ def test_package_logs_remove_failed_http_error_suppress(web_client: WebClient, p
must suppress HTTP exception happened during logs removal and don't log
"""
web_client.suppress_errors = True
mocker.patch("requests.Session.request", side_effect=requests.HTTPError())
mocker.patch("requests.Session.request", side_effect=requests.HTTPError)
logging_mock = mocker.patch("logging.exception")
web_client.package_logs_remove(package_ahriman.base, "42")
@ -847,7 +847,7 @@ def test_package_patches_get_failed(web_client: WebClient, package_ahriman: Pack
"""
must suppress any exception happened during patches fetch
"""
mocker.patch("requests.Session.request", side_effect=Exception())
mocker.patch("requests.Session.request", side_effect=Exception)
web_client.package_patches_get(package_ahriman.base, None)
@ -856,7 +856,7 @@ def test_package_patches_get_failed_http_error(web_client: WebClient, package_ah
"""
must suppress HTTP exception happened during patches fetch
"""
mocker.patch("requests.Session.request", side_effect=requests.HTTPError())
mocker.patch("requests.Session.request", side_effect=requests.HTTPError)
web_client.package_patches_get(package_ahriman.base, None)
@ -866,7 +866,7 @@ def test_package_patches_get_failed_suppress(web_client: WebClient, package_ahri
must suppress any exception happened during patches fetch and don't log
"""
web_client.suppress_errors = True
mocker.patch("requests.Session.request", side_effect=Exception())
mocker.patch("requests.Session.request", side_effect=Exception)
logging_mock = mocker.patch("logging.exception")
web_client.package_patches_get(package_ahriman.base, None)
@ -879,7 +879,7 @@ def test_package_patches_get_failed_http_error_suppress(web_client: WebClient, p
must suppress HTTP exception happened during patches fetch and don't log
"""
web_client.suppress_errors = True
mocker.patch("requests.Session.request", side_effect=requests.HTTPError())
mocker.patch("requests.Session.request", side_effect=requests.HTTPError)
logging_mock = mocker.patch("logging.exception")
web_client.package_patches_get(package_ahriman.base, None)
@ -901,7 +901,7 @@ def test_package_patches_update_failed(web_client: WebClient, package_ahriman: P
"""
must suppress any exception happened during patches update
"""
mocker.patch("requests.Session.request", side_effect=Exception())
mocker.patch("requests.Session.request", side_effect=Exception)
web_client.package_patches_update(package_ahriman.base, PkgbuildPatch("key", "value"))
@ -910,7 +910,7 @@ def test_package_patches_update_failed_http_error(web_client: WebClient, package
"""
must suppress HTTP exception happened during patches update
"""
mocker.patch("requests.Session.request", side_effect=requests.HTTPError())
mocker.patch("requests.Session.request", side_effect=requests.HTTPError)
web_client.package_patches_update(package_ahriman.base, PkgbuildPatch("key", "value"))
@ -920,7 +920,7 @@ def test_package_patches_update_failed_suppress(web_client: WebClient, package_a
must suppress any exception happened during patches update and don't log
"""
web_client.suppress_errors = True
mocker.patch("requests.Session.request", side_effect=Exception())
mocker.patch("requests.Session.request", side_effect=Exception)
logging_mock = mocker.patch("logging.exception")
web_client.package_patches_update(package_ahriman.base, PkgbuildPatch("key", "value"))
@ -933,7 +933,7 @@ def test_package_patches_update_failed_http_error_suppress(web_client: WebClient
must suppress HTTP exception happened during patches update and don't log
"""
web_client.suppress_errors = True
mocker.patch("requests.Session.request", side_effect=requests.HTTPError())
mocker.patch("requests.Session.request", side_effect=requests.HTTPError)
logging_mock = mocker.patch("logging.exception")
web_client.package_patches_update(package_ahriman.base, PkgbuildPatch("key", "value"))
@ -954,7 +954,7 @@ def test_package_patches_remove_failed(web_client: WebClient, package_ahriman: P
"""
must suppress any exception happened during patches removal
"""
mocker.patch("requests.Session.request", side_effect=Exception())
mocker.patch("requests.Session.request", side_effect=Exception)
web_client.package_patches_remove(package_ahriman.base, None)
@ -963,7 +963,7 @@ def test_package_patches_remove_failed_http_error(web_client: WebClient, package
"""
must suppress HTTP exception happened during patches removal
"""
mocker.patch("requests.Session.request", side_effect=requests.HTTPError())
mocker.patch("requests.Session.request", side_effect=requests.HTTPError)
web_client.package_patches_remove(package_ahriman.base, None)
@ -973,7 +973,7 @@ def test_package_patches_remove_failed_suppress(web_client: WebClient, package_a
must suppress any exception happened during patches removal and don't log
"""
web_client.suppress_errors = True
mocker.patch("requests.Session.request", side_effect=Exception())
mocker.patch("requests.Session.request", side_effect=Exception)
logging_mock = mocker.patch("logging.exception")
web_client.package_patches_remove(package_ahriman.base, None)
@ -986,7 +986,7 @@ def test_package_patches_remove_failed_http_error_suppress(web_client: WebClient
must suppress HTTP exception happened during patches removal and don't log
"""
web_client.suppress_errors = True
mocker.patch("requests.Session.request", side_effect=requests.HTTPError())
mocker.patch("requests.Session.request", side_effect=requests.HTTPError)
logging_mock = mocker.patch("logging.exception")
web_client.package_patches_remove(package_ahriman.base, None)
@ -1008,7 +1008,7 @@ def test_package_remove_failed(web_client: WebClient, package_ahriman: Package,
"""
must suppress any exception happened during removal
"""
mocker.patch("requests.Session.request", side_effect=Exception())
mocker.patch("requests.Session.request", side_effect=Exception)
web_client.package_remove(package_ahriman.base)
@ -1017,7 +1017,7 @@ def test_package_remove_failed_http_error(web_client: WebClient, package_ahriman
"""
must suppress HTTP exception happened during removal
"""
mocker.patch("requests.Session.request", side_effect=requests.HTTPError())
mocker.patch("requests.Session.request", side_effect=requests.HTTPError)
web_client.package_remove(package_ahriman.base)
@ -1039,7 +1039,7 @@ def test_package_status_update_failed(web_client: WebClient, package_ahriman: Pa
"""
must suppress any exception happened during update
"""
mocker.patch("requests.Session.request", side_effect=Exception())
mocker.patch("requests.Session.request", side_effect=Exception)
web_client.package_status_update(package_ahriman.base, BuildStatusEnum.Unknown)
@ -1048,7 +1048,7 @@ def test_package_status_update_failed_http_error(web_client: WebClient, package_
"""
must suppress HTTP exception happened during update
"""
mocker.patch("requests.Session.request", side_effect=requests.HTTPError())
mocker.patch("requests.Session.request", side_effect=requests.HTTPError)
web_client.package_status_update(package_ahriman.base, BuildStatusEnum.Unknown)
@ -1068,7 +1068,7 @@ def test_package_update_failed(web_client: WebClient, package_ahriman: Package,
"""
must suppress any exception happened during addition
"""
mocker.patch("requests.Session.request", side_effect=Exception())
mocker.patch("requests.Session.request", side_effect=Exception)
web_client.package_update(package_ahriman, BuildStatusEnum.Unknown)
@ -1077,7 +1077,7 @@ def test_package_update_failed_http_error(web_client: WebClient, package_ahriman
"""
must suppress HTTP exception happened during addition
"""
mocker.patch("requests.Session.request", side_effect=requests.HTTPError())
mocker.patch("requests.Session.request", side_effect=requests.HTTPError)
web_client.package_update(package_ahriman, BuildStatusEnum.Unknown)
@ -1086,7 +1086,7 @@ def test_package_update_failed_suppress(web_client: WebClient, package_ahriman:
must suppress any exception happened during addition and don't log
"""
web_client.suppress_errors = True
mocker.patch("requests.Session.request", side_effect=Exception())
mocker.patch("requests.Session.request", side_effect=Exception)
logging_mock = mocker.patch("logging.exception")
web_client.package_update(package_ahriman, BuildStatusEnum.Unknown)
@ -1099,7 +1099,7 @@ def test_package_update_failed_http_error_suppress(web_client: WebClient, packag
must suppress HTTP exception happened during addition and don't log
"""
web_client.suppress_errors = True
mocker.patch("requests.Session.request", side_effect=requests.HTTPError())
mocker.patch("requests.Session.request", side_effect=requests.HTTPError)
logging_mock = mocker.patch("logging.exception")
web_client.package_update(package_ahriman, BuildStatusEnum.Unknown)
@ -1127,7 +1127,7 @@ def test_status_get_failed(web_client: WebClient, mocker: MockerFixture) -> None
"""
must suppress any exception happened during web service status getting
"""
mocker.patch("requests.Session.request", side_effect=Exception())
mocker.patch("requests.Session.request", side_effect=Exception)
assert web_client.status_get().architecture is None
@ -1135,7 +1135,7 @@ def test_status_get_failed_http_error(web_client: WebClient, mocker: MockerFixtu
"""
must suppress HTTP exception happened during web service status getting
"""
mocker.patch("requests.Session.request", side_effect=requests.HTTPError())
mocker.patch("requests.Session.request", side_effect=requests.HTTPError)
assert web_client.status_get().architecture is None
@ -1159,7 +1159,7 @@ def test_status_update_self_failed(web_client: WebClient, mocker: MockerFixture)
"""
must suppress any exception happened during service update
"""
mocker.patch("requests.Session.request", side_effect=Exception())
mocker.patch("requests.Session.request", side_effect=Exception)
web_client.status_update(BuildStatusEnum.Unknown)
@ -1167,5 +1167,5 @@ def test_status_update_failed_http_error(web_client: WebClient, mocker: MockerFi
"""
must suppress HTTP exception happened during service update
"""
mocker.patch("requests.Session.request", side_effect=requests.HTTPError())
mocker.patch("requests.Session.request", side_effect=requests.HTTPError)
web_client.status_update(BuildStatusEnum.Unknown)

View File

@ -19,10 +19,9 @@ def test_configuration_schema(configuration: Configuration) -> None:
"""
section = "console"
configuration.set_option("report", "target", section)
_, repository_id = configuration.check_loaded()
expected = {section: ReportTrigger.CONFIGURATION_SCHEMA[section]}
assert ReportTrigger.configuration_schema(repository_id, configuration) == expected
assert ReportTrigger.configuration_schema(configuration) == expected
def test_configuration_schema_no_section(configuration: Configuration) -> None:
@ -31,9 +30,7 @@ def test_configuration_schema_no_section(configuration: Configuration) -> None:
"""
section = "abracadabra"
configuration.set_option("report", "target", section)
_, repository_id = configuration.check_loaded()
assert ReportTrigger.configuration_schema(repository_id, configuration) == {}
assert ReportTrigger.configuration_schema(configuration) == {}
def test_configuration_schema_no_schema(configuration: Configuration) -> None:
@ -43,17 +40,15 @@ def test_configuration_schema_no_schema(configuration: Configuration) -> None:
section = "abracadabra"
configuration.set_option("report", "target", section)
configuration.set_option(section, "key", "value")
_, repository_id = configuration.check_loaded()
assert ReportTrigger.configuration_schema(repository_id, configuration) == {}
assert ReportTrigger.configuration_schema(configuration) == {}
def test_configuration_schema_empty(configuration: Configuration) -> None:
"""
must return default schema if no configuration set
"""
_, repository_id = configuration.check_loaded()
assert ReportTrigger.configuration_schema(repository_id, None) == ReportTrigger.CONFIGURATION_SCHEMA
assert ReportTrigger.configuration_schema(None) == ReportTrigger.CONFIGURATION_SCHEMA
def test_configuration_schema_variables() -> None:

View File

@ -49,7 +49,7 @@ def test_load_trigger_package_error_on_creation(trigger_loader: TriggerLoader, c
"""
must raise InvalidException on trigger initialization if any exception is thrown
"""
mocker.patch("ahriman.core.triggers.trigger.Trigger.__init__", side_effect=Exception())
mocker.patch("ahriman.core.triggers.trigger.Trigger.__init__", side_effect=Exception)
_, repository_id = configuration.check_loaded()
with pytest.raises(ExtensionError):
@ -67,7 +67,7 @@ def test_load_trigger_class_package_invalid_import(trigger_loader: TriggerLoader
"""
must raise InvalidExtension on invalid import
"""
mocker.patch("importlib.import_module", side_effect=ModuleNotFoundError())
mocker.patch("importlib.import_module", side_effect=ModuleNotFoundError)
with pytest.raises(ExtensionError):
trigger_loader.load_trigger_class("random.module")
@ -137,7 +137,7 @@ def test_on_result_exception(trigger_loader: TriggerLoader, package_ahriman: Pac
"""
must suppress exception during trigger run
"""
upload_mock = mocker.patch("ahriman.core.upload.UploadTrigger.on_result", side_effect=Exception())
upload_mock = mocker.patch("ahriman.core.upload.UploadTrigger.on_result", side_effect=Exception)
report_mock = mocker.patch("ahriman.core.report.ReportTrigger.on_result")
log_mock = mocker.patch("logging.Logger.exception")

View File

@ -172,7 +172,7 @@ def test_release_get_exception(github: GitHub, mocker: MockerFixture) -> None:
"""
must re-raise non HTTPError exception
"""
mocker.patch("ahriman.core.upload.github.GitHub.make_request", side_effect=Exception())
mocker.patch("ahriman.core.upload.github.GitHub.make_request", side_effect=Exception)
with pytest.raises(Exception):
github.release_get()

View File

@ -13,7 +13,7 @@ def test_upload_failure(configuration: Configuration, mocker: MockerFixture) ->
"""
must raise SyncFailed on errors
"""
mocker.patch("ahriman.core.upload.rsync.Rsync.sync", side_effect=Exception())
mocker.patch("ahriman.core.upload.rsync.Rsync.sync", side_effect=Exception)
_, repository_id = configuration.check_loaded()
with pytest.raises(SynchronizationError):

View File

@ -393,7 +393,7 @@ def test_actual_version_failed(package_tpacpi_bat_git: Package, configuration: C
"""
must return same version in case if exception occurred
"""
mocker.patch("ahriman.core.build_tools.task.Task.init", side_effect=Exception())
mocker.patch("ahriman.core.build_tools.task.Task.init", side_effect=Exception)
mocker.patch("pathlib.Path.glob", return_value=[Path("local")])
unlink_mock = mocker.patch("pathlib.Path.unlink")

View File

@ -62,7 +62,7 @@ def test_resolve_aur_no_access(repository_paths: RepositoryPaths, mocker: Mocker
"""
must resolve auto type into the AUR package in case if we cannot read in suggested path
"""
mocker.patch("pathlib.Path.is_dir", side_effect=PermissionError())
mocker.patch("pathlib.Path.is_dir", side_effect=PermissionError)
assert PackageSource.Auto.resolve("package", repository_paths) == PackageSource.AUR

View File

@ -72,7 +72,7 @@ async def test_exception_handler_success(mocker: MockerFixture) -> None:
must pass 2xx and 3xx codes
"""
request = pytest.helpers.request("", "", "")
request_handler = AsyncMock(side_effect=HTTPNoContent())
request_handler = AsyncMock(side_effect=HTTPNoContent)
logging_mock = mocker.patch("logging.Logger.exception")
handler = exception_handler(logging.getLogger())
@ -86,7 +86,7 @@ async def test_exception_handler_unauthorized(mocker: MockerFixture) -> None:
must handle unauthorized exception as json response
"""
request = pytest.helpers.request("", "", "")
request_handler = AsyncMock(side_effect=HTTPUnauthorized())
request_handler = AsyncMock(side_effect=HTTPUnauthorized)
mocker.patch("ahriman.web.middlewares.exception_handler._is_templated_unauthorized", return_value=False)
render_mock = mocker.patch("aiohttp_jinja2.render_template")
@ -101,7 +101,7 @@ async def test_exception_handler_unauthorized_templated(mocker: MockerFixture) -
must handle unauthorized exception as json response in html context
"""
request = pytest.helpers.request("", "", "")
request_handler = AsyncMock(side_effect=HTTPUnauthorized())
request_handler = AsyncMock(side_effect=HTTPUnauthorized)
mocker.patch("ahriman.web.middlewares.exception_handler._is_templated_unauthorized", return_value=True)
render_mock = mocker.patch("aiohttp_jinja2.render_template")
@ -154,7 +154,7 @@ async def test_exception_handler_client_error(mocker: MockerFixture) -> None:
must handle client exception
"""
request = pytest.helpers.request("", "", "")
request_handler = AsyncMock(side_effect=HTTPBadRequest())
request_handler = AsyncMock(side_effect=HTTPBadRequest)
logging_mock = mocker.patch("logging.Logger.exception")
handler = exception_handler(logging.getLogger())
@ -168,7 +168,7 @@ async def test_exception_handler_server_error(mocker: MockerFixture) -> None:
must handle server exception
"""
request = pytest.helpers.request("", "", "")
request_handler = AsyncMock(side_effect=HTTPInternalServerError())
request_handler = AsyncMock(side_effect=HTTPInternalServerError)
logging_mock = mocker.patch("logging.Logger.exception")
handler = exception_handler(logging.getLogger())

View File

@ -86,7 +86,7 @@ async def test_on_startup_exception(application: Application, watcher: Watcher,
must throw exception on load error
"""
mocker.patch("aiohttp.web.Application.__getitem__", return_value={"": watcher})
mocker.patch("ahriman.core.status.watcher.Watcher.load", side_effect=Exception())
mocker.patch("ahriman.core.status.watcher.Watcher.load", side_effect=Exception)
with pytest.raises(InitializeError):
await _on_startup(application)

View File

@ -60,7 +60,7 @@ async def test_get_process_exception(client: TestClient, mocker: MockerFixture)
"""
must raise 404 on invalid PGP server response
"""
import_mock = mocker.patch("ahriman.core.sign.gpg.GPG.key_download", side_effect=Exception())
import_mock = mocker.patch("ahriman.core.sign.gpg.GPG.key_download", side_effect=Exception)
response_schema = pytest.helpers.schema_response(PGPView.get, code=400)
response = await client.get("/api/v1/service/pgp", params={"key": "0xdeadbeaf", "server": "keyserver.ubuntu.com"})

View File

@ -82,7 +82,7 @@ async def test_post_exception_inside(client: TestClient, mocker: MockerFixture)
exception handler must handle 500 errors
"""
payload = {"status": BuildStatusEnum.Success.value}
mocker.patch("ahriman.core.status.watcher.Watcher.status_update", side_effect=Exception())
mocker.patch("ahriman.core.status.watcher.Watcher.status_update", side_effect=Exception)
response_schema = pytest.helpers.schema_response(StatusView.post, code=500)
response = await client.post("/api/v1/status", json=payload)

View File

@ -40,7 +40,7 @@ async def test_post_unauthorized(client_with_auth: TestClient, mocker: MockerFix
"""
must raise exception if unauthorized
"""
mocker.patch("ahriman.web.views.v1.user.logout.check_authorized", side_effect=HTTPUnauthorized())
mocker.patch("ahriman.web.views.v1.user.logout.check_authorized", side_effect=HTTPUnauthorized)
forget_mock = mocker.patch("ahriman.web.views.v1.user.logout.forget")
response_schema = pytest.helpers.schema_response(LogoutView.post, code=401)

View File

@ -37,6 +37,9 @@ target =
[keyring]
target = keyring
[logs-rotation]
keep_last_logs = 5
[mirrorlist]
target = mirrorlist
servers = http://localhost