support provides in aur

This commit is contained in:
2025-06-26 11:05:15 +03:00
parent 7f223ecc0a
commit 98a540c658
14 changed files with 284 additions and 55 deletions

View File

@ -1,4 +1,6 @@
from pathlib import Path
from pytest_mock import MockerFixture
from typing import Any
from unittest.mock import MagicMock, call as MockCall
from ahriman.application.application import Application
@ -73,6 +75,10 @@ def test_with_dependencies(application: Application, package_ahriman: Package, p
mock.packages_full = [package_base]
return mock
def get_package(name: str | Path, *args: Any, **kwargs: Any) -> Package:
name = name if isinstance(name, str) else name.name
return packages[name]
package_python_schedule.packages = {
package_python_schedule.base: package_python_schedule.packages[package_python_schedule.base]
}
@ -87,10 +93,8 @@ def test_with_dependencies(application: Application, package_ahriman: Package, p
}
mocker.patch("pathlib.Path.is_dir", autospec=True, side_effect=lambda p: p.name == "python")
package_aur_mock = mocker.patch("ahriman.models.package.Package.from_aur",
side_effect=lambda *args: packages[args[0]])
package_local_mock = mocker.patch("ahriman.models.package.Package.from_build",
side_effect=lambda *args: packages[args[0].name])
package_aur_mock = mocker.patch("ahriman.models.package.Package.from_aur", side_effect=get_package)
package_local_mock = mocker.patch("ahriman.models.package.Package.from_build", side_effect=get_package)
packages_mock = mocker.patch("ahriman.application.application.Application._known_packages",
return_value={"devtools", "python-build", "python-pytest"})
status_client_mock = mocker.patch("ahriman.core.status.Client.set_unknown")
@ -98,8 +102,8 @@ def test_with_dependencies(application: Application, package_ahriman: Package, p
result = application.with_dependencies([package_ahriman], process_dependencies=True)
assert {package.base: package for package in result} == packages
package_aur_mock.assert_has_calls([
MockCall(package_python_schedule.base, package_ahriman.packager),
MockCall("python-installer", package_ahriman.packager),
MockCall(package_python_schedule.base, package_ahriman.packager, include_provides=True),
MockCall("python-installer", package_ahriman.packager, include_provides=True),
], any_order=True)
package_local_mock.assert_has_calls([
MockCall(application.repository.paths.cache_for("python"), "x86_64", package_ahriman.packager),

View File

@ -4,7 +4,7 @@ import requests
from pathlib import Path
from pytest_mock import MockerFixture
from unittest.mock import MagicMock
from unittest.mock import MagicMock, call as MockCall
from ahriman.core.alpm.remote import AUR
from ahriman.core.exceptions import PackageInfoError, UnknownPackageError
@ -139,17 +139,46 @@ def test_package_info(aur: AUR, aur_package_ahriman: AURPackage, mocker: MockerF
def test_package_info_not_found(aur: AUR, aur_package_ahriman: AURPackage, mocker: MockerFixture) -> None:
"""
must raise UnknownPackage exception in case if no package was found
must raise UnknownPackageError in case if no package was found
"""
mocker.patch("ahriman.core.alpm.remote.AUR.aur_request", return_value=[])
with pytest.raises(UnknownPackageError, match=aur_package_ahriman.name):
assert aur.package_info(aur_package_ahriman.name, pacman=None)
def test_package_provided_by(aur: AUR, aur_package_ahriman: AURPackage, aur_package_akonadi: AURPackage,
mocker: MockerFixture) -> None:
"""
must search for packages which provide required one
"""
aur_package_ahriman.provides.append(aur_package_ahriman.name)
search_mock = mocker.patch("ahriman.core.alpm.remote.AUR.package_search", return_value=[
aur_package_ahriman, aur_package_akonadi
])
info_mock = mocker.patch("ahriman.core.alpm.remote.AUR.package_info", side_effect=[
aur_package_ahriman, aur_package_akonadi
])
assert aur.package_provided_by(aur_package_ahriman.name, pacman=None) == [aur_package_ahriman]
search_mock.assert_called_once_with(aur_package_ahriman.name, pacman=None, search_by="provides")
info_mock.assert_has_calls([
MockCall(aur_package_ahriman.name, pacman=None), MockCall(aur_package_akonadi.name, pacman=None)
])
def test_package_search(aur: AUR, aur_package_ahriman: AURPackage, mocker: MockerFixture) -> None:
"""
must make request for search
"""
request_mock = mocker.patch("ahriman.core.alpm.remote.AUR.aur_request", return_value=[aur_package_ahriman])
assert aur.package_search(aur_package_ahriman.name, pacman=None) == [aur_package_ahriman]
assert aur.package_search(aur_package_ahriman.name, pacman=None, search_by=None) == [aur_package_ahriman]
request_mock.assert_called_once_with("search", aur_package_ahriman.name, by="name-desc")
def test_package_search_provides(aur: AUR, aur_package_ahriman: AURPackage, mocker: MockerFixture) -> None:
"""
must make request for search with custom field
"""
request_mock = mocker.patch("ahriman.core.alpm.remote.AUR.aur_request")
aur.package_search(aur_package_ahriman.name, pacman=None, search_by="provides")
request_mock.assert_called_once_with("search", aur_package_ahriman.name, by="provides")

View File

@ -106,7 +106,7 @@ def test_package_info(official: Official, aur_package_akonadi: AURPackage, mocke
def test_package_info_not_found(official: Official, aur_package_ahriman: AURPackage, mocker: MockerFixture) -> None:
"""
must raise UnknownPackage exception in case if no package was found
must raise UnknownPackageError in case if no package was found
"""
mocker.patch("ahriman.core.alpm.remote.Official.arch_request", return_value=[])
with pytest.raises(UnknownPackageError, match=aur_package_ahriman.name):
@ -119,5 +119,16 @@ def test_package_search(official: Official, aur_package_akonadi: AURPackage, moc
"""
request_mock = mocker.patch("ahriman.core.alpm.remote.Official.arch_request",
return_value=[aur_package_akonadi])
assert official.package_search(aur_package_akonadi.name, pacman=None) == [aur_package_akonadi]
assert official.package_search(aur_package_akonadi.name, pacman=None, search_by=None) == [
aur_package_akonadi,
]
request_mock.assert_called_once_with(aur_package_akonadi.name, by="q")
def test_package_search_name(official: Official, aur_package_akonadi: AURPackage, mocker: MockerFixture) -> None:
"""
must make request for search with custom field
"""
request_mock = mocker.patch("ahriman.core.alpm.remote.Official.arch_request")
official.package_search(aur_package_akonadi.name, pacman=None, search_by="name")
request_mock.assert_called_once_with(aur_package_akonadi.name, by="name")

View File

@ -16,18 +16,14 @@ def test_package_info(official_syncdb: OfficialSyncdb, aur_package_akonadi: AURP
mocker.patch("ahriman.models.aur_package.AURPackage.from_pacman", return_value=aur_package_akonadi)
get_mock = mocker.patch("ahriman.core.alpm.pacman.Pacman.package", return_value=[aur_package_akonadi])
package = official_syncdb.package_info(aur_package_akonadi.name, pacman=pacman)
assert official_syncdb.package_info(aur_package_akonadi.name, pacman=pacman) == aur_package_akonadi
get_mock.assert_called_once_with(aur_package_akonadi.name)
assert package == aur_package_akonadi
def test_package_info_no_pacman(official_syncdb: OfficialSyncdb, aur_package_akonadi: AURPackage,
mocker: MockerFixture) -> None:
def test_package_info_no_pacman(official_syncdb: OfficialSyncdb, aur_package_akonadi: AURPackage) -> None:
"""
must raise UnknownPackageError if no pacman set
"""
mocker.patch("ahriman.core.alpm.pacman.Pacman.package", return_value=[aur_package_akonadi])
with pytest.raises(UnknownPackageError, match=aur_package_akonadi.name):
official_syncdb.package_info(aur_package_akonadi.name, pacman=None)
@ -40,3 +36,22 @@ def test_package_info_not_found(official_syncdb: OfficialSyncdb, aur_package_ako
mocker.patch("ahriman.core.alpm.pacman.Pacman.package", return_value=[])
with pytest.raises(UnknownPackageError, match=aur_package_akonadi.name):
assert official_syncdb.package_info(aur_package_akonadi.name, pacman=pacman)
def test_package_provided_by(official_syncdb: OfficialSyncdb, aur_package_akonadi: AURPackage, pacman: Pacman,
mocker: MockerFixture) -> None:
"""
must search by provides in database
"""
mocker.patch("ahriman.models.aur_package.AURPackage.from_pacman", return_value=aur_package_akonadi)
get_mock = mocker.patch("ahriman.core.alpm.pacman.Pacman.provided_by", return_value=[aur_package_akonadi])
assert official_syncdb.package_provided_by(aur_package_akonadi.name, pacman=pacman) == [aur_package_akonadi]
get_mock.assert_called_once_with(aur_package_akonadi.name)
def test_package_provided_by_no_pacman(official_syncdb: OfficialSyncdb, aur_package_akonadi: AURPackage) -> None:
"""
must return empty list if no pacman set
"""
assert official_syncdb.package_provided_by(aur_package_akonadi.name, pacman=None) == []

View File

@ -5,16 +5,53 @@ from unittest.mock import call as MockCall
from ahriman.core.alpm.pacman import Pacman
from ahriman.core.alpm.remote import Remote
from ahriman.core.exceptions import UnknownPackageError
from ahriman.models.aur_package import AURPackage
def test_info(pacman: Pacman, mocker: MockerFixture) -> None:
def test_info(aur_package_ahriman: AURPackage, pacman: Pacman, mocker: MockerFixture) -> None:
"""
must call info method
"""
info_mock = mocker.patch("ahriman.core.alpm.remote.Remote.package_info")
Remote.info("ahriman", pacman=pacman)
info_mock.assert_called_once_with("ahriman", pacman=pacman)
info_mock = mocker.patch("ahriman.core.alpm.remote.Remote.package_info", return_value=aur_package_ahriman)
assert Remote.info(aur_package_ahriman.name, pacman=pacman) == aur_package_ahriman
info_mock.assert_called_once_with(aur_package_ahriman.name, pacman=pacman)
def test_info_not_found(aur_package_ahriman: AURPackage, pacman: Pacman, mocker: MockerFixture) -> None:
"""
must raise UnknownPackageError if no package found and search by provides is disabled
"""
mocker.patch("ahriman.core.alpm.remote.Remote.package_info",
side_effect=UnknownPackageError(aur_package_ahriman.name))
with pytest.raises(UnknownPackageError):
Remote.info(aur_package_ahriman.name, pacman=pacman)
def test_info_include_provides(aur_package_ahriman: AURPackage, pacman: Pacman, mocker: MockerFixture) -> None:
"""
must perform search through provides list is set
"""
mocker.patch("ahriman.core.alpm.remote.Remote.package_info",
side_effect=UnknownPackageError(aur_package_ahriman.name))
provided_mock = mocker.patch("ahriman.core.alpm.remote.Remote.package_provided_by",
return_value=[aur_package_ahriman])
assert Remote.info(aur_package_ahriman.name, pacman=pacman, include_provides=True) == aur_package_ahriman
provided_mock.assert_called_once_with(aur_package_ahriman.name, pacman=pacman)
def test_info_include_provides_not_found(aur_package_ahriman: AURPackage, pacman: Pacman,
mocker: MockerFixture) -> None:
"""
must raise UnknownPackageError if no package found and search by provides returns empty list
"""
mocker.patch("ahriman.core.alpm.remote.Remote.package_info",
side_effect=UnknownPackageError(aur_package_ahriman.name))
mocker.patch("ahriman.core.alpm.remote.Remote.package_provided_by", return_value=[])
with pytest.raises(UnknownPackageError):
Remote.info("ahriman", pacman=pacman, include_provides=True)
def test_multisearch(aur_package_ahriman: AURPackage, pacman: Pacman, mocker: MockerFixture) -> None:
@ -22,10 +59,13 @@ def test_multisearch(aur_package_ahriman: AURPackage, pacman: Pacman, mocker: Mo
must search in AUR with multiple words
"""
terms = ["ahriman", "is", "cool"]
search_mock = mocker.patch("ahriman.core.alpm.remote.Remote.search", return_value=[aur_package_ahriman])
search_mock = mocker.patch("ahriman.core.alpm.remote.Remote.package_search", return_value=[aur_package_ahriman])
assert Remote.multisearch(*terms, pacman=pacman) == [aur_package_ahriman]
search_mock.assert_has_calls([MockCall("ahriman", pacman=pacman), MockCall("cool", pacman=pacman)])
assert Remote.multisearch(*terms, pacman=pacman, search_by="name") == [aur_package_ahriman]
search_mock.assert_has_calls([
MockCall("ahriman", pacman=pacman, search_by="name"),
MockCall("cool", pacman=pacman, search_by="name"),
])
def test_multisearch_empty(pacman: Pacman, mocker: MockerFixture) -> None:
@ -33,7 +73,7 @@ def test_multisearch_empty(pacman: Pacman, mocker: MockerFixture) -> None:
must return empty list if no long terms supplied
"""
terms = ["it", "is"]
search_mock = mocker.patch("ahriman.core.alpm.remote.Remote.search")
search_mock = mocker.patch("ahriman.core.alpm.remote.Remote.package_search")
assert Remote.multisearch(*terms, pacman=pacman) == []
search_mock.assert_not_called()
@ -43,9 +83,9 @@ def test_multisearch_single(aur_package_ahriman: AURPackage, pacman: Pacman, moc
"""
must search in AUR with one word
"""
search_mock = mocker.patch("ahriman.core.alpm.remote.Remote.search", return_value=[aur_package_ahriman])
search_mock = mocker.patch("ahriman.core.alpm.remote.Remote.package_search", return_value=[aur_package_ahriman])
assert Remote.multisearch("ahriman", pacman=pacman) == [aur_package_ahriman]
search_mock.assert_called_once_with("ahriman", pacman=pacman)
search_mock.assert_called_once_with("ahriman", pacman=pacman, search_by=None)
def test_remote_git_url(remote: Remote) -> None:
@ -69,8 +109,8 @@ def test_search(pacman: Pacman, mocker: MockerFixture) -> None:
must call search method
"""
search_mock = mocker.patch("ahriman.core.alpm.remote.Remote.package_search")
Remote.search("ahriman", pacman=pacman)
search_mock.assert_called_once_with("ahriman", pacman=pacman)
Remote.search("ahriman", pacman=pacman, search_by="name")
search_mock.assert_called_once_with("ahriman", pacman=pacman, search_by="name")
def test_package_info(remote: Remote, pacman: Pacman) -> None:
@ -81,9 +121,16 @@ def test_package_info(remote: Remote, pacman: Pacman) -> None:
remote.package_info("package", pacman=pacman)
def test_package_provided_by(remote: Remote, pacman: Pacman) -> None:
"""
must return empty list for provides method
"""
assert remote.package_provided_by("package", pacman=pacman) == []
def test_package_search(remote: Remote, pacman: Pacman) -> None:
"""
must raise NotImplemented for missing package search method
"""
with pytest.raises(NotImplementedError):
remote.package_search("package", pacman=pacman)
remote.package_search("package", pacman=pacman, search_by=None)

View File

@ -282,3 +282,10 @@ def test_packages_with_provides(pacman: Pacman) -> None:
"""
assert "sh" in pacman.packages()
assert "mysql" in pacman.packages() # mariadb
def test_package_provided_by(pacman: Pacman) -> None:
"""
must search through the provides lists
"""
assert list(pacman.provided_by("sh"))

View File

@ -167,15 +167,26 @@ def test_from_aur(package_ahriman: Package, aur_package_ahriman: AURPackage, moc
"""
must construct package from aur
"""
mocker.patch("ahriman.core.alpm.remote.AUR.info", return_value=aur_package_ahriman)
info_mock = mocker.patch("ahriman.core.alpm.remote.AUR.info", return_value=aur_package_ahriman)
package = Package.from_aur(package_ahriman.base, package_ahriman.packager)
info_mock.assert_called_once_with(package_ahriman.base, include_provides=False)
assert package_ahriman.base == package.base
assert package_ahriman.version == package.version
assert package_ahriman.packages.keys() == package.packages.keys()
assert package_ahriman.packager == package.packager
def test_from_aur_include_provides(package_ahriman: Package, aur_package_ahriman: AURPackage,
mocker: MockerFixture) -> None:
"""
must construct package from aur by using provides list
"""
info_mock = mocker.patch("ahriman.core.alpm.remote.AUR.info", return_value=aur_package_ahriman)
Package.from_aur(package_ahriman.base, package_ahriman.packager, include_provides=True)
info_mock.assert_called_once_with(package_ahriman.base, include_provides=True)
def test_from_build(package_ahriman: Package, mocker: MockerFixture, resource_path_root: Path) -> None:
"""
must construct package from PKGBUILD
@ -269,14 +280,25 @@ def test_from_json_view_3(package_tpacpi_bat_git: Package) -> None:
assert Package.from_json(package_tpacpi_bat_git.view()) == package_tpacpi_bat_git
def test_from_official_include_provides(package_ahriman: Package, aur_package_ahriman: AURPackage, pacman: Pacman,
mocker: MockerFixture) -> None:
"""
must construct package from official repository
"""
info_mock = mocker.patch("ahriman.core.alpm.remote.Official.info", return_value=aur_package_ahriman)
Package.from_official(package_ahriman.base, pacman, package_ahriman.packager, include_provides=True)
info_mock.assert_called_once_with(package_ahriman.base, pacman=pacman, include_provides=True)
def test_from_official(package_ahriman: Package, aur_package_ahriman: AURPackage, pacman: Pacman,
mocker: MockerFixture) -> None:
"""
must construct package from official repository
"""
mocker.patch("ahriman.core.alpm.remote.Official.info", return_value=aur_package_ahriman)
info_mock = mocker.patch("ahriman.core.alpm.remote.Official.info", return_value=aur_package_ahriman)
package = Package.from_official(package_ahriman.base, pacman, package_ahriman.packager)
info_mock.assert_called_once_with(package_ahriman.base, pacman=pacman, include_provides=False)
assert package_ahriman.base == package.base
assert package_ahriman.version == package.version
assert package_ahriman.packages.keys() == package.packages.keys()