Source code for tests.test_manager_guix

# Copyright Kevin Deldycke <[email protected]> and contributors.
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
"""GNU Guix output tests.

They replay what Guix printed on Guix System `aarch64-linux`: release `1.5.0`, and
master commit `5ef098e1` once `guix pull` ran. So they need neither `guix` nor a
Guix host.
"""

from __future__ import annotations

from pathlib import Path

import pytest

from meta_package_manager.managers.guix import Guix

LIST_INSTALLED = (
    "hello          \t2.12.2\tout\t/gnu/store/8qjzxdk26p8c5nyj98s3321vbkmv9za0-hello-2.12.2\n"  # noqa: E501
    "lua            \t5.1.5 \tout\t/gnu/store/sq2sj9gj8bqzgv493249xd8gzhhw1f0x-lua-5.1.5\n"  # noqa: E501
    "glib           \t2.83.3\tout\t/gnu/store/h95r1yvlbrlqap6l8fsdzp7lpxair7sv-glib-2.83.3\n"  # noqa: E501
    "glib           \t2.83.3\tbin\t/gnu/store/06w4p65r8hli2qnsdsnp0l8r1zghz5qr-glib-2.83.3-bin\n"  # noqa: E501
    "glib-networking\t2.78.1\tout\t/gnu/store/n4nicicydz8d24m2qi3ddwlcxlr534qn-glib-networking-2.78.1\n"
)
"""`guix package --list-installed`, with the `bin` output of `glib` installed."""

UPGRADE_REPORT = (
    "guix upgrade: warning: Consider running 'guix pull' followed by\n"
    "'guix package -u' to get up-to-date packages and security updates.\n"
    "\n"
    "The following package would be upgraded:\n"
    "   lua 5.1.5 → 5.4.8\n"
    "\n"
)
"""What `guix upgrade --dry-run` writes to `<stderr>`, with `<stdout>` empty."""

PULLED_UPGRADE_REPORT = (
    "The following packages would be upgraded:\n"
    "   glib            2.83.3 → 2.86.0\n"
    "   glib-networking 2.78.1 → 2.80.1\n"
    "   glib:bin        2.83.3 → 2.86.0\n"
    "   hello           2.12.2 → 2.12.3\n"
    "   lua             5.1.5 → 5.5.0\n"
    "\n"
    "22.6 MB would be downloaded\n"
)
"""The same report once `guix pull` ran: padded names, and one row per output."""

SEARCH_OUTPUT = (
    "name: cowsay\n"
    "version: 3.8.4\n"
    "outputs:\n"
    "+ out: everything\n"
    "systems: x86_64-linux mips64el-linux aarch64-linux powerpc64le-linux\n"
    "+ i686-linux armhf-linux powerpc-linux\n"
    "dependencies: [email protected]\n"
    "location: gnu/packages/games.scm:1431:2\n"
    "homepage: https://web.archive.org/web/20071026043648/http://www.nog.net:80/~tony/warez/cowsay.shtml\n"
    "license: GPL 3+\n"
    "synopsis: Speaking cow text filter  \n"
    "description: Cowsay is basically a text filter.  Send some text into it, and\n"
    "+ you get a cow saying your text.  If you think a talking cow isn't enough, cows\n"
    "+ can think too: all you have to do is run `cowthink'.  If you're tired of cows,\n"
    "+ a variety of other ASCII-art messengers are available.\n"
    "relevance: 32\n"
    "\n"
    "name: python-snakesay\n"
    "version: 0.10.4\n"
    "outputs:\n"
    "+ out: everything\n"
    "systems: x86_64-linux mips64el-linux aarch64-linux powerpc64le-linux\n"
    "+ i686-linux armhf-linux powerpc-linux\n"
    "dependencies: [email protected] [email protected]\n"
    "location: gnu/packages/python-xyz.scm:2293:2\n"
    "homepage: https://github.com/pythonanywhere/snakesay\n"
    "license: Expat\n"
    "synopsis: Like `cowsay' but with Python flavor  \n"
    "description: This package provides a simple ASCII art pictures generator of a\n"
    "+ Snake with a message.\n"
    "relevance: 3\n"
    "\n"
)
"""`guix search cowsay`, whose synopses end with two spaces."""

