mirror of
https://github.com/arcan1s/ahriman.git
synced 2025-11-17 22:13:41 +00:00
feat: add abillity to check broken dependencies (#122)
* implement elf dynamic linking check * load local database too in pacman wrapper
This commit is contained in:
@ -1,13 +1,14 @@
|
||||
import pytest
|
||||
import tarfile
|
||||
|
||||
from pathlib import Path
|
||||
from pyalpm import error as PyalpmError
|
||||
from pytest_mock import MockerFixture
|
||||
from tempfile import TemporaryDirectory
|
||||
from unittest.mock import MagicMock
|
||||
from unittest.mock import MagicMock, call as MockCall
|
||||
|
||||
from ahriman.core.alpm.pacman import Pacman
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.models.package import Package
|
||||
from ahriman.models.pacman_synchronization import PacmanSynchronization
|
||||
from ahriman.models.repository_paths import RepositoryPaths
|
||||
|
||||
@ -48,7 +49,7 @@ def test_init_with_local_cache_forced(configuration: Configuration, mocker: Mock
|
||||
sync_mock.assert_called_once_with(pytest.helpers.anyvar(int), force=True)
|
||||
|
||||
|
||||
def test_database_copy(pacman: Pacman, repository_paths: RepositoryPaths, mocker: MockerFixture) -> None:
|
||||
def test_database_copy(pacman: Pacman, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must copy database from root
|
||||
"""
|
||||
@ -62,13 +63,13 @@ def test_database_copy(pacman: Pacman, repository_paths: RepositoryPaths, mocker
|
||||
copy_mock = mocker.patch("shutil.copy")
|
||||
chown_mock = mocker.patch("ahriman.models.repository_paths.RepositoryPaths.chown")
|
||||
|
||||
pacman.database_copy(pacman.handle, database, path, repository_paths, use_ahriman_cache=True)
|
||||
pacman.database_copy(pacman.handle, database, path, use_ahriman_cache=True)
|
||||
mkdir_mock.assert_called_once_with(mode=0o755, exist_ok=True)
|
||||
copy_mock.assert_called_once_with(path / "sync" / "core.db", dst_path)
|
||||
chown_mock.assert_called_once_with(dst_path)
|
||||
|
||||
|
||||
def test_database_copy_skip(pacman: Pacman, repository_paths: RepositoryPaths, mocker: MockerFixture) -> None:
|
||||
def test_database_copy_skip(pacman: Pacman, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must do not copy database from root if local cache is disabled
|
||||
"""
|
||||
@ -79,11 +80,11 @@ def test_database_copy_skip(pacman: Pacman, repository_paths: RepositoryPaths, m
|
||||
mocker.patch("pathlib.Path.is_file", autospec=True, side_effect=lambda p: p.is_relative_to(path))
|
||||
copy_mock = mocker.patch("shutil.copy")
|
||||
|
||||
pacman.database_copy(pacman.handle, database, path, repository_paths, use_ahriman_cache=False)
|
||||
pacman.database_copy(pacman.handle, database, path, use_ahriman_cache=False)
|
||||
copy_mock.assert_not_called()
|
||||
|
||||
|
||||
def test_database_copy_no_directory(pacman: Pacman, repository_paths: RepositoryPaths, mocker: MockerFixture) -> None:
|
||||
def test_database_copy_no_directory(pacman: Pacman, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must do not copy database if local cache already exists
|
||||
"""
|
||||
@ -94,11 +95,11 @@ def test_database_copy_no_directory(pacman: Pacman, repository_paths: Repository
|
||||
mocker.patch("pathlib.Path.is_file", autospec=True, side_effect=lambda p: p.is_relative_to(path))
|
||||
copy_mock = mocker.patch("shutil.copy")
|
||||
|
||||
pacman.database_copy(pacman.handle, database, path, repository_paths, use_ahriman_cache=True)
|
||||
pacman.database_copy(pacman.handle, database, path, use_ahriman_cache=True)
|
||||
copy_mock.assert_not_called()
|
||||
|
||||
|
||||
def test_database_copy_no_root_file(pacman: Pacman, repository_paths: RepositoryPaths, mocker: MockerFixture) -> None:
|
||||
def test_database_copy_no_root_file(pacman: Pacman, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must do not copy database if no repository file exists in filesystem
|
||||
"""
|
||||
@ -109,11 +110,11 @@ def test_database_copy_no_root_file(pacman: Pacman, repository_paths: Repository
|
||||
mocker.patch("pathlib.Path.is_file", return_value=False)
|
||||
copy_mock = mocker.patch("shutil.copy")
|
||||
|
||||
pacman.database_copy(pacman.handle, database, path, repository_paths, use_ahriman_cache=True)
|
||||
pacman.database_copy(pacman.handle, database, path, use_ahriman_cache=True)
|
||||
copy_mock.assert_not_called()
|
||||
|
||||
|
||||
def test_database_copy_database_exist(pacman: Pacman, repository_paths: RepositoryPaths, mocker: MockerFixture) -> None:
|
||||
def test_database_copy_database_exist(pacman: Pacman, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must do not copy database if local cache already exists
|
||||
"""
|
||||
@ -123,7 +124,7 @@ def test_database_copy_database_exist(pacman: Pacman, repository_paths: Reposito
|
||||
mocker.patch("pathlib.Path.is_file", return_value=True)
|
||||
copy_mock = mocker.patch("shutil.copy")
|
||||
|
||||
pacman.database_copy(pacman.handle, database, Path("root"), repository_paths, use_ahriman_cache=True)
|
||||
pacman.database_copy(pacman.handle, database, Path("root"), use_ahriman_cache=True)
|
||||
copy_mock.assert_not_called()
|
||||
|
||||
|
||||
@ -131,71 +132,133 @@ def test_database_init(pacman: Pacman, configuration: Configuration) -> None:
|
||||
"""
|
||||
must init database with settings
|
||||
"""
|
||||
mirror = configuration.get("alpm", "mirror")
|
||||
database = pacman.database_init(pacman.handle, "testing", mirror, "x86_64")
|
||||
database = pacman.database_init(pacman.handle, "testing", "x86_64")
|
||||
assert database.servers == ["https://geo.mirror.pkgbuild.com/testing/os/x86_64"]
|
||||
|
||||
|
||||
def test_database_sync(pacman: Pacman) -> None:
|
||||
def test_database_init_local(pacman: Pacman, configuration: Configuration) -> None:
|
||||
"""
|
||||
must set file protocol for local databases
|
||||
"""
|
||||
_, repository_id = configuration.check_loaded()
|
||||
database = pacman.database_init(MagicMock(), repository_id.name, repository_id.architecture)
|
||||
assert database.servers == [f"file://{configuration.repository_paths.repository}"]
|
||||
|
||||
|
||||
def test_database_sync(pacman: Pacman, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must sync databases
|
||||
"""
|
||||
handle_mock = MagicMock()
|
||||
core_mock = MagicMock()
|
||||
extra_mock = MagicMock()
|
||||
transaction_mock = MagicMock()
|
||||
handle_mock.get_syncdbs.return_value = [core_mock, extra_mock]
|
||||
handle_mock.get_syncdbs.return_value = [1, 2]
|
||||
handle_mock.init_transaction.return_value = transaction_mock
|
||||
pacman.handle = handle_mock
|
||||
|
||||
pacman.database_sync(pacman.handle, force=False)
|
||||
sync_mock = mocker.patch("ahriman.core.alpm.pacman_database.PacmanDatabase.sync")
|
||||
|
||||
pacman.database_sync(handle_mock, force=False)
|
||||
handle_mock.init_transaction.assert_called_once_with()
|
||||
core_mock.update.assert_called_once_with(False)
|
||||
extra_mock.update.assert_called_once_with(False)
|
||||
sync_mock.assert_has_calls([MockCall(force=False), MockCall(force=False)])
|
||||
transaction_mock.release.assert_called_once_with()
|
||||
|
||||
|
||||
def test_database_sync_failed(pacman: Pacman) -> None:
|
||||
"""
|
||||
must sync databases even if there was exception
|
||||
"""
|
||||
handle_mock = MagicMock()
|
||||
core_mock = MagicMock()
|
||||
core_mock.update.side_effect = PyalpmError()
|
||||
extra_mock = MagicMock()
|
||||
handle_mock.get_syncdbs.return_value = [core_mock, extra_mock]
|
||||
pacman.handle = handle_mock
|
||||
|
||||
pacman.database_sync(pacman.handle, force=False)
|
||||
extra_mock.update.assert_called_once_with(False)
|
||||
|
||||
|
||||
def test_database_sync_forced(pacman: Pacman) -> None:
|
||||
def test_database_sync_forced(pacman: Pacman, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must sync databases with force flag
|
||||
"""
|
||||
handle_mock = MagicMock()
|
||||
core_mock = MagicMock()
|
||||
handle_mock.get_syncdbs.return_value = [core_mock]
|
||||
handle_mock.get_syncdbs.return_value = [1]
|
||||
|
||||
sync_mock = mocker.patch("ahriman.core.alpm.pacman_database.PacmanDatabase.sync")
|
||||
|
||||
pacman.database_sync(handle_mock, force=True)
|
||||
sync_mock.assert_called_once_with(force=True)
|
||||
|
||||
|
||||
def test_files(pacman: Pacman, package_ahriman: Package, mocker: MockerFixture, resource_path_root: Path) -> None:
|
||||
"""
|
||||
must load files from databases
|
||||
"""
|
||||
handle_mock = MagicMock()
|
||||
handle_mock.get_syncdbs.return_value = [MagicMock()]
|
||||
pacman.handle = handle_mock
|
||||
tarball = resource_path_root / "core" / "arcanisrepo.files.tar.gz"
|
||||
|
||||
mocker.patch("pathlib.Path.is_file", return_value=True)
|
||||
open_mock = mocker.patch("ahriman.core.alpm.pacman.tarfile.open", return_value=tarfile.open(tarball, "r:gz"))
|
||||
|
||||
files = pacman.files()
|
||||
assert len(files) == 2
|
||||
assert package_ahriman.base in files
|
||||
assert Path("usr/bin/ahriman") in files[package_ahriman.base]
|
||||
open_mock.assert_called_once_with(pytest.helpers.anyvar(int), "r:gz")
|
||||
|
||||
|
||||
def test_files_package(pacman: Pacman, package_ahriman: Package, mocker: MockerFixture,
|
||||
resource_path_root: Path) -> None:
|
||||
"""
|
||||
must load files only for the specified package
|
||||
"""
|
||||
handle_mock = MagicMock()
|
||||
handle_mock.get_syncdbs.return_value = [MagicMock()]
|
||||
pacman.handle = handle_mock
|
||||
|
||||
pacman.database_sync(pacman.handle, force=True)
|
||||
handle_mock.init_transaction.assert_called_once_with()
|
||||
core_mock.update.assert_called_once_with(True)
|
||||
tarball = resource_path_root / "core" / "arcanisrepo.files.tar.gz"
|
||||
|
||||
mocker.patch("pathlib.Path.is_file", return_value=True)
|
||||
mocker.patch("ahriman.core.alpm.pacman.tarfile.open", return_value=tarfile.open(tarball, "r:gz"))
|
||||
|
||||
files = pacman.files(package_ahriman.base)
|
||||
assert len(files) == 1
|
||||
assert package_ahriman.base in files
|
||||
|
||||
|
||||
def test_package_get(pacman: Pacman) -> None:
|
||||
def test_files_skip(pacman: Pacman, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must return empty list if no database found
|
||||
"""
|
||||
handle_mock = MagicMock()
|
||||
handle_mock.get_syncdbs.return_value = [MagicMock()]
|
||||
pacman.handle = handle_mock
|
||||
|
||||
mocker.patch("pathlib.Path.is_file", return_value=False)
|
||||
|
||||
assert not pacman.files()
|
||||
|
||||
|
||||
def test_files_no_content(pacman: Pacman, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must skip package if no content can be loaded
|
||||
"""
|
||||
handle_mock = MagicMock()
|
||||
handle_mock.get_syncdbs.return_value = [MagicMock()]
|
||||
pacman.handle = handle_mock
|
||||
|
||||
tar_mock = MagicMock()
|
||||
tar_mock.getmembers.return_value = [MagicMock()]
|
||||
tar_mock.extractfile.return_value = None
|
||||
|
||||
open_mock = MagicMock()
|
||||
open_mock.__enter__.return_value = tar_mock
|
||||
|
||||
mocker.patch("pathlib.Path.is_file", return_value=True)
|
||||
mocker.patch("ahriman.core.alpm.pacman.tarfile.open", return_value=open_mock)
|
||||
|
||||
assert not pacman.files()
|
||||
|
||||
|
||||
def test_package(pacman: Pacman) -> None:
|
||||
"""
|
||||
must retrieve package
|
||||
"""
|
||||
assert list(pacman.package_get("pacman"))
|
||||
assert list(pacman.package("pacman"))
|
||||
|
||||
|
||||
def test_package_get_empty(pacman: Pacman) -> None:
|
||||
def test_package_empty(pacman: Pacman) -> None:
|
||||
"""
|
||||
must return empty packages list without exception
|
||||
"""
|
||||
assert not list(pacman.package_get("some-random-name"))
|
||||
assert not list(pacman.package("some-random-name"))
|
||||
|
||||
|
||||
def test_packages(pacman: Pacman) -> None:
|
||||
|
||||
Reference in New Issue
Block a user