alpm tests implementation

This commit is contained in:
Evgenii Alekseev 2021-03-22 03:47:20 +03:00
parent 449b8a2033
commit 1ab2921e25
8 changed files with 229 additions and 10 deletions

View File

@ -68,15 +68,17 @@ class Repo:
cwd=self.paths.repository,
logger=self.logger)
def remove(self, package: str) -> None:
def remove(self, package: str, filename: str) -> None:
"""
remove package from repository
:param package: package name to remove
:param filename: package filename to remove
"""
# remove package and signature (if any) from filesystem
for fn in filter(lambda f: f.startswith(package), os.listdir(self.paths.repository)):
for fn in filter(lambda f: f.startswith(filename), os.listdir(self.paths.repository)):
full_path = os.path.join(self.paths.repository, fn)
os.remove(full_path)
# remove package from registry
Repo._check_output(
"repo-remove", *self.sign_args, self.repo_path, package,

View File

@ -73,23 +73,33 @@ class Executor(Cleaner):
:param packages: list of package names or bases to rmeove
:return: path to repository database
"""
def remove_single(package: str) -> None:
def remove_single(package: str, filename: Optional[str]) -> None:
if filename is None:
self.logger.warning(f"could not remove {package} because no filename set")
return
try:
self.repo.remove(package)
self.repo.remove(package, filename)
except Exception:
self.logger.exception(f"could not remove {package}", exc_info=True)
requested = set(packages)
for local in self.packages():
if local.base in packages:
to_remove = set(local.packages.keys())
if local.base in packages or all(package in requested for package in local.packages):
to_remove = {
package: properties.filename
for package, properties in local.packages.items()
}
self.reporter.remove(local.base) # we only update status page in case of base removal
elif requested.intersection(local.packages.keys()):
to_remove = requested.intersection(local.packages.keys())
to_remove = {
package: properties.filename
for package, properties in local.packages.items()
if package in requested
}
else:
to_remove = set()
for package in to_remove:
remove_single(package)
to_remove = dict()
for package, filename in to_remove.items():
remove_single(package, filename)
return self.repo.repo_path

View File

@ -0,0 +1,10 @@
from ahriman.core.alpm.pacman import Pacman
def test_all_packages(pacman: Pacman) -> None:
"""
package list must not be empty
"""
packages = pacman.all_packages()
assert packages
assert "pacman" in packages

View File

@ -0,0 +1,65 @@
import os
import pytest
from pytest_mock import MockerFixture
from unittest import mock
from ahriman.core.alpm.repo import Repo
def test_repo_path(repo: Repo) -> None:
"""
name must be something like archive name
"""
assert repo.repo_path.endswith("db.tar.gz")
def test_repo_add(repo: Repo, mocker: MockerFixture) -> None:
"""
must call repo-add on package addition
"""
check_output_mock = mocker.patch("ahriman.core.alpm.repo.Repo._check_output")
repo.add("path")
Repo._check_output.assert_called_once()
assert check_output_mock.call_args[0][0] == "repo-add"
def test_repo_remove(repo: Repo, mocker: MockerFixture) -> None:
"""
must call repo-remove on package addition
"""
mocker.patch("os.listdir", return_value=[])
check_output_mock = mocker.patch("ahriman.core.alpm.repo.Repo._check_output")
repo.remove("package", "package.pkg.tar.xz")
Repo._check_output.assert_called_once()
assert check_output_mock.call_args[0][0] == "repo-remove"
def test_repo_remove_fail_no_file(repo: Repo, mocker: MockerFixture) -> None:
"""
must fail on missing file
"""
mocker.patch("os.listdir", return_value=["package.pkg.tar.xz"])
mocker.patch("os.remove", side_effect=FileNotFoundError())
with pytest.raises(FileNotFoundError):
repo.remove("package", "package.pkg.tar.xz")
def test_repo_remove_remove_requested(repo: Repo, mocker: MockerFixture) -> None:
"""
must remove only requested files
"""
packages = ["package.pkg.tar.xz", "package.pkg.tar.xz.sig"]
all_packages = packages + ["valid-package.pkg.tar.xz.sig", "package-valid.pkg.tar.xz.sig"]
mocker.patch("os.listdir", return_value=all_packages)
remove_mock = mocker.patch("os.remove")
mocker.patch("ahriman.core.alpm.repo.Repo._check_output")
repo.remove("package", "package.pkg.tar.xz")
removed = [call.call_list()[0][0][0] for call in remove_mock.call_args_list]
to_be_removed = [os.path.join(repo.paths.repository, package) for package in packages]
assert set(removed) == set(to_be_removed)

View File

@ -0,0 +1,27 @@
from pathlib import Path
import pytest
from ahriman.core.alpm.pacman import Pacman
from ahriman.core.alpm.repo import Repo
from ahriman.core.configuration import Configuration
from ahriman.models.repository_paths import RepositoryPaths
@pytest.fixture
def configuration(resource_path_root: Path) -> Configuration:
path = resource_path_root / "core" / "ahriman.ini"
return Configuration.from_path(path=str(path), logfile=False)
@pytest.fixture
def pacman(configuration: Configuration) -> Pacman:
return Pacman(configuration)
@pytest.fixture
def repo(configuration: Configuration) -> Repo:
return Repo(
configuration.get("repository", "name"),
RepositoryPaths(configuration.get("repository", "root"), "x86_64"),
[])

View File

View File

@ -0,0 +1,46 @@
[settings]
logging = logging.ini
[alpm]
aur_url = https://aur.archlinux.org
database = /var/lib/pacman
repositories = core extra community multilib
root = /
[build]
archbuild_flags =
build_command = extra-x86_64-build
ignore_packages =
makechrootpkg_flags =
makepkg_flags = --skippgpcheck
[repository]
name = aur-clone
root = /var/lib/ahriman
[sign]
target =
key =
[report]
target =
[html]
path =
homepage =
link_path =
template_path = /usr/share/ahriman/repo-index.jinja2
[upload]
target =
[rsync]
remote =
[s3]
bucket =
[web]
host =
port =
templates = /usr/share/ahriman

View File

@ -0,0 +1,59 @@
[loggers]
keys = root,builder,build_details,http
[handlers]
keys = console_handler,build_file_handler,file_handler,http_handler
[formatters]
keys = generic_format
[handler_console_handler]
class = StreamHandler
level = DEBUG
formatter = generic_format
args = (sys.stderr,)
[handler_file_handler]
class = logging.handlers.RotatingFileHandler
level = DEBUG
formatter = generic_format
args = ('/var/log/ahriman/ahriman.log', 'a', 20971520, 20)
[handler_build_file_handler]
class = logging.handlers.RotatingFileHandler
level = DEBUG
formatter = generic_format
args = ('/var/log/ahriman/build.log', 'a', 20971520, 20)
[handler_http_handler]
class = logging.handlers.RotatingFileHandler
level = DEBUG
formatter = generic_format
args = ('/var/log/ahriman/http.log', 'a', 20971520, 20)
[formatter_generic_format]
format = [%(levelname)s %(asctime)s] [%(filename)s:%(lineno)d] [%(funcName)s]: %(message)s
datefmt =
[logger_root]
level = DEBUG
handlers = file_handler
qualname = root
[logger_builder]
level = DEBUG
handlers = file_handler
qualname = builder
propagate = 0
[logger_build_details]
level = DEBUG
handlers = build_file_handler
qualname = build_details
propagate = 0
[logger_http]
level = DEBUG
handlers = http_handler
qualname = http
propagate = 0