Files
2026-10-02 15:29:35 +02:00

177 lines
4.8 KiB
Python

"""Tests for the pacman sync database parser (built from a synthetic archive)."""
from __future__ import annotations
import gzip
import io
import tarfile
from sjaur.repodb import load_repo_packages, sync_db_paths
DESC = """%FILENAME%
linux-6.16.8-1-x86_64.pkg.tar.zst
%NAME%
linux
%BASE%
linux
%VERSION%
6.16.8-1
%DESC%
The Linux kernel and modules
%URL%
https://github.com/torvalds/linux
%ARCH%
x86_64
%PACKAGER%
Jan Alexander Steffens (heftig) <heftig@archlinux.org>
%BUILDDATE%
1757429406
"""
DEPENDS = """%DEPENDS%
coreutils
initramfs
kmod
%OPTDEPENDS%
linux-firmware: kernel firmware for hw drivers
%MAKEDEPENDS%
bc
cpio
%PROVIDES%
VIRTUALBOX-GUEST-MODULES
WIREGUARD-MODULE
%CONFLICTS%
linux-libre
%REPLACES%
virtualbox-guest-modules-arch
%GROUPS%
base
%LICENSE%
GPL2
"""
def build_db(tmp_path, repository: str, entries: dict[str, tuple[str, str]]) -> None:
"""Write a gzip-compressed tar archive mimicking a pacman sync DB."""
buffer = io.BytesIO()
with tarfile.open(fileobj=buffer, mode="w") as archive:
for directory, (desc, depends) in entries.items():
for filename, content in (
("desc", desc),
("depends", depends),
):
data = content.encode()
info = tarfile.TarInfo(name=f"{directory}/{filename}")
info.size = len(data)
archive.addfile(info, io.BytesIO(data))
(tmp_path / f"{repository}.db").write_bytes(gzip.compress(buffer.getvalue()))
def test_sync_db_paths_sorted_and_filtered(tmp_path):
build_db(tmp_path, "extra", {})
(tmp_path / "local").mkdir()
(tmp_path / "core.db.bak").write_text("not a db")
paths = sync_db_paths(tmp_path)
assert [path.name for path in paths] == ["extra.db"]
def test_sync_db_paths_missing_dir(tmp_path):
assert sync_db_paths(tmp_path / "does-not-exist") == []
def test_load_repo_packages_parses_all_fields(tmp_path):
build_db(tmp_path, "core", {"linux-6.16.8-1": (DESC, DEPENDS)})
packages, loaded = load_repo_packages(tmp_path)
assert loaded == ["core"]
(package,) = packages
assert package.name == "linux"
assert package.version == "6.16.8-1"
assert package.description == "The Linux kernel and modules"
assert package.repository == "core"
assert package.is_repo_package
assert not package.is_orphan
# Packager email is reduced to the username for @maintainer searches.
assert package.maintainer == "heftig"
assert package.url == "https://github.com/torvalds/linux"
assert package.last_modified == 1757429406
assert package.depends == ("coreutils", "initramfs", "kmod")
assert package.opt_depends == ("linux-firmware: kernel firmware for hw drivers",)
assert package.make_depends == ("bc", "cpio")
assert package.provides == ("VIRTUALBOX-GUEST-MODULES", "WIREGUARD-MODULE")
assert package.conflicts == ("linux-libre",)
assert package.replaces == ("virtualbox-guest-modules-arch",)
assert package.groups == ("base",)
assert package.licenses == ("GPL2",)
assert package.votes == 0 # AUR-only concept
assert package.aur_url == "https://aur.archlinux.org/packages/linux"
def test_load_repo_packages_multiple_repositories(tmp_path):
bash_desc = DESC.replace("linux", "bash").replace("6.16.8-1", "5.3-1")
build_db(tmp_path, "core", {"bash-5.3-1": (bash_desc, "")})
build_db(tmp_path, "extra", {"linux-6.16.8-1": (DESC, DEPENDS)})
packages, loaded = load_repo_packages(tmp_path)
assert loaded == ["core", "extra"]
assert len(packages) == 2
repos = {package.name: package.repository for package in packages}
assert repos == {"bash": "core", "linux": "extra"}
def test_corrupt_database_is_skipped(tmp_path):
build_db(tmp_path, "core", {"linux": (DESC, DEPENDS)})
(tmp_path / "broken.db").write_bytes(b"this is not a tar archive")
packages, loaded = load_repo_packages(tmp_path)
assert loaded == ["core"]
assert [package.name for package in packages] == ["linux"]
def test_entries_without_name_are_skipped(tmp_path):
build_db(tmp_path, "extra", {"broken-1.0-1": ("%VERSION%\n1.0-1\n", "")})
packages, loaded = load_repo_packages(tmp_path)
assert loaded == ["extra"]
assert packages == []
def test_packager_without_email_is_kept_verbatim(tmp_path):
desc = DESC.replace(
"Jan Alexander Steffens (heftig) <heftig@archlinux.org>", "Arch Linux"
)
build_db(tmp_path, "core", {"linux": (desc, "")})
packages, _ = load_repo_packages(tmp_path)
assert packages[0].maintainer == "Arch Linux"
def test_builddate_garbage_becomes_zero(tmp_path):
desc = DESC.replace("1757429406", "not-a-date")
build_db(tmp_path, "core", {"linux": (desc, "")})
packages, _ = load_repo_packages(tmp_path)
assert packages[0].last_modified == 0