reorder tests

This commit is contained in:
2026-07-13 13:00:13 +03:00
parent 92ac036f78
commit 7db38ff9e4
800 changed files with 307 additions and 996 deletions
@@ -0,0 +1,9 @@
from ahriman.application.handlers.triggers import Triggers
from ahriman.application.handlers.triggers_support.triggers_support import TriggersSupport
def test_arguments() -> None:
"""
must define own arguments
"""
assert TriggersSupport.arguments != Triggers.arguments
@@ -0,0 +1,34 @@
import pytest
from ahriman.core.archive import ArchiveTrigger
from ahriman.core.archive.archive_tree import ArchiveTree
from ahriman.core.configuration import Configuration
@pytest.fixture
def archive_tree(configuration: Configuration) -> ArchiveTree:
"""
archive tree fixture
Args:
configuration(Configuration): configuration fixture
Returns:
ArchiveTree: archive tree test instance
"""
return ArchiveTree(configuration.repository_paths, [])
@pytest.fixture
def archive_trigger(configuration: Configuration) -> ArchiveTrigger:
"""
archive trigger fixture
Args:
configuration(Configuration): configuration fixture
Returns:
ArchiveTrigger: archive trigger test instance
"""
_, repository_id = configuration.check_loaded()
return ArchiveTrigger(repository_id, configuration)
@@ -0,0 +1,176 @@
from pathlib import Path
from pytest_mock import MockerFixture
from unittest.mock import call as MockCall
from ahriman.core.archive.archive_tree import ArchiveTree
from ahriman.core.utils import utcnow
from ahriman.models.package import Package
def test_repo(archive_tree: ArchiveTree) -> None:
"""
must return correct repository object
"""
local = Path("local")
repo = archive_tree._repo(local)
assert repo.sign_args == archive_tree.sign_args
assert repo.name == archive_tree.repository_id.name
assert repo.root == local
def test_repository_for(archive_tree: ArchiveTree) -> None:
"""
must correctly generate path to repository
"""
path = archive_tree.repository_for()
assert path.is_relative_to(archive_tree.paths.archive / "repos")
assert (archive_tree.repository_id.name, archive_tree.repository_id.architecture) == path.parts[-2:]
assert set(map("{:02d}".format, utcnow().timetuple()[:3])).issubset(path.parts)
def test_directories_fix(archive_tree: ArchiveTree, mocker: MockerFixture) -> None:
"""
must remove empty directories recursively
"""
root = archive_tree.paths.archive / "repos"
(root / "a" / "b").mkdir(parents=True, exist_ok=True)
(root / "a" / "b" / "file").touch()
(root / "a" / "b" / "c" / "d").mkdir(parents=True, exist_ok=True)
_original_rmdir = Path.rmdir
rmdir_mock = mocker.patch("pathlib.Path.rmdir", autospec=True, side_effect=_original_rmdir)
archive_tree.directories_fix({Path("a") / "b" / "c" / "d"})
rmdir_mock.assert_has_calls([
MockCall(root / "a" / "b" / "c" / "d"),
MockCall(root / "a" / "b" / "c"),
])
def test_symlinks_create(archive_tree: ArchiveTree, package_ahriman: Package, package_python_schedule: Package,
mocker: MockerFixture) -> None:
"""
must create symlinks
"""
_original_exists = Path.exists
symlinks_mock = mocker.patch("pathlib.Path.symlink_to", side_effect=(None, FileExistsError, FileExistsError))
add_mock = mocker.patch("ahriman.core.alpm.repo.Repo.add")
mocker.patch("pathlib.Path.glob", autospec=True, side_effect=lambda path, name: [path / name[:-1]])
archive_tree.symlinks_create([package_ahriman, package_python_schedule])
symlinks_mock.assert_has_calls([
MockCall(Path("..") /
".." /
".." /
".." /
".." /
".." /
archive_tree.paths.archive_for(package.base)
.relative_to(archive_tree.paths.root)
.relative_to("archive") /
single.filename
)
for package in (package_ahriman, package_python_schedule)
for single in package.packages.values()
])
add_mock.assert_called_once_with(
archive_tree.repository_for() / package_ahriman.packages[package_ahriman.base].filename
)
def test_symlinks_create_empty_filename(archive_tree: ArchiveTree, package_ahriman: Package,
mocker: MockerFixture) -> None:
"""
must skip symlinks creation if filename is not set
"""
package_ahriman.packages[package_ahriman.base].filename = None
symlinks_mock = mocker.patch("pathlib.Path.symlink_to")
archive_tree.symlinks_create([package_ahriman])
symlinks_mock.assert_not_called()
def test_symlinks_fix(archive_tree: ArchiveTree, mocker: MockerFixture) -> None:
"""
must fix broken symlinks
"""
_original_exists = Path.exists
def exists_mock(path: Path) -> bool:
if path.name.startswith("symlink"):
return True
return _original_exists(path)
mocker.patch("pathlib.Path.is_symlink", side_effect=[True, True, False])
mocker.patch("pathlib.Path.exists", autospec=True, side_effect=exists_mock)
walk_mock = mocker.patch("ahriman.core.archive.archive_tree.walk", return_value=[
archive_tree.repository_for() / filename
for filename in (
"symlink-1.0.0-1-x86_64.pkg.tar.zst",
"symlink-1.0.0-1-x86_64.pkg.tar.zst.sig",
"broken_symlink-1.0.0-1-x86_64.pkg.tar.zst",
"file-1.0.0-1-x86_64.pkg.tar.zst",
)
])
remove_mock = mocker.patch("ahriman.core.alpm.repo.Repo.remove")
assert list(archive_tree.symlinks_fix()) == [
archive_tree.repository_for().relative_to(archive_tree.paths.archive / "repos"),
]
walk_mock.assert_called_once_with(archive_tree.paths.archive / "repos")
remove_mock.assert_called_once_with(
"broken_symlink", archive_tree.repository_for() / "broken_symlink-1.0.0-1-x86_64.pkg.tar.zst")
def test_symlinks_fix_foreign_repository(archive_tree: ArchiveTree, mocker: MockerFixture) -> None:
"""
must skip symlinks check if repository name or architecture doesn't match
"""
_original_exists = Path.exists
def exists_mock(path: Path) -> bool:
if path.name.startswith("symlink"):
return True
return _original_exists(path)
mocker.patch("pathlib.Path.is_symlink", side_effect=[True, True, False])
mocker.patch("pathlib.Path.exists", autospec=True, side_effect=exists_mock)
mocker.patch("ahriman.core.archive.archive_tree.walk", return_value=[
archive_tree.repository_for().with_name("i686") / filename
for filename in (
"symlink-1.0.0-1-x86_64.pkg.tar.zst",
"broken_symlink-1.0.0-1-x86_64.pkg.tar.zst",
"file-1.0.0-1-x86_64.pkg.tar.zst",
)
])
remove_mock = mocker.patch("ahriman.core.alpm.repo.Repo.remove")
assert list(archive_tree.symlinks_fix()) == []
remove_mock.assert_not_called()
def test_tree_create(archive_tree: ArchiveTree, mocker: MockerFixture) -> None:
"""
must create repository root if not exists
"""
owner_guard_mock = mocker.patch("ahriman.models.repository_paths.RepositoryPaths.preserve_owner")
mkdir_mock = mocker.patch("pathlib.Path.mkdir")
init_mock = mocker.patch("ahriman.core.alpm.repo.Repo.init")
archive_tree.tree_create()
owner_guard_mock.assert_called_once_with()
mkdir_mock.assert_called_once_with(0o755, parents=True)
init_mock.assert_called_once_with()
def test_tree_create_exists(archive_tree: ArchiveTree, mocker: MockerFixture) -> None:
"""
must skip directory creation if already exists
"""
mocker.patch("pathlib.Path.exists", return_value=True)
mkdir_mock = mocker.patch("pathlib.Path.mkdir")
archive_tree.tree_create()
mkdir_mock.assert_not_called()
@@ -0,0 +1,37 @@
from pathlib import Path
from pytest_mock import MockerFixture
from ahriman.core.archive import ArchiveTrigger
from ahriman.models.package import Package
from ahriman.models.result import Result
def test_on_result(archive_trigger: ArchiveTrigger, package_ahriman: Package, mocker: MockerFixture) -> None:
"""
must create symlinks for actual repository
"""
symlinks_mock = mocker.patch("ahriman.core.archive.archive_tree.ArchiveTree.symlinks_create")
archive_trigger.on_result(Result(), [package_ahriman])
symlinks_mock.assert_called_once_with([package_ahriman])
def test_on_start(archive_trigger: ArchiveTrigger, mocker: MockerFixture) -> None:
"""
must create repository tree on load
"""
tree_mock = mocker.patch("ahriman.core.archive.archive_tree.ArchiveTree.tree_create")
archive_trigger.on_start()
tree_mock.assert_called_once_with()
def test_on_stop(archive_trigger: ArchiveTrigger, mocker: MockerFixture) -> None:
"""
must fix broken symlinks on stop
"""
local = Path("local")
symlinks_mock = mocker.patch("ahriman.core.archive.archive_tree.ArchiveTree.symlinks_fix", return_value=[local])
directories_mock = mocker.patch("ahriman.core.archive.archive_tree.ArchiveTree.directories_fix")
archive_trigger.on_stop()
symlinks_mock.assert_called_once_with()
directories_mock.assert_called_once_with({local})
@@ -0,0 +1,51 @@
import pytest
from ahriman.core.configuration import Configuration
from ahriman.core.distributed import WorkerTrigger, WorkersCache
from ahriman.core.distributed.distributed_system import DistributedSystem
@pytest.fixture
def distributed_system(configuration: Configuration) -> DistributedSystem:
"""
distributed system fixture
Args:
configuration(Configuration): configuration fixture
Returns:
DistributedSystem: distributed system test instance
"""
configuration.set_option("status", "address", "http://localhost:8081")
_, repository_id = configuration.check_loaded()
return DistributedSystem(repository_id, configuration)
@pytest.fixture
def worker_trigger(configuration: Configuration) -> WorkerTrigger:
"""
worker trigger fixture
Args:
configuration(Configuration): configuration fixture
Returns:
WorkerTrigger: worker trigger test instance
"""
configuration.set_option("status", "address", "http://localhost:8081")
_, repository_id = configuration.check_loaded()
return WorkerTrigger(repository_id, configuration)
@pytest.fixture
def workers_cache(configuration: Configuration) -> WorkersCache:
"""
workers cache fixture
Args:
configuration(Configuration): configuration fixture
Returns:
WorkersCache: workers cache test instance
"""
return WorkersCache(configuration)
@@ -0,0 +1,82 @@
import json
import requests
from pytest_mock import MockerFixture
from ahriman.core.configuration import Configuration
from ahriman.core.distributed.distributed_system import DistributedSystem
from ahriman.models.worker import Worker
def test_configuration_sections(configuration: Configuration) -> None:
"""
must correctly parse target list
"""
assert DistributedSystem.configuration_sections(configuration) == ["worker"]
def test_workers_url(distributed_system: DistributedSystem) -> None:
"""
must generate workers url correctly
"""
assert distributed_system._workers_url().startswith(distributed_system.address)
assert distributed_system._workers_url().endswith("/api/v1/distributed")
def test_register(distributed_system: DistributedSystem, mocker: MockerFixture) -> None:
"""
must register service
"""
run_mock = mocker.patch("ahriman.core.distributed.distributed_system.DistributedSystem.make_request")
distributed_system.register()
run_mock.assert_called_once_with("POST", f"{distributed_system.address}/api/v1/distributed",
json=distributed_system.worker.view())
def test_register_failed(distributed_system: DistributedSystem, mocker: MockerFixture) -> None:
"""
must suppress any exception happened during worker registration
"""
mocker.patch("requests.Session.request", side_effect=Exception)
distributed_system.register()
def test_register_failed_http_error(distributed_system: DistributedSystem, mocker: MockerFixture) -> None:
"""
must suppress HTTP exception happened during worker registration
"""
mocker.patch("requests.Session.request", side_effect=requests.HTTPError)
distributed_system.register()
def test_workers(distributed_system: DistributedSystem, mocker: MockerFixture) -> None:
"""
must return available remote workers
"""
worker = Worker("remote")
response_obj = requests.Response()
response_obj._content = json.dumps([worker.view()]).encode("utf8")
response_obj.status_code = 200
requests_mock = mocker.patch("ahriman.core.status.web_client.WebClient.make_request",
return_value=response_obj)
result = distributed_system.workers()
requests_mock.assert_called_once_with("GET", distributed_system._workers_url())
assert result == [worker]
def test_workers_failed(distributed_system: DistributedSystem, mocker: MockerFixture) -> None:
"""
must suppress any exception happened during worker extraction
"""
mocker.patch("requests.Session.request", side_effect=Exception)
distributed_system.workers()
def test_workers_failed_http_error(distributed_system: DistributedSystem, mocker: MockerFixture) -> None:
"""
must suppress HTTP exception happened during worker extraction
"""
mocker.patch("requests.Session.request", side_effect=requests.HTTPError)
distributed_system.workers()
@@ -0,0 +1,47 @@
from pytest_mock import MockerFixture
from ahriman.core.configuration import Configuration
from ahriman.core.distributed import WorkerLoaderTrigger
from ahriman.models.worker import Worker
def test_on_start(configuration: Configuration, mocker: MockerFixture) -> None:
"""
must load workers from remote
"""
worker = Worker("address")
configuration.set_option("status", "address", "http://localhost:8081")
run_mock = mocker.patch("ahriman.core.distributed.WorkerLoaderTrigger.workers", return_value=[worker])
_, repository_id = configuration.check_loaded()
trigger = WorkerLoaderTrigger(repository_id, configuration)
trigger.on_start()
run_mock.assert_called_once_with()
assert configuration.getlist("build", "workers") == [worker.address]
def test_on_start_skip(configuration: Configuration, mocker: MockerFixture) -> None:
"""
must skip loading if option is already set
"""
configuration.set_option("status", "address", "http://localhost:8081")
configuration.set_option("build", "workers", "address")
run_mock = mocker.patch("ahriman.core.distributed.WorkerLoaderTrigger.workers")
_, repository_id = configuration.check_loaded()
trigger = WorkerLoaderTrigger(repository_id, configuration)
trigger.on_start()
run_mock.assert_not_called()
def test_on_start_empty_list(configuration: Configuration, mocker: MockerFixture) -> None:
"""
must do not set anything if workers are not available
"""
configuration.set_option("status", "address", "http://localhost:8081")
mocker.patch("ahriman.core.distributed.WorkerLoaderTrigger.workers", return_value=[])
_, repository_id = configuration.check_loaded()
trigger = WorkerLoaderTrigger(repository_id, configuration)
trigger.on_start()
assert not configuration.has_option("build", "workers")
@@ -0,0 +1,62 @@
from pytest_mock import MockerFixture
from threading import Timer
from ahriman.core.distributed import WorkerTrigger
def test_create_timer(worker_trigger: WorkerTrigger) -> None:
"""
must create a timer and put it to queue
"""
worker_trigger.create_timer()
assert worker_trigger._timer.function == worker_trigger.ping
worker_trigger._timer.cancel()
def test_on_start(worker_trigger: WorkerTrigger, mocker: MockerFixture) -> None:
"""
must register itself as worker
"""
run_mock = mocker.patch("ahriman.core.distributed.WorkerTrigger.create_timer")
worker_trigger.on_start()
run_mock.assert_called_once_with()
def test_on_stop(worker_trigger: WorkerTrigger, mocker: MockerFixture) -> None:
"""
must unregister itself as worker
"""
run_mock = mocker.patch("threading.Timer.cancel")
worker_trigger._timer = Timer(1, print) # doesn't matter
worker_trigger.on_stop()
run_mock.assert_called_once_with()
def test_on_stop_empty_timer(worker_trigger: WorkerTrigger) -> None:
"""
must do not fail if no timer was started
"""
worker_trigger.on_stop()
def test_ping(worker_trigger: WorkerTrigger, mocker: MockerFixture) -> None:
"""
must correctly process timer action
"""
run_mock = mocker.patch("ahriman.core.distributed.WorkerTrigger.register")
timer_mock = mocker.patch("threading.Timer.start")
worker_trigger._timer = Timer(1, print) # doesn't matter
worker_trigger.ping()
run_mock.assert_called_once_with()
timer_mock.assert_called_once_with()
def test_ping_empty_queue(worker_trigger: WorkerTrigger, mocker: MockerFixture) -> None:
"""
must do nothing in case of empty queue
"""
run_mock = mocker.patch("ahriman.core.distributed.WorkerTrigger.register")
worker_trigger.ping()
run_mock.assert_not_called()
@@ -0,0 +1,43 @@
import time
from ahriman.core.distributed import WorkersCache
from ahriman.models.worker import Worker
def test_workers(workers_cache: WorkersCache) -> None:
"""
must return alive workers
"""
workers_cache._workers = {
str(index): (Worker(f"address{index}"), index)
for index in range(2)
}
workers_cache.time_to_live = time.monotonic()
assert workers_cache.workers == [Worker("address1")]
def test_workers_remove(workers_cache: WorkersCache) -> None:
"""
must remove all workers
"""
workers_cache.workers_update(Worker("address"))
assert workers_cache.workers
workers_cache.workers_remove()
assert not workers_cache.workers
def test_workers_update(workers_cache: WorkersCache) -> None:
"""
must update worker
"""
worker = Worker("address")
workers_cache.workers_update(worker)
assert workers_cache.workers == [worker]
_, first_last_seen = workers_cache._workers[worker.identifier]
workers_cache.workers_update(worker)
_, second_last_seen = workers_cache._workers[worker.identifier]
assert first_last_seen < second_last_seen
@@ -0,0 +1,35 @@
import pytest
from ahriman.core.configuration import Configuration
from ahriman.core.support.package_creator import PackageCreator
from ahriman.core.support.pkgbuild.mirrorlist_generator import MirrorlistGenerator
@pytest.fixture
def mirrorlist_generator(configuration: Configuration) -> MirrorlistGenerator:
"""
fixture for mirrorlist pkgbuild generator
Args:
configuration(Configuration): configuration fixture
Returns:
MirrorlistGenerator: mirrorlist pkgbuild generator test instance
"""
_, repository_id = configuration.check_loaded()
return MirrorlistGenerator(repository_id, configuration, "mirrorlist")
@pytest.fixture
def package_creator(configuration: Configuration, mirrorlist_generator: MirrorlistGenerator) -> PackageCreator:
"""
package creator fixture
Args:
configuration(Configuration): configuration fixture
mirrorlist_generator(MirrorlistGenerator):
Returns:
PackageCreator: package creator test instance
"""
return PackageCreator(configuration, mirrorlist_generator)
@@ -0,0 +1,35 @@
import pytest
from ahriman.core.configuration import Configuration
from ahriman.core.database import SQLite
from ahriman.core.sign.gpg import GPG
from ahriman.core.support.pkgbuild.keyring_generator import KeyringGenerator
from ahriman.core.support.pkgbuild.pkgbuild_generator import PkgbuildGenerator
@pytest.fixture
def keyring_generator(database: SQLite, gpg: GPG, configuration: Configuration) -> KeyringGenerator:
"""
fixture for keyring pkgbuild generator
Args:
database(SQLite): database fixture
gpg(GPG): empty GPG fixture
configuration(Configuration): configuration fixture
Returns:
KeyringGenerator: keyring generator test instance
"""
_, repository_id = configuration.check_loaded()
return KeyringGenerator(database, gpg, repository_id, configuration, "keyring")
@pytest.fixture
def pkgbuild_generator() -> PkgbuildGenerator:
"""
fixture for dummy pkgbuild generator
Returns:
PkgbuildGenerator: pkgbuild generator test instance
"""
return PkgbuildGenerator()
@@ -0,0 +1,201 @@
import pytest
from pathlib import Path
from pytest_mock import MockerFixture
from unittest.mock import MagicMock, call as MockCall
from ahriman.core.configuration import Configuration
from ahriman.core.database import SQLite
from ahriman.core.exceptions import PkgbuildGeneratorError
from ahriman.core.sign.gpg import GPG
from ahriman.core.support.pkgbuild.keyring_generator import KeyringGenerator
from ahriman.models.user import User
def test_init_packagers(database: SQLite, gpg: GPG, configuration: Configuration, user: User,
mocker: MockerFixture) -> None:
"""
must extract packagers keys
"""
mocker.patch("ahriman.core.database.SQLite.user_list", return_value=[user])
_, repository_id = configuration.check_loaded()
assert KeyringGenerator(database, gpg, repository_id, configuration, "keyring").packagers == ["key"]
configuration.set_option("keyring", "packagers", "key1")
assert KeyringGenerator(database, gpg, repository_id, configuration, "keyring").packagers == ["key1"]
def test_init_revoked(database: SQLite, gpg: GPG, configuration: Configuration) -> None:
"""
must extract revoked keys
"""
_, repository_id = configuration.check_loaded()
assert KeyringGenerator(database, gpg, repository_id, configuration, "keyring").revoked == []
configuration.set_option("keyring", "revoked", "key1")
assert KeyringGenerator(database, gpg, repository_id, configuration, "keyring").revoked == ["key1"]
def test_init_trusted(database: SQLite, gpg: GPG, configuration: Configuration) -> None:
"""
must extract trusted keys
"""
_, repository_id = configuration.check_loaded()
assert KeyringGenerator(database, gpg, repository_id, configuration, "keyring").trusted == []
gpg.default_key = "key"
assert KeyringGenerator(database, gpg, repository_id, configuration, "keyring").trusted == ["key"]
configuration.set_option("keyring", "trusted", "key1")
assert KeyringGenerator(database, gpg, repository_id, configuration, "keyring").trusted == ["key1"]
def test_license(database: SQLite, gpg: GPG, configuration: Configuration) -> None:
"""
must generate correct licenses list
"""
_, repository_id = configuration.check_loaded()
assert KeyringGenerator(database, gpg, repository_id, configuration, "keyring").license == ["Unlicense"]
configuration.set_option("keyring", "license", "GPL MPL")
assert KeyringGenerator(database, gpg, repository_id, configuration, "keyring").license == ["GPL", "MPL"]
def test_pkgdesc(database: SQLite, gpg: GPG, configuration: Configuration) -> None:
"""
must generate correct pkgdesc property
"""
_, repository_id = configuration.check_loaded()
assert KeyringGenerator(database, gpg, repository_id, configuration, "keyring").pkgdesc == "aur PGP keyring"
configuration.set_option("keyring", "description", "description")
assert KeyringGenerator(database, gpg, repository_id, configuration, "keyring").pkgdesc == "description"
def test_pkgname(database: SQLite, gpg: GPG, configuration: Configuration) -> None:
"""
must generate correct pkgname property
"""
_, repository_id = configuration.check_loaded()
assert KeyringGenerator(database, gpg, repository_id, configuration, "keyring").pkgname == "aur-keyring"
configuration.set_option("keyring", "package", "keyring")
assert KeyringGenerator(database, gpg, repository_id, configuration, "keyring").pkgname == "keyring"
def test_url(database: SQLite, gpg: GPG, configuration: Configuration) -> None:
"""
must generate correct url property
"""
_, repository_id = configuration.check_loaded()
assert KeyringGenerator(database, gpg, repository_id, configuration, "keyring").url == ""
configuration.set_option("keyring", "homepage", "homepage")
assert KeyringGenerator(database, gpg, repository_id, configuration, "keyring").url == "homepage"
def test_generate_gpg(keyring_generator: KeyringGenerator, mocker: MockerFixture) -> None:
"""
must correctly generate file with all PGP keys
"""
file_mock = MagicMock()
export_mock = mocker.patch("ahriman.core.sign.gpg.GPG.key_export", side_effect=lambda key: key)
open_mock = mocker.patch("pathlib.Path.open")
open_mock.return_value.__enter__.return_value = file_mock
keyring_generator.packagers = ["key"]
keyring_generator.revoked = ["revoked"]
keyring_generator.trusted = ["trusted", "key"]
keyring_generator._generate_gpg(Path("local"))
open_mock.assert_called_once_with("w", encoding="utf8")
export_mock.assert_has_calls([MockCall("key"), MockCall("revoked"), MockCall("trusted")])
file_mock.write.assert_has_calls([
MockCall("key"), MockCall("\n"),
MockCall("revoked"), MockCall("\n"),
MockCall("trusted"), MockCall("\n"),
])
def test_generate_revoked(keyring_generator: KeyringGenerator, mocker: MockerFixture) -> None:
"""
must correctly generate file with revoked keys
"""
file_mock = MagicMock()
fingerprint_mock = mocker.patch("ahriman.core.sign.gpg.GPG.key_fingerprint", side_effect=lambda key: key)
open_mock = mocker.patch("pathlib.Path.open")
open_mock.return_value.__enter__.return_value = file_mock
keyring_generator.revoked = ["revoked"]
keyring_generator._generate_revoked(Path("local"))
open_mock.assert_called_once_with("w", encoding="utf8")
fingerprint_mock.assert_called_once_with("revoked")
file_mock.write.assert_has_calls([MockCall("revoked"), MockCall("\n")])
def test_generate_trusted(keyring_generator: KeyringGenerator, mocker: MockerFixture) -> None:
"""
must correctly generate file with trusted keys
"""
file_mock = MagicMock()
fingerprint_mock = mocker.patch("ahriman.core.sign.gpg.GPG.key_fingerprint", side_effect=lambda key: key)
open_mock = mocker.patch("pathlib.Path.open")
open_mock.return_value.__enter__.return_value = file_mock
keyring_generator.trusted = ["trusted", "trusted"]
keyring_generator._generate_trusted(Path("local"))
open_mock.assert_called_once_with("w", encoding="utf8")
fingerprint_mock.assert_called_once_with("trusted")
file_mock.write.assert_has_calls([MockCall("trusted"), MockCall(":4:\n")])
def test_generate_trusted_empty(keyring_generator: KeyringGenerator) -> None:
"""
must raise PkgbuildGeneratorError if no trusted keys set
"""
with pytest.raises(PkgbuildGeneratorError):
keyring_generator._generate_trusted(Path("local"))
def test_install(keyring_generator: KeyringGenerator) -> None:
"""
must return install functions
"""
assert keyring_generator.install() == """post_upgrade() {
if usr/bin/pacman-key -l >/dev/null 2>&1; then
usr/bin/pacman-key --populate aur
usr/bin/pacman-key --updatedb
fi
}
post_install() {
if [ -x usr/bin/pacman-key ]; then
post_upgrade
fi
}"""
def test_package(keyring_generator: KeyringGenerator) -> None:
"""
must generate package function correctly
"""
assert keyring_generator.package() == """{
install -Dm644 "$srcdir/aur.gpg" "$pkgdir/usr/share/pacman/keyrings/aur.gpg"
install -Dm644 "$srcdir/aur-revoked" "$pkgdir/usr/share/pacman/keyrings/aur-revoked"
install -Dm644 "$srcdir/aur-trusted" "$pkgdir/usr/share/pacman/keyrings/aur-trusted"
}"""
def test_sources(keyring_generator: KeyringGenerator) -> None:
"""
must return valid sources files list
"""
assert keyring_generator.sources().get("aur.gpg")
assert keyring_generator.sources().get("aur-revoked")
assert keyring_generator.sources().get("aur-trusted")
@@ -0,0 +1,102 @@
from pathlib import Path
from pytest_mock import MockerFixture
from ahriman.core.configuration import Configuration
from ahriman.core.support.pkgbuild.mirrorlist_generator import MirrorlistGenerator
def test_init_path(configuration: Configuration) -> None:
"""
must set relative path to mirrorlist
"""
_, repository_id = configuration.check_loaded()
assert MirrorlistGenerator(repository_id, configuration, "mirrorlist").path == \
Path("etc") / "pacman.d" / "aur-mirrorlist"
configuration.set_option("mirrorlist", "path", "/etc")
assert MirrorlistGenerator(repository_id, configuration, "mirrorlist").path == Path("etc")
def test_license(configuration: Configuration) -> None:
"""
must generate correct licenses list
"""
_, repository_id = configuration.check_loaded()
assert MirrorlistGenerator(repository_id, configuration, "mirrorlist").license == ["Unlicense"]
configuration.set_option("mirrorlist", "license", "GPL MPL")
assert MirrorlistGenerator(repository_id, configuration, "mirrorlist").license == ["GPL", "MPL"]
def test_pkgdesc(configuration: Configuration) -> None:
"""
must generate correct pkgdesc property
"""
_, repository_id = configuration.check_loaded()
assert MirrorlistGenerator(repository_id, configuration, "mirrorlist").pkgdesc == \
"aur mirror list for use by pacman"
configuration.set_option("mirrorlist", "description", "description")
assert MirrorlistGenerator(repository_id, configuration, "mirrorlist").pkgdesc == "description"
def test_pkgname(configuration: Configuration) -> None:
"""
must generate correct pkgname property
"""
_, repository_id = configuration.check_loaded()
assert MirrorlistGenerator(repository_id, configuration, "mirrorlist").pkgname == "aur-mirrorlist"
configuration.set_option("mirrorlist", "package", "mirrorlist")
assert MirrorlistGenerator(repository_id, configuration, "mirrorlist").pkgname == "mirrorlist"
def test_url(configuration: Configuration) -> None:
"""
must generate correct url property
"""
_, repository_id = configuration.check_loaded()
assert MirrorlistGenerator(repository_id, configuration, "mirrorlist").url == ""
configuration.set_option("mirrorlist", "homepage", "homepage")
assert MirrorlistGenerator(repository_id, configuration, "mirrorlist").url == "homepage"
def test_generate_mirrorlist(mirrorlist_generator: MirrorlistGenerator, mocker: MockerFixture) -> None:
"""
must correctly generate mirrorlist file
"""
write_mock = mocker.patch("pathlib.Path.write_text")
mirrorlist_generator._generate_mirrorlist(Path("local"))
write_mock.assert_called_once_with("Server = http://localhost\n", encoding="utf8")
def test_package(mirrorlist_generator: MirrorlistGenerator) -> None:
"""
must generate package function correctly
"""
assert mirrorlist_generator.package() == """{
install -Dm644 "$srcdir/mirrorlist" "$pkgdir/etc/pacman.d/aur-mirrorlist"
}"""
def test_patches(mirrorlist_generator: MirrorlistGenerator) -> None:
"""
must generate additional patch list
"""
patches = {patch.key: patch for patch in mirrorlist_generator.patches()}
assert "backup" in patches
assert patches["backup"].value == [str(mirrorlist_generator.path)]
def test_sources(mirrorlist_generator: MirrorlistGenerator) -> None:
"""
must return valid sources files list
"""
assert mirrorlist_generator.sources().get("mirrorlist")
@@ -0,0 +1,140 @@
import datetime
import pytest
from pathlib import Path
from pytest_mock import MockerFixture
from unittest.mock import MagicMock, call as MockCall
from ahriman.core.support.pkgbuild.pkgbuild_generator import PkgbuildGenerator
from ahriman.models.pkgbuild_patch import PkgbuildPatch
def test_license(pkgbuild_generator: PkgbuildGenerator) -> None:
"""
must return empty license list
"""
assert pkgbuild_generator.license == []
def test_pkgdesc(pkgbuild_generator: PkgbuildGenerator) -> None:
"""
must raise NotImplementedError on missing pkgdesc property
"""
with pytest.raises(NotImplementedError):
assert pkgbuild_generator.pkgdesc
def test_pkgname(pkgbuild_generator: PkgbuildGenerator) -> None:
"""
must raise NotImplementedError on missing pkgname property
"""
with pytest.raises(NotImplementedError):
assert pkgbuild_generator.pkgname
def test_pkgver(pkgbuild_generator: PkgbuildGenerator, mocker: MockerFixture) -> None:
"""
must implement default version as current date
"""
mocker.patch("ahriman.core.support.pkgbuild.pkgbuild_generator.utcnow", return_value=datetime.datetime(2002, 3, 11))
assert pkgbuild_generator.pkgver == "20020311"
def test_url(pkgbuild_generator: PkgbuildGenerator) -> None:
"""
must return empty url
"""
assert pkgbuild_generator.url == ""
def test_install(pkgbuild_generator: PkgbuildGenerator) -> None:
"""
must return empty install function
"""
assert pkgbuild_generator.install() is None
def test_package(pkgbuild_generator: PkgbuildGenerator) -> None:
"""
must raise NotImplementedError on missing package function
"""
with pytest.raises(NotImplementedError):
pkgbuild_generator.package()
def test_patches(pkgbuild_generator: PkgbuildGenerator) -> None:
"""
must return empty patches list
"""
assert pkgbuild_generator.patches() == []
def test_sources(pkgbuild_generator: PkgbuildGenerator) -> None:
"""
must return empty sources list
"""
assert pkgbuild_generator.sources() == {}
def test_write_install(pkgbuild_generator: PkgbuildGenerator, mocker: MockerFixture) -> None:
"""
must write install file
"""
mocker.patch.object(PkgbuildGenerator, "pkgname", "package")
mocker.patch("ahriman.core.support.pkgbuild.pkgbuild_generator.PkgbuildGenerator.install", return_value="content")
write_mock = mocker.patch("pathlib.Path.write_text")
assert pkgbuild_generator.write_install(Path("local")) == [PkgbuildPatch("install", "package.install")]
write_mock.assert_called_once_with("content")
def test_write_install_empty(pkgbuild_generator: PkgbuildGenerator) -> None:
"""
must return empty patch list for missing install function
"""
assert pkgbuild_generator.write_install(Path("local")) == []
def test_write_pkgbuild(pkgbuild_generator: PkgbuildGenerator, mocker: MockerFixture) -> None:
"""
must write PKGBUILD content to file
"""
path = Path("local")
for prop in ("pkgdesc", "pkgname"):
mocker.patch.object(PkgbuildGenerator, prop, "")
mocker.patch("ahriman.core.support.pkgbuild.pkgbuild_generator.PkgbuildGenerator.package", return_value="{}")
patches_mock = mocker.patch("ahriman.core.support.pkgbuild.pkgbuild_generator.PkgbuildGenerator.patches",
return_value=[PkgbuildPatch("property", "value")])
install_mock = mocker.patch("ahriman.core.support.pkgbuild.pkgbuild_generator.PkgbuildGenerator.write_install",
return_value=[PkgbuildPatch("install", "pkgname.install")])
sources_mock = mocker.patch("ahriman.core.support.pkgbuild.pkgbuild_generator.PkgbuildGenerator.write_sources",
return_value=[PkgbuildPatch("source", []), PkgbuildPatch("sha512sums", [])])
write_mock = mocker.patch("ahriman.models.pkgbuild_patch.PkgbuildPatch.write")
pkgbuild_generator.write_pkgbuild(path)
patches_mock.assert_called_once_with()
install_mock.assert_called_once_with(path)
sources_mock.assert_called_once_with(path)
write_mock.assert_has_calls([MockCall(path / "PKGBUILD")] * 12)
def test_write_sources(pkgbuild_generator: PkgbuildGenerator, mocker: MockerFixture) -> None:
"""
must write sources files
"""
path = Path("local")
generator_mock = MagicMock()
sources_mock = mocker.patch("ahriman.core.support.pkgbuild.pkgbuild_generator.PkgbuildGenerator.sources",
return_value={"source": generator_mock})
open_mock = mocker.patch("pathlib.Path.open")
hash_mock = MagicMock()
hash_mock.hexdigest.return_value = "hash"
mocker.patch("hashlib.sha512", return_value=hash_mock)
assert pkgbuild_generator.write_sources(path) == [
PkgbuildPatch("source", ["source"]),
PkgbuildPatch("sha512sums", ["hash"]),
]
generator_mock.assert_called_once_with(path / "source")
sources_mock.assert_called_once_with()
open_mock.assert_called_once_with("rb")
@@ -0,0 +1,32 @@
from pytest_mock import MockerFixture
from unittest.mock import call as MockCall
from ahriman.core.configuration import Configuration
from ahriman.core.database import SQLite
from ahriman.core.sign.gpg import GPG
from ahriman.core.support import KeyringTrigger
def test_configuration_sections(configuration: Configuration) -> None:
"""
must correctly parse target list
"""
configuration.set_option("keyring", "target", "a b c")
assert KeyringTrigger.configuration_sections(configuration) == ["a", "b", "c"]
configuration.remove_option("keyring", "target")
assert KeyringTrigger.configuration_sections(configuration) == []
def test_on_start(configuration: Configuration, mocker: MockerFixture) -> None:
"""
must run report for specified targets
"""
context_mock = mocker.patch("ahriman.core._Context.get")
run_mock = mocker.patch("ahriman.core.support.package_creator.PackageCreator.run")
_, repository_id = configuration.check_loaded()
trigger = KeyringTrigger(repository_id, configuration)
trigger.on_start()
context_mock.assert_has_calls([MockCall(GPG), MockCall(SQLite)])
run_mock.assert_called_once_with()
@@ -0,0 +1,27 @@
from pytest_mock import MockerFixture
from ahriman.core.configuration import Configuration
from ahriman.core.support import MirrorlistTrigger
def test_configuration_sections(configuration: Configuration) -> None:
"""
must correctly parse target list
"""
configuration.set_option("mirrorlist", "target", "a b c")
assert MirrorlistTrigger.configuration_sections(configuration) == ["a", "b", "c"]
configuration.remove_option("mirrorlist", "target")
assert MirrorlistTrigger.configuration_sections(configuration) == []
def test_on_start(configuration: Configuration, mocker: MockerFixture) -> None:
"""
must run report for specified targets
"""
run_mock = mocker.patch("ahriman.core.support.package_creator.PackageCreator.run")
_, repository_id = configuration.check_loaded()
trigger = MirrorlistTrigger(repository_id, configuration)
trigger.on_start()
run_mock.assert_called_once_with()
@@ -0,0 +1,60 @@
from pathlib import Path
from pytest_mock import MockerFixture
from ahriman.core.status import Client
from ahriman.core.support.package_creator import PackageCreator
from ahriman.models.package import Package
from ahriman.models.package_description import PackageDescription
from ahriman.models.package_source import PackageSource
from ahriman.models.remote_source import RemoteSource
def test_package_create(package_creator: PackageCreator, mocker: MockerFixture) -> None:
"""
must create package
"""
path = Path("local")
rmtree_mock = mocker.patch("shutil.rmtree")
mkdir_mock = mocker.patch("pathlib.Path.mkdir")
write_mock = mocker.patch("ahriman.core.support.pkgbuild.pkgbuild_generator.PkgbuildGenerator.write_pkgbuild")
init_mock = mocker.patch("ahriman.core.build_tools.sources.Sources.init")
package_creator.package_create(path)
rmtree_mock.assert_called_once_with(path, ignore_errors=True)
mkdir_mock.assert_called_once_with(mode=0o755, parents=True, exist_ok=True)
write_mock.assert_called_once_with(path)
init_mock.assert_called_once_with(path)
def test_package_register(package_creator: PackageCreator, mocker: MockerFixture) -> None:
"""
must register package
"""
path = Path("local")
package = Package(
base=package_creator.generator.pkgname,
version=package_creator.generator.pkgver,
remote=RemoteSource(source=PackageSource.Local),
packages={package_creator.generator.pkgname: PackageDescription()},
)
client_mock = mocker.patch("ahriman.core._Context.get", return_value=Client())
insert_mock = mocker.patch("ahriman.core.status.Client.set_unknown")
package_mock = mocker.patch("ahriman.models.package.Package.from_build", return_value=package)
package_creator.package_register(path)
package_mock.assert_called_once_with(path, "x86_64", None)
client_mock.assert_called_once_with(Client)
insert_mock.assert_called_once_with(package)
def test_run(package_creator: PackageCreator, mocker: MockerFixture) -> None:
"""
must correctly process package creation
"""
path = package_creator.configuration.repository_paths.cache_for(package_creator.generator.pkgname)
create_mock = mocker.patch("ahriman.core.support.package_creator.PackageCreator.package_create")
register_mock = mocker.patch("ahriman.core.support.package_creator.PackageCreator.package_register")
package_creator.run()
create_mock.assert_called_once_with(path)
register_mock.assert_called_once_with(path)
+13
View File
@@ -0,0 +1,13 @@
# pylint: disable=wildcard-import,unused-wildcard-import
from fixtures import *
import sys
from pathlib import Path
import pytest
sys.path.insert(0, str(Path(__file__).resolve().parents[2] / "tests"))
@pytest.fixture
def resource_path_root() -> Path:
return Path(__file__).resolve().parents[2] / "tests" / "testresources"