SEARCH_GTK_OUTPUT = (
    "name: gtk+\n"
    "version: 3.24.51\n"
    "outputs:\n"
    "+ bin: executable programs and scripts\n"
    "+ out: everything else\n"
    "systems: x86_64-linux aarch64-linux\n"
    "dependencies: [email protected] [email protected] [email protected]\n"
    "+ [email protected] [email protected] [email protected]\n"
    "+ [email protected] [email protected] [email protected]\n"
    "+ [email protected] [email protected] [email protected]\n"
    "+ [email protected] [email protected] [email protected] [email protected]\n"
    "+ [email protected] [email protected] [email protected]\n"
    "+ [email protected] [email protected] [email protected] [email protected]\n"
    "+ [email protected] [email protected] [email protected] [email protected] [email protected]\n"
    "+ [email protected] [email protected] [email protected] [email protected]\n"
    "+ [email protected] [email protected] [email protected] [email protected]\n"
    "+ [email protected] [email protected] [email protected] [email protected]\n"
    "+ [email protected] [email protected]\n"
    "location: gnu/packages/gtk.scm:1010:2\n"
    "homepage: https://www.gtk.org/\n"
    "license: LGPL 2.0+\n"
    "synopsis: Cross-platform toolkit for creating graphical user interfaces  \n"
    "description: GTK+, or the GIMP Toolkit, is a multi-platform toolkit for\n"
    "+ creating graphical user interfaces.  Offering a complete set of widgets, GTK+\n"
    "+ is suitable for projects ranging from small one-off tools to complete\n"
    "+ application suites.\n"
    "relevance: 30\n"
    "\n"
    "name: gtk+\n"
    "version: 2.24.33\n"
    "outputs:\n"
    "+ bin: executable programs and scripts\n"
    "+ doc: documentation\n"
    "+ debug: debug information\n"
    "+ out: everything else\n"
    "systems: x86_64-linux aarch64-linux\n"
    "dependencies: [email protected] [email protected] [email protected]\n"
    "+ [email protected] [email protected] [email protected]\n"
    "+ [email protected] [email protected] [email protected] [email protected]\n"
    "+ [email protected] [email protected] [email protected] [email protected] [email protected]\n"
    "+ [email protected] [email protected] [email protected] [email protected]\n"
    "+ [email protected] [email protected] [email protected] [email protected]\n"
    "+ [email protected]\n"
    "location: gnu/packages/gtk.scm:907:2\n"
    "homepage: https://www.gtk.org/\n"
    "license: LGPL 2.0+\n"
    "synopsis: Cross-platform toolkit for creating graphical user interfaces  \n"
    "description: GTK+, or the GIMP Toolkit, is a multi-platform toolkit for\n"
    "+ creating graphical user interfaces.  Offering a complete set of widgets, GTK+\n"
    "+ is suitable for projects ranging from small one-off tools to complete\n"
    "+ application suites.\n"
    "relevance: 30\n"
    "\n"
)
"""`guix search ^gtk\\+$`: two versions under one name, with different outputs."""


[docs] @pytest.fixture def guix(monkeypatch): manager = Guix() monkeypatch.setattr(manager, "cli_errors", []) monkeypatch.setattr(manager, "cli_path", Path("/usr/bin/guix"), raising=False) return manager
[docs] def test_installed_strips_padding_and_names_outputs(guix, stub_run_cli): stub_run_cli(guix, LIST_INSTALLED) assert [ (package.id, str(package.installed_version)) for package in guix.installed ] == [ ("hello", "2.12.2"), ("lua", "5.1.5"), ("glib", "2.83.3"), ("glib:bin", "2.83.3"), ("glib-networking", "2.78.1"), ]
[docs] @pytest.mark.parametrize( ("report", "expected"), ( pytest.param(UPGRADE_REPORT, [("lua", "5.1.5", "5.4.8")], id="one_row"), pytest.param( PULLED_UPGRADE_REPORT, [ ("glib", "2.83.3", "2.86.0"), ("glib-networking", "2.78.1", "2.80.1"), ("glib:bin", "2.83.3", "2.86.0"), ("hello", "2.12.2", "2.12.3"), ("lua", "5.1.5", "5.5.0"), ], id="padded_rows", ), ), ) def test_outdated_reads_the_report_from_stderr(guix, monkeypatch, report, expected): monkeypatch.setattr(guix, "_spawn", lambda *args, **kwargs: (0, "", report)) assert [ (package.id, str(package.installed_version), str(package.latest_version)) for package in guix.outdated ] == expected
[docs] def test_search_strips_synopsis_padding(guix, stub_run_cli): stub_run_cli(guix, SEARCH_OUTPUT) assert [ (package.id, str(package.latest_version), package.description) for package in guix.search("cowsay", extended=False, exact=False) ] == [ ("cowsay", "3.8.4", "Speaking cow text filter"), ("python-snakesay", "0.10.4", "Like `cowsay' but with Python flavor"), ]
[docs] @pytest.mark.parametrize( ("query", "expected"), ( pytest.param(r"^gtk\+$", [("gtk+", "3.24.51")], id="newest_version"), pytest.param("gtk+:bin", [("gtk+:bin", "3.24.51")], id="output"), pytest.param("gtk+:doc", [("gtk+:doc", "2.24.33")], id="older_output"), pytest.param("gtk+:apricot", [], id="missing_output"), ), ) def test_search_reports_a_name_once(guix, stub_run_cli, query, expected): """`mpm install` fails when its exact search returns more than one package.""" stub_run_cli(guix, SEARCH_GTK_OUTPUT) assert [ (package.id, str(package.latest_version)) for package in guix.search(query, extended=False, exact=False) ] == expected
[docs] def test_search_for_an_output_matches_the_name_alone(guix, monkeypatch): calls = [] def record(*args, **kwargs): calls.append(args) return SEARCH_GTK_OUTPUT monkeypatch.setattr(guix, "run_cli", record) list(guix.search("gtk+:bin", extended=False, exact=False)) assert calls == [("search", r"^gtk\+$")]
[docs] @pytest.mark.parametrize( ("package_id", "regexp"), ( pytest.param("lua", "^lua$", id="anchored"), pytest.param("glib:bin", "^glib$", id="output_dropped"), pytest.param("gtk+", r"^gtk\+$", id="plus_escaped"), pytest.param("python-ruamel.yaml", r"^python-ruamel\.yaml$", id="dot_escaped"), ), ) def test_upgrade_one_matches_the_name_alone(guix, package_id, regexp): """`guix upgrade glib` would also upgrade `glib-networking`.""" assert guix.upgrade_one_cli(package_id)[1:] == ("upgrade", regexp)