"""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) %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) ", "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