triggers implementation (#62)

This commit is contained in:
2022-05-09 17:45:39 +03:00
committed by Evgeniy Alekseev
parent 1905360f8f
commit b9cd98235e
49 changed files with 776 additions and 344 deletions

View File

@ -9,12 +9,10 @@ def test_finalize(application: Application, mocker: MockerFixture) -> None:
"""
must report and sync at the last
"""
report_mock = mocker.patch("ahriman.application.application.Application.report")
sync_mock = mocker.patch("ahriman.application.application.Application.sync")
triggers_mock = mocker.patch("ahriman.core.repository.Repository.process_triggers")
application._finalize(Result())
report_mock.assert_called_once_with([], Result())
sync_mock.assert_called_once_with([], [])
triggers_mock.assert_called_once_with(Result())
def test_known_packages(application: Application, package_ahriman: Package, mocker: MockerFixture) -> None:

View File

@ -53,15 +53,6 @@ def test_clean_packages(application_repository: ApplicationRepository, mocker: M
clear_mock.assert_called_once_with()
def test_report(application_repository: ApplicationRepository, mocker: MockerFixture) -> None:
"""
must generate report
"""
executor_mock = mocker.patch("ahriman.core.repository.executor.Executor.process_report")
application_repository.report(["a"], Result())
executor_mock.assert_called_once_with(["a"], Result())
def test_sign(application_repository: ApplicationRepository, package_ahriman: Package, package_python_schedule: Package,
mocker: MockerFixture) -> None:
"""
@ -121,15 +112,6 @@ def test_sign_specific(application_repository: ApplicationRepository, package_ah
finalize_mock.assert_called_once_with(Result())
def test_sync(application_repository: ApplicationRepository, mocker: MockerFixture) -> None:
"""
must sync to remote
"""
executor_mock = mocker.patch("ahriman.core.repository.executor.Executor.process_sync")
application_repository.sync(["a"], [])
executor_mock.assert_called_once_with(["a"], [])
def test_unknown_no_aur(application_repository: ApplicationRepository, package_ahriman: Package,
mocker: MockerFixture) -> None:
"""

View File

@ -1,33 +0,0 @@
import argparse
from pytest_mock import MockerFixture
from ahriman.application.handlers import Report
from ahriman.core.configuration import Configuration
from ahriman.models.result import Result
def _default_args(args: argparse.Namespace) -> argparse.Namespace:
"""
default arguments for these test cases
Args:
args(argparse.Namespace): command line arguments fixture
Returns:
argparse.Namespace: generated arguments for these test cases
"""
args.target = []
return args
def test_run(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None:
"""
must run command
"""
args = _default_args(args)
mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create")
application_mock = mocker.patch("ahriman.application.application.Application.report")
Report.run(args, "x86_64", configuration, True, False)
application_mock.assert_called_once_with(args.target, Result())

View File

@ -1,32 +0,0 @@
import argparse
from pytest_mock import MockerFixture
from ahriman.application.handlers import Sync
from ahriman.core.configuration import Configuration
def _default_args(args: argparse.Namespace) -> argparse.Namespace:
"""
default arguments for these test cases
Args:
args(argparse.Namespace): command line arguments fixture
Returns:
argparse.Namespace: generated arguments for these test cases
"""
args.target = []
return args
def test_run(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None:
"""
must run command
"""
args = _default_args(args)
mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create")
application_mock = mocker.patch("ahriman.application.application.Application.sync")
Sync.run(args, "x86_64", configuration, True, False)
application_mock.assert_called_once_with(args.target, [])

View File

@ -0,0 +1,18 @@
import argparse
from pytest_mock import MockerFixture
from ahriman.application.handlers import Triggers
from ahriman.core.configuration import Configuration
from ahriman.models.result import Result
def test_run(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None:
"""
must run command
"""
mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create")
application_mock = mocker.patch("ahriman.core.repository.Repository.process_triggers")
Triggers.run(args, "x86_64", configuration, True, False)
application_mock.assert_called_once_with(Result())

View File

@ -348,16 +348,6 @@ def test_subparsers_repo_remove_unknown_architecture(parser: argparse.ArgumentPa
assert args.architecture == ["x86_64"]
def test_subparsers_repo_report_architecture(parser: argparse.ArgumentParser) -> None:
"""
repo-report command must correctly parse architecture list
"""
args = parser.parse_args(["repo-report"])
assert args.architecture is None
args = parser.parse_args(["-a", "x86_64", "repo-report"])
assert args.architecture == ["x86_64"]
def test_subparsers_repo_restore(parser: argparse.ArgumentParser) -> None:
"""
repo-restore command must imply architecture list, lock, no-report and unsafe
@ -446,13 +436,13 @@ def test_subparsers_repo_status_update_option_status(parser: argparse.ArgumentPa
assert isinstance(args.status, BuildStatusEnum)
def test_subparsers_repo_sync_architecture(parser: argparse.ArgumentParser) -> None:
def test_subparsers_repo_triggers_architecture(parser: argparse.ArgumentParser) -> None:
"""
repo-sync command must correctly parse architecture list
repo-triggers command must correctly parse architecture list
"""
args = parser.parse_args(["repo-sync"])
args = parser.parse_args(["repo-triggers"])
assert args.architecture is None
args = parser.parse_args(["-a", "x86_64", "repo-sync"])
args = parser.parse_args(["-a", "x86_64", "repo-triggers"])
assert args.architecture == ["x86_64"]

View File

@ -24,7 +24,7 @@ def test_report_dummy(configuration: Configuration, result: Result, mocker: Mock
"""
mocker.patch("ahriman.models.report_settings.ReportSettings.from_option", return_value=ReportSettings.Disabled)
report_mock = mocker.patch("ahriman.core.report.Report.generate")
Report.load("x86_64", configuration, "disabled").run([], result)
Report.load("x86_64", configuration, "disabled").run(result, [])
report_mock.assert_called_once_with([], result)
@ -33,7 +33,7 @@ def test_report_console(configuration: Configuration, result: Result, mocker: Mo
must generate console report
"""
report_mock = mocker.patch("ahriman.core.report.Console.generate")
Report.load("x86_64", configuration, "console").run([], result)
Report.load("x86_64", configuration, "console").run(result, [])
report_mock.assert_called_once_with([], result)
@ -42,7 +42,7 @@ def test_report_email(configuration: Configuration, result: Result, mocker: Mock
must generate email report
"""
report_mock = mocker.patch("ahriman.core.report.Email.generate")
Report.load("x86_64", configuration, "email").run([], result)
Report.load("x86_64", configuration, "email").run(result, [])
report_mock.assert_called_once_with([], result)
@ -51,7 +51,7 @@ def test_report_html(configuration: Configuration, result: Result, mocker: Mocke
must generate html report
"""
report_mock = mocker.patch("ahriman.core.report.HTML.generate")
Report.load("x86_64", configuration, "html").run([], result)
Report.load("x86_64", configuration, "html").run(result, [])
report_mock.assert_called_once_with([], result)
@ -60,5 +60,5 @@ def test_report_telegram(configuration: Configuration, result: Result, mocker: M
must generate telegram report
"""
report_mock = mocker.patch("ahriman.core.report.Telegram.generate")
Report.load("x86_64", configuration, "telegram").run([], result)
Report.load("x86_64", configuration, "telegram").run(result, [])
report_mock.assert_called_once_with([], result)

View File

@ -0,0 +1,17 @@
from pytest_mock import MockerFixture
from ahriman.core.configuration import Configuration
from ahriman.core.report import ReportTrigger
from ahriman.models.result import Result
def test_run(configuration: Configuration, mocker: MockerFixture) -> None:
"""
must run report for specified targets
"""
configuration.set_option("report", "target", "email")
run_mock = mocker.patch("ahriman.core.report.Report.run")
trigger = ReportTrigger("x86_64", configuration)
trigger.run(Result(), [])
run_mock.assert_called_once_with(Result(), [])

View File

@ -3,12 +3,11 @@ import pytest
from pathlib import Path
from pytest_mock import MockerFixture
from unittest import mock
from unittest.mock import MagicMock
from ahriman.core.report import Report
from ahriman.core.repository.executor import Executor
from ahriman.core.upload import Upload
from ahriman.models.package import Package
from ahriman.models.result import Result
def test_load_archives(executor: Executor) -> None:
@ -145,45 +144,15 @@ def test_process_remove_nothing(executor: Executor, package_ahriman: Package, pa
repo_remove_mock.assert_not_called()
def test_process_report(executor: Executor, package_ahriman: Package, mocker: MockerFixture) -> None:
def test_process_triggers(executor: Executor, package_ahriman: Package, result: Result, mocker: MockerFixture) -> None:
"""
must process report
"""
mocker.patch("ahriman.core.repository.executor.Executor.packages", return_value=[package_ahriman])
mocker.patch("ahriman.core.report.Report.load", return_value=Report("x86_64", executor.configuration))
report_mock = mocker.patch("ahriman.core.report.Report.run")
triggers_mock = mocker.patch("ahriman.core.triggers.TriggerLoader.process")
executor.process_report(["dummy"], [])
report_mock.assert_called_once_with([package_ahriman], [])
def test_process_report_auto(executor: Executor) -> None:
"""
must process report in auto mode if no targets supplied
"""
configuration_mock = executor.configuration = MagicMock()
executor.process_report(None, [])
configuration_mock.getlist.assert_called_once_with("report", "target")
def test_process_upload(executor: Executor, mocker: MockerFixture) -> None:
"""
must process sync
"""
mocker.patch("ahriman.core.upload.Upload.load", return_value=Upload("x86_64", executor.configuration))
upload_mock = mocker.patch("ahriman.core.upload.Upload.run")
executor.process_sync(["dummy"], [])
upload_mock.assert_called_once_with(executor.paths.repository, [])
def test_process_upload_auto(executor: Executor) -> None:
"""
must process sync in auto mode if no targets supplied
"""
configuration_mock = executor.configuration = MagicMock()
executor.process_sync(None, [])
configuration_mock.getlist.assert_called_once_with("upload", "target")
executor.process_triggers(result)
triggers_mock.assert_called_once_with(result, [package_ahriman])
def test_process_update(executor: Executor, package_ahriman: Package, mocker: MockerFixture) -> None:

View File

@ -0,0 +1,31 @@
import pytest
from ahriman.core.configuration import Configuration
from ahriman.core.triggers import Trigger, TriggerLoader
@pytest.fixture
def trigger(configuration: Configuration) -> Trigger:
"""
fixture for trigger
Args:
configuration(Configuration): configuration fixture
Returns:
Trigger: trigger test instance
"""
return Trigger("x86_64", configuration)
@pytest.fixture
def trigger_loader(configuration: Configuration) -> TriggerLoader:
"""
fixture for trigger loader
Args:
configuration(Configuration): configuration fixture
Returns:
TriggerLoader: trigger loader test instance
"""
return TriggerLoader("x86_64", configuration)

View File

@ -0,0 +1,12 @@
import pytest
from ahriman.core.triggers import Trigger
from ahriman.models.result import Result
def test_run(trigger: Trigger) -> None:
"""
must raise NotImplemented for missing rum method
"""
with pytest.raises(NotImplementedError):
trigger.run(Result(), [])

View File

@ -0,0 +1,92 @@
import pytest
from pathlib import Path
from pytest_mock import MockerFixture
from ahriman.core.exceptions import InvalidExtension
from ahriman.core.triggers import TriggerLoader
from ahriman.models.package import Package
from ahriman.models.result import Result
def test_load_trigger_package(trigger_loader: TriggerLoader) -> None:
"""
must load trigger from package
"""
assert trigger_loader._load_trigger("ahriman.core.report.ReportTrigger")
def test_load_trigger_package_invalid_import(trigger_loader: TriggerLoader, mocker: MockerFixture) -> None:
"""
must raise InvalidExtension on invalid import
"""
mocker.patch("ahriman.core.triggers.trigger_loader.importlib.import_module", side_effect=ModuleNotFoundError())
with pytest.raises(InvalidExtension):
trigger_loader._load_trigger("random.module")
def test_load_trigger_package_not_trigger(trigger_loader: TriggerLoader) -> None:
"""
must raise InvalidExtension if imported module is not a type
"""
with pytest.raises(InvalidExtension):
trigger_loader._load_trigger("ahriman.core.util.check_output")
def test_load_trigger_package_error_on_creation(trigger_loader: TriggerLoader, mocker: MockerFixture) -> None:
"""
must raise InvalidException on trigger initialization if any exception is thrown
"""
mocker.patch("ahriman.core.triggers.trigger.Trigger.__init__", side_effect=Exception())
with pytest.raises(InvalidExtension):
trigger_loader._load_trigger("ahriman.core.report.ReportTrigger")
def test_load_trigger_package_is_not_trigger(trigger_loader: TriggerLoader) -> None:
"""
must raise InvalidExtension if loaded class is not a trigger
"""
with pytest.raises(InvalidExtension):
trigger_loader._load_trigger("ahriman.core.sign.gpg.GPG")
def test_load_trigger_path(trigger_loader: TriggerLoader, resource_path_root: Path) -> None:
"""
must load trigger from path
"""
path = resource_path_root.parent.parent / "src" / "ahriman" / "core" / "report" / "report_trigger.py"
assert trigger_loader._load_trigger(f"{path}.ReportTrigger")
def test_load_trigger_path_not_found(trigger_loader: TriggerLoader) -> None:
"""
must raise InvalidExtension if file cannot be found
"""
with pytest.raises(InvalidExtension):
trigger_loader._load_trigger("/some/random/path.py.SomeRandomModule")
def test_process(trigger_loader: TriggerLoader, package_ahriman: Package, mocker: MockerFixture) -> None:
"""
must run triggers
"""
upload_mock = mocker.patch("ahriman.core.upload.UploadTrigger.run")
report_mock = mocker.patch("ahriman.core.report.ReportTrigger.run")
trigger_loader.process(Result(), [package_ahriman])
report_mock.assert_called_once_with(Result(), [package_ahriman])
upload_mock.assert_called_once_with(Result(), [package_ahriman])
def test_process_exception(trigger_loader: TriggerLoader, package_ahriman: Package, mocker: MockerFixture) -> None:
"""
must suppress exception during trigger run
"""
upload_mock = mocker.patch("ahriman.core.upload.UploadTrigger.run", side_effect=Exception())
report_mock = mocker.patch("ahriman.core.report.ReportTrigger.run")
log_mock = mocker.patch("logging.Logger.exception")
trigger_loader.process(Result(), [package_ahriman])
report_mock.assert_called_once_with(Result(), [package_ahriman])
upload_mock.assert_called_once_with(Result(), [package_ahriman])
log_mock.assert_called_once()

View File

@ -0,0 +1,17 @@
from pytest_mock import MockerFixture
from ahriman.core.configuration import Configuration
from ahriman.core.upload import UploadTrigger
from ahriman.models.result import Result
def test_run(configuration: Configuration, mocker: MockerFixture) -> None:
"""
must run report for specified targets
"""
configuration.set_option("upload", "target", "rsync")
run_mock = mocker.patch("ahriman.core.upload.Upload.run")
trigger = UploadTrigger("x86_64", configuration)
trigger.run(Result(), [])
run_mock.assert_called_once_with(configuration.repository_paths.repository, [])

View File

@ -22,6 +22,7 @@ build_command = extra-x86_64-build
ignore_packages =
makechrootpkg_flags =
makepkg_flags = --skippgpcheck
triggers = ahriman.core.report.ReportTrigger ahriman.core.upload.UploadTrigger
[repository]
name = aur-clone