File: test_mixin__verify_system_packages.py

package info (click to toggle)
python-briefcase 0.3.25-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 7,596 kB
  • sloc: python: 62,519; makefile: 60
file content (189 lines) | stat: -rw-r--r-- 6,842 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
import subprocess
from unittest.mock import MagicMock, call

import pytest

from briefcase.exceptions import BriefcaseCommandError
from briefcase.platforms.linux.system import LinuxSystemBuildCommand


@pytest.fixture
def build_command(dummy_console, tmp_path, first_app):
    command = LinuxSystemBuildCommand(
        console=dummy_console,
        base_path=tmp_path / "base_path",
        data_path=tmp_path / "briefcase",
        apps={"first": first_app},
    )
    command.tools.host_os = "Linux"
    command.tools.host_arch = "wonky"

    # All calls to `shutil.which()` succeed
    command.tools.shutil.which = MagicMock(return_value="/path/to/exe")

    # Mock subprocess
    command.tools.subprocess = MagicMock()

    return command


def test_deb_requirements(build_command, first_app_config):
    """Debian requirements can be verified."""
    first_app_config.target_vendor_base = "debian"

    build_command.verify_system_packages(first_app_config)

    # The packages were verified
    assert build_command.tools.subprocess.check_output.mock_calls == [
        call(["dpkg", "-s", "python3-dev"], quiet=1),
        call(["dpkg", "-s", "dpkg-dev"], quiet=1),
        call(["dpkg", "-s", "g++"], quiet=1),
        call(["dpkg", "-s", "gcc"], quiet=1),
        call(["dpkg", "-s", "libc6-dev"], quiet=1),
        call(["dpkg", "-s", "make"], quiet=1),
    ]


def test_rpm_requirements(build_command, first_app_config):
    """RHEL requirements can be verified."""
    first_app_config.target_vendor_base = "rhel"

    build_command.verify_system_packages(first_app_config)

    assert build_command.tools.subprocess.check_output.mock_calls == [
        call(["rpm", "-q", "python3-devel"], quiet=1),
        call(["rpm", "-q", "gcc"], quiet=1),
        call(["rpm", "-q", "make"], quiet=1),
        call(["rpm", "-q", "pkgconf-pkg-config"], quiet=1),
    ]


def test_suse_requirements(build_command, first_app_config):
    """SUSE requirements can be verified."""
    first_app_config.target_vendor_base = "suse"

    build_command.verify_system_packages(first_app_config)

    assert build_command.tools.subprocess.check_output.mock_calls == [
        call(["rpm", "-q", "--whatprovides", "python3-devel"], quiet=1),
        call(
            ["rpm", "-q", "--whatprovides", "patterns-devel-base-devel_basis"], quiet=1
        ),
    ]


def test_arch_requirements(build_command, first_app_config, capsys):
    """Arch requirements can be verified."""
    first_app_config.target_vendor_base = "arch"

    build_command.verify_system_packages(first_app_config)

    assert build_command.tools.subprocess.check_output.mock_calls == [
        call(["pacman", "-Q", "python3"], quiet=1),
        call(["pacman", "-Q", "base-devel"], quiet=1),
    ]


def test_unknown_requirements(build_command, first_app_config, capsys):
    """An unknown system can't be verified."""
    first_app_config.target_vendor_base = "somevendor"

    build_command.verify_system_packages(first_app_config)

    # No packages verified
    build_command.tools.subprocess.check_output.assert_not_called()

    # A warning was logged.
    output = capsys.readouterr().out
    assert "WARNING: Can't verify system packages" in output


def test_missing_packages(build_command, first_app_config, capsys):
    """If there are missing system packages, an error is raised."""
    # Mock the system requirement tools; there's a base requirement of packages called
    # "compiler" and "compiler++", plus 3 packages provided by an installation alias
    # "alias". These packages are verified using "check <pkg>", and installed using
    # "system install_flag <pkg>"
    build_command._system_requirement_tools = MagicMock(
        return_value=(
            [
                "compiler",
                "compiler++",
                # Three packages provided by the `alias` alias
                ("aliased-1", "alias"),
                ("aliased-2", "alias"),
                ("aliased-3", "alias"),
            ],
            ["check"],
            ["system", "install_flag"],
        )
    )

    # Add some system requirements.
    first_app_config.system_requires = ["first", "second", "third"]

    # Mock the side effect of checking those requirements.
    build_command.tools.subprocess.check_output.side_effect = [
        subprocess.CalledProcessError(cmd="check", returncode=1),  # compiler
        "installed",  # compiler++
        subprocess.CalledProcessError(cmd="check", returncode=1),  # aliased-1
        "installed",  # aliased-2
        subprocess.CalledProcessError(cmd="check", returncode=1),  # aliased-3
        "installed",  # first
        subprocess.CalledProcessError(cmd="check", returncode=1),  # second
        "installed",  # third
    ]

    # Verify the requirements. This will raise an error, but the error
    # message will tell you how to install the system packages. This includes
    # using an alias for the install of aliased-1 and aliased-3.
    with pytest.raises(
        BriefcaseCommandError,
        match=r"    sudo system install_flag alias compiler second",
    ):
        build_command.verify_system_packages(first_app_config)


def test_missing_system_verify(build_command, first_app_config, capsys):
    """If the program to verify system packages doesn't exist, a warning is logged."""
    # Mock the system verifier is missing
    build_command.tools.shutil.which = MagicMock(return_value="")

    build_command.verify_system_packages(first_app_config)

    # No packages verified
    build_command.tools.subprocess.check_output.assert_not_called()

    # A warning was logged.
    output = capsys.readouterr().out
    assert "WARNING: Can't verify system packages" in output


def test_packages_installed(build_command, first_app_config, capsys):
    """If all required packages are installed, no error is raised."""
    # Mock the system requirement tools; there's a base requirement of
    # a packaged called "compiler", verified using "check <pkg>", and
    # installed using "system <pkg>"
    build_command._system_requirement_tools = MagicMock(
        return_value=(
            ["compiler"],
            ["check"],
            ["system", "install_flag"],
        )
    )

    # Add some system requirements.
    first_app_config.system_requires = ["first", "second", "third"]

    # Mock the effect of checking requirements that are all present
    build_command.tools.subprocess.check_output.return_value = "installed"

    # Verify the requirements. This will raise an error.
    build_command.verify_system_packages(first_app_config)

    assert build_command.tools.subprocess.check_output.mock_calls == [
        call(["check", "compiler"], quiet=1),
        call(["check", "first"], quiet=1),
        call(["check", "second"], quiet=1),
        call(["check", "third"], quiet=1),
    ]