lib.distros.Distro.install_*(): Add install_deps
The install methods of Distro inconsistently resolve dependencies or don't depending on the descendant's implementation. Pin that more unambigously by adding a new parameter install_deps, defaulting to True, to the following methods of lib.Distro: _install_local_files() _install_urls() _install_urls_and_names() install() The implementations in lib.distros.* make use of the new lib.pm.*.install_packages() method introduced by the previous commit. Add a unit test directory per Distro descendant. Assisted-by: unsloth/Qwen3.8-27B-GGUF:Q4_K_M with pi.dev v1.4.0 Signed-off-by: Jan Lindemann <jan@janware.com>
This commit is contained in:
parent
36978c55e2
commit
c5ad946d6e
2 changed files with 522 additions and 14 deletions
7
test/unit/python/jw/pkg/lib/distros/suse/Makefile
Normal file
7
test/unit/python/jw/pkg/lib/distros/suse/Makefile
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
TOPDIR = ../../../../../../../..
|
||||
|
||||
include $(TOPDIR)/make/proj.mk
|
||||
include $(JWBDIR)/make/py-run.mk
|
||||
|
||||
all:
|
||||
test: run
|
||||
134
test/unit/python/jw/pkg/lib/distros/suse/test.py
Normal file
134
test/unit/python/jw/pkg/lib/distros/suse/test.py
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
|
||||
from typing import override
|
||||
|
||||
from jw.pkg.lib.distros.suse.Distro import Distro as SuseDistro
|
||||
from jw.pkg.lib.ec.Local import Local
|
||||
from jw.pkg.lib.Result import Result
|
||||
|
||||
class DispatchLocal(Local):
|
||||
"""A canned execution context that answers rpm queries"""
|
||||
|
||||
def __init__(self, files: dict[str, str], installed: dict[str, str]) -> None:
|
||||
super().__init__('local')
|
||||
self.files = files
|
||||
self.installed = installed
|
||||
self.cmds: list[list[str]] = []
|
||||
|
||||
@override
|
||||
async def _run(
|
||||
self,
|
||||
cmd: list[str],
|
||||
wd: str | None,
|
||||
verbose: bool,
|
||||
cmd_input: bytes | None,
|
||||
mod_env: dict[str, str] | None,
|
||||
interactive: bool,
|
||||
log_prefix: str,
|
||||
) -> Result:
|
||||
self.cmds.append(cmd)
|
||||
if '-qp' in cmd:
|
||||
return Result(stdout = self.files.get(cmd[-1], '').encode(), status = 0)
|
||||
if '-q' in cmd:
|
||||
name = cmd[-1]
|
||||
return Result(
|
||||
stdout = self.installed.get(name, '').encode(),
|
||||
status = 0 if name in self.installed else 1,
|
||||
)
|
||||
return Result(stdout = b'', status = 0)
|
||||
|
||||
def rpm_args(cmd: list[str]) -> list[str]:
|
||||
"""The rpm command without the sudo prefix and its options"""
|
||||
return cmd[cmd.index('/usr/bin/rpm'):]
|
||||
|
||||
# -- A mixed transaction runs two installs, the upgrades first: the
|
||||
# distro installs local files with force, which keeps the reinstall
|
||||
# semantics for already-installed versions
|
||||
cl = DispatchLocal(
|
||||
files = {
|
||||
'/a/jw-base-run-1.0.0-42.x86_64.rpm': 'jw-base\t1.0.0-42',
|
||||
'/a/jw-base-run-1.0.0-41.x86_64.rpm': 'jw-base\t1.0.0-41',
|
||||
},
|
||||
installed = {'jw-base': 'jw-base|||||1.0.0-42\n'},
|
||||
)
|
||||
d = SuseDistro(cl, id = 'suse')
|
||||
asyncio.run(
|
||||
d._install_local_files(
|
||||
['/a/jw-base-run-1.0.0-42.x86_64.rpm', '/a/jw-base-run-1.0.0-41.x86_64.rpm'],
|
||||
False,
|
||||
install_deps = False,
|
||||
)
|
||||
)
|
||||
installs = [rpm_args(cmd) for cmd in cl.cmds if '-U' in cmd]
|
||||
assert installs == [
|
||||
['/usr/bin/rpm', '-U', '/a/jw-base-run-1.0.0-41.x86_64.rpm'],
|
||||
[
|
||||
'/usr/bin/rpm',
|
||||
'-U',
|
||||
'--reinstall',
|
||||
'/a/jw-base-run-1.0.0-42.x86_64.rpm',
|
||||
],
|
||||
]
|
||||
|
||||
# -- A single file whose version is already installed is reinstalled
|
||||
cl = DispatchLocal(
|
||||
files = {'/a/jw-base-run-1.0.0-42.x86_64.rpm': 'jw-base\t1.0.0-42'},
|
||||
installed = {'jw-base': 'jw-base|||||1.0.0-42\n'},
|
||||
)
|
||||
d = SuseDistro(cl, id = 'suse')
|
||||
asyncio.run(
|
||||
d._install_local_files(
|
||||
['/a/jw-base-run-1.0.0-42.x86_64.rpm'], False, install_deps = False
|
||||
)
|
||||
)
|
||||
assert rpm_args(cl.cmds[-1]) == [
|
||||
'/usr/bin/rpm',
|
||||
'-U',
|
||||
'--reinstall',
|
||||
'/a/jw-base-run-1.0.0-42.x86_64.rpm',
|
||||
]
|
||||
|
||||
# -- only_update raises on files whose package is not installed
|
||||
cl = DispatchLocal(
|
||||
files = {
|
||||
'/a/jw-base-run-1.0.0-42.x86_64.rpm': 'jw-base\t1.0.0-42',
|
||||
'/a/jw-foo-run-1.0.0-42.x86_64.rpm': 'jw-foo\t1.0.0-42',
|
||||
},
|
||||
installed = {'jw-base': 'jw-base|||||1.0.0-42\n'},
|
||||
)
|
||||
d = SuseDistro(cl, id = 'suse')
|
||||
try:
|
||||
asyncio.run(
|
||||
d._install_local_files(
|
||||
['/a/jw-base-run-1.0.0-42.x86_64.rpm', '/a/jw-foo-run-1.0.0-42.x86_64.rpm'],
|
||||
True,
|
||||
install_deps = False,
|
||||
)
|
||||
)
|
||||
except Exception as e:
|
||||
assert '/a/jw-foo-run-1.0.0-42.x86_64.rpm' in str(e)
|
||||
else:
|
||||
raise AssertionError('expected an exception')
|
||||
assert not [cmd for cmd in cl.cmds if '-U' in cmd]
|
||||
|
||||
# -- deps routes local files through the package manager
|
||||
cl = DispatchLocal(
|
||||
files = {'/a/jw-base-run-1.0.0-42.x86_64.rpm': 'jw-base\t1.0.0-42'},
|
||||
installed = {'jw-base': 'jw-base|||||1.0.0-42\n'},
|
||||
)
|
||||
d = SuseDistro(cl, id = 'suse')
|
||||
asyncio.run(
|
||||
d._install_local_files(
|
||||
['/a/jw-base-run-1.0.0-42.x86_64.rpm'], False, install_deps = True
|
||||
)
|
||||
)
|
||||
pm_cmds = [cmd for cmd in cl.cmds if '/usr/bin/zypper' in cmd]
|
||||
assert len(pm_cmds) == 1
|
||||
args = pm_cmds[0][pm_cmds[0].index('/usr/bin/zypper'):]
|
||||
assert 'install' in args
|
||||
assert args[-1] == '/a/jw-base-run-1.0.0-42.x86_64.rpm'
|
||||
assert not [cmd for cmd in cl.cmds if '-U' in cmd]
|
||||
|
||||
print('All suse distro tests passed')
|
||||
Loading…
Reference in a new issue