Files
linux-image-manager/tests/unit/test_image_setup.py
Kevin Veen-Birkenbach a91100fc0e chore(session): harden chroot package installs (PATH + apt-get update)
- chroot_bash exports a Debian-safe PATH so /usr/sbin tools (update-initramfs,
  useradd, chpasswd, ...) resolve inside the chroot instead of failing with
  code 127.
- install_packages runs apt-get update before install (a stock image ships
  stale lists whose superseded .deb URLs 404) and non-interactive
  apt-get install -y; pacman gains -Sy for the same index-refresh reason.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-24 17:57:28 +02:00

147 lines
5.4 KiB
Python

import pytest
from lim.errors import LimError
from lim.image import choosers, raspberry, transfer
from lim.image.plan import ImagePlan
from lim.image.session import install_packages
@pytest.fixture
def plan():
return ImagePlan()
class TestDistributionChoosers:
def test_arch_rpi4_uses_aarch64_and_high_memory_cost(self, plan, answers):
answers("4")
choosers.choose_arch(plan)
assert plan.image_name == "ArchLinuxARM-rpi-aarch64-latest.tar.gz"
assert plan.luks_memory_cost == "256000"
assert plan.raspberry_pi_version == "4"
assert plan.download_url == (
"http://os.archlinuxarm.org/os/ArchLinuxARM-rpi-aarch64-latest.tar.gz"
)
def test_arch_rpi1_uses_armv7_and_low_memory_cost(self, plan, answers):
answers("1")
choosers.choose_arch(plan)
assert plan.image_name == "ArchLinuxARM-rpi-armv7-latest.tar.gz"
assert plan.luks_memory_cost == "64000"
def test_arch_unknown_version_raises(self, plan, answers):
answers("99")
with pytest.raises(LimError):
choosers.choose_arch(plan)
def test_manjaro_gnome_25(self, plan, answers):
answers("gnome", "25")
choosers.choose_manjaro(plan)
assert plan.image_name == "manjaro-gnome-25.0.10-251013-linux612.iso"
assert plan.base_download_url == "https://download.manjaro.org/gnome/25.0.10/"
assert plan.image_checksum is None
def test_manjaro_raspberrypi_release_sets_rpi_version(self, plan, answers):
answers("gnome", "raspberrypi")
choosers.choose_manjaro(plan)
assert plan.raspberry_pi_version == "4"
assert plan.luks_memory_cost == "256000"
assert plan.image_name == "Manjaro-ARM-gnome-rpi4-23.02.img.xz"
def test_manjaro_unknown_flavour_raises(self, plan, answers):
answers("kde")
with pytest.raises(LimError):
choosers.choose_manjaro(plan)
def test_retropie_rpi3_shares_rpi2_image(self, plan, answers):
answers("3")
choosers.choose_retropie(plan)
assert plan.image_name == "retropie-buster-4.8-rpi2_3_zero2w.img.gz"
assert plan.image_checksum == "224e64d8820fc64046ba3850f481c87e"
def test_unknown_distribution_raises(self, plan, answers):
answers("gentoo")
with pytest.raises(LimError):
choosers.choose_linux_image(plan)
class TestPartitionInput:
def test_contains_boot_size_and_writes_table(self):
script = transfer.arch_partition_input("+500M")
assert script.startswith("o\n")
assert "\n+500M\n" in script
assert script.endswith("w\n")
class TestDecompressCommand:
@pytest.mark.parametrize(
("name", "expected"),
[
("image.zip", ["unzip", "-p"]),
("image.img.gz", ["gunzip", "-c"]),
("image.iso", ["pv"]),
("image.img.xz", ["unxz", "-c"]),
],
)
def test_known_formats(self, tmp_path, name, expected):
path = tmp_path / name
command = transfer.decompress_command(path)
assert command[: len(expected)] == expected
assert command[-1] == str(path)
def test_unknown_format_raises(self, tmp_path):
with pytest.raises(LimError):
transfer.decompress_command(tmp_path / "image.rar")
class TestInstallPackages:
def test_pacman_for_arch(self, tmp_path, fake_runner):
install_packages("arch", tmp_path, "btrfs-progs")
chroot_calls = [
input_text
for kind, cmd, input_text in fake_runner.calls
if kind == "run" and cmd[0] == "chroot"
]
assert len(chroot_calls) == 1
assert "pacman --noconfirm -Sy --needed btrfs-progs" in chroot_calls[0]
def test_apt_for_retropie(self, tmp_path, fake_runner):
install_packages("retropie", tmp_path, "btrfs-progs")
chroot_calls = [
input_text
for kind, cmd, input_text in fake_runner.calls
if kind == "run" and cmd[0] == "chroot"
]
assert len(chroot_calls) == 1
assert "apt-get update" in chroot_calls[0]
assert "apt-get install -y btrfs-progs" in chroot_calls[0]
def test_unsupported_distribution_raises(self, tmp_path, fake_runner):
with pytest.raises(LimError):
install_packages("gentoo", tmp_path, "btrfs-progs")
class TestConfigureHelpers:
def test_configure_sudoers(self, tmp_path):
raspberry.configure_sudoers(tmp_path, "administrator")
sudoers = tmp_path / "etc/sudoers.d/administrator"
assert sudoers.read_text() == "administrator ALL=(ALL:ALL) ALL\n"
assert (sudoers.stat().st_mode & 0o777) == 0o440
def test_configure_ssh_key(self, tmp_path):
public_key = tmp_path / "id_rsa.pub"
public_key.write_text("ssh-rsa AAAA test@host\n")
ssh_folder = tmp_path / "root/home/user/.ssh"
authorized_keys = ssh_folder / "authorized_keys"
raspberry.configure_ssh_key(str(public_key), ssh_folder, authorized_keys)
assert authorized_keys.read_text() == "ssh-rsa AAAA test@host\n"
assert (ssh_folder.stat().st_mode & 0o777) == 0o700
assert (authorized_keys.stat().st_mode & 0o777) == 0o600
def test_configure_ssh_key_missing_source_raises(self, tmp_path):
with pytest.raises(LimError):
raspberry.configure_ssh_key(
str(tmp_path / "missing.pub"),
tmp_path / ".ssh",
tmp_path / ".ssh/authorized_keys",
)