forked from Mirror/pmbootstrap
test: add pytest and test config load/migrate (MR 2252)
re-introduce pytest, add a conftest.py with some useful fixtures and basic tests for config loading. This just checks that we can load the config and migrate it from the old 2.3.x format to the new 3.0 format with the new mirrors section. Testing anything that requires args or Context should probably wait until we can properly model state (since global state like in get_context() really doesn't jive with pytest). Signed-off-by: Caleb Connolly <caleb@postmarketos.org>
This commit is contained in:
parent
0db01a2919
commit
ff86792fb6
4 changed files with 207 additions and 0 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -9,6 +9,9 @@
|
||||||
*.rej
|
*.rej
|
||||||
*.orig
|
*.orig
|
||||||
|
|
||||||
|
# Pytest tmp dir
|
||||||
|
.pytest_tmp
|
||||||
|
|
||||||
# Byte-compiled / optimized / DLL files
|
# Byte-compiled / optimized / DLL files
|
||||||
__pycache__/
|
__pycache__/
|
||||||
*.py[cod]
|
*.py[cod]
|
||||||
|
|
94
pmb/config/test_config_serde.py
Normal file
94
pmb/config/test_config_serde.py
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
from pathlib import Path
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
import pmb.config
|
||||||
|
from pmb.core.config import SystemdConfig
|
||||||
|
|
||||||
|
"""Test the config file serialization and deserialization."""
|
||||||
|
|
||||||
|
def test_load(config_file):
|
||||||
|
config = pmb.config.load(config_file)
|
||||||
|
assert config.build_default_device_arch
|
||||||
|
assert config.ccache_size == "5G"
|
||||||
|
assert config.device == "qemu-amd64"
|
||||||
|
assert config.extra_packages == "neofetch,neovim,reboot-mode"
|
||||||
|
assert config.hostname == "qemu-amd64"
|
||||||
|
assert not config.is_default_channel
|
||||||
|
assert config.jobs == "8"
|
||||||
|
assert config.kernel == "edge"
|
||||||
|
assert config.locale == "C.UTF-8"
|
||||||
|
assert config.ssh_keys
|
||||||
|
assert config.sudo_timer
|
||||||
|
assert config.systemd == SystemdConfig.ALWAYS
|
||||||
|
assert config.timezone == "Europe/Berlin"
|
||||||
|
assert config.ui == "gnome"
|
||||||
|
assert config.providers == {}
|
||||||
|
assert config.mirrors["pmaports"] is not None
|
||||||
|
assert ".pytest_tmp" in config.work.parts
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def config_file_2_3_x(tmp_path: Path):
|
||||||
|
"""Fixture to create a temporary pmbootstrap.cfg file with 2.3.x format."""
|
||||||
|
file = tmp_path / "pmbootstrap.cfg"
|
||||||
|
contents = """[pmbootstrap]
|
||||||
|
aports = /home/user/.local/var/pmbootstrap/cache_git/pmaports
|
||||||
|
ccache_size = 32G
|
||||||
|
is_default_channel = False
|
||||||
|
device = oneplus-fajita
|
||||||
|
extra_packages = none
|
||||||
|
hostname = pmos
|
||||||
|
build_pkgs_on_install = True
|
||||||
|
jobs = 32
|
||||||
|
kernel = edge
|
||||||
|
keymap =
|
||||||
|
locale = C.UTF-8
|
||||||
|
nonfree_firmware = True
|
||||||
|
nonfree_userland = False
|
||||||
|
ssh_keys = True
|
||||||
|
timezone = Europe/London
|
||||||
|
ui = gnome-mobile
|
||||||
|
ui_extras = False
|
||||||
|
user = user
|
||||||
|
work = /home/user/.local/var/pmbootstrap
|
||||||
|
boot_size = 256
|
||||||
|
extra_space = 0
|
||||||
|
sudo_timer = True
|
||||||
|
mirrors_postmarketos = http://mirror.postmarketos.org/postmarketos/
|
||||||
|
mirror_alpine = http://dl-cdn.alpinelinux.org/alpine/
|
||||||
|
ssh_key_glob = ~/.ssh/id_*.pub
|
||||||
|
qemu_redir_stdio = True
|
||||||
|
build_default_device_arch = True
|
||||||
|
merge_usr = True
|
||||||
|
auto_checksum = True
|
||||||
|
systemd = always
|
||||||
|
|
||||||
|
[providers]
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
open(file, "w").write(contents)
|
||||||
|
return file
|
||||||
|
|
||||||
|
|
||||||
|
def test_migrate_2_to_3(config_file_2_3_x, tmp_path, monkeypatch):
|
||||||
|
tmp_path = tmp_path / "pmbootstrap-new.cfg"
|
||||||
|
|
||||||
|
did_migrate = False
|
||||||
|
def mock_save(path, config):
|
||||||
|
nonlocal did_migrate
|
||||||
|
did_migrate = True
|
||||||
|
|
||||||
|
monkeypatch.setattr(pmb.config.file, "save", mock_save)
|
||||||
|
|
||||||
|
config = pmb.config.load(config_file_2_3_x)
|
||||||
|
|
||||||
|
# The 2.3.x to 3.0 migration removes these keys from the
|
||||||
|
# config in favour of a new [mirrors] section.
|
||||||
|
# It should be automatically migrated.
|
||||||
|
assert not hasattr(config, "mirror_alpine")
|
||||||
|
assert not hasattr(config, "mirrors_postmarketos")
|
||||||
|
|
||||||
|
# Check that save was called (which happens on a config migration)
|
||||||
|
assert did_migrate
|
||||||
|
|
103
pmb/conftest.py
Normal file
103
pmb/conftest.py
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
import pytest
|
||||||
|
from contextlib import contextmanager
|
||||||
|
|
||||||
|
@contextmanager
|
||||||
|
def _fixture_context(val):
|
||||||
|
yield val
|
||||||
|
|
||||||
|
@pytest.fixture(scope="session")
|
||||||
|
def config_file_session(tmp_path_factory):
|
||||||
|
"""Fixture to create a temporary pmbootstrap.cfg file."""
|
||||||
|
tmp_path = tmp_path_factory.mktemp("pmbootstrap")
|
||||||
|
file = tmp_path / "pmbootstrap.cfg"
|
||||||
|
workdir = tmp_path / "work"
|
||||||
|
workdir.mkdir()
|
||||||
|
contents = """[pmbootstrap]
|
||||||
|
build_default_device_arch = True
|
||||||
|
ccache_size = 5G
|
||||||
|
device = qemu-amd64
|
||||||
|
extra_packages = neofetch,neovim,reboot-mode
|
||||||
|
hostname = qemu-amd64
|
||||||
|
is_default_channel = False
|
||||||
|
jobs = 8
|
||||||
|
kernel = edge
|
||||||
|
locale = C.UTF-8
|
||||||
|
ssh_keys = True
|
||||||
|
sudo_timer = True
|
||||||
|
systemd = always
|
||||||
|
timezone = Europe/Berlin
|
||||||
|
ui = gnome
|
||||||
|
work = {0}
|
||||||
|
|
||||||
|
[providers]
|
||||||
|
|
||||||
|
[mirrors]
|
||||||
|
""".format(workdir)
|
||||||
|
|
||||||
|
open(file, "w").write(contents)
|
||||||
|
return file
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def config_file(config_file_session):
|
||||||
|
"""Fixture to create a temporary pmbootstrap.cfg file."""
|
||||||
|
with _fixture_context(config_file_session) as val:
|
||||||
|
yield val
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(autouse=True)
|
||||||
|
def setup_logging(tmp_path: Path):
|
||||||
|
"""Setup logging for all tests."""
|
||||||
|
import logging
|
||||||
|
logfile = tmp_path / "test.log"
|
||||||
|
logging.basicConfig(level=logging.DEBUG, force=True, filename=logfile)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(autouse=True)
|
||||||
|
def setup_mock_ask(monkeypatch):
|
||||||
|
"""Common setup to mock cli.ask() to avoid reading from stdin"""
|
||||||
|
import pmb.helpers.cli
|
||||||
|
|
||||||
|
def mock_ask(question="Continue?", choices=["y", "n"], default="n",
|
||||||
|
lowercase_answer=True, validation_regex=None, complete=None):
|
||||||
|
return default
|
||||||
|
|
||||||
|
monkeypatch.setattr(pmb.helpers.cli, "ask", mock_ask)
|
||||||
|
|
||||||
|
|
||||||
|
# FIXME: get_context() at runtime somehow doesn't return the
|
||||||
|
# custom context we set up here.
|
||||||
|
# @pytest.fixture(scope="session")
|
||||||
|
# def pmb_args(config_file_session):
|
||||||
|
# """This is (still) a hack, since a bunch of the codebase still
|
||||||
|
# expects some global state to be initialised. We do that here."""
|
||||||
|
|
||||||
|
# from pmb.types import PmbArgs
|
||||||
|
# from pmb.helpers.args import init as init_args
|
||||||
|
|
||||||
|
# args = PmbArgs()
|
||||||
|
# args.config = config_file_session
|
||||||
|
# args.aports = None
|
||||||
|
# args.timeout = 900
|
||||||
|
# args.details_to_stdout = False
|
||||||
|
# args.quiet = False
|
||||||
|
# args.verbose = False
|
||||||
|
# args.offline = False
|
||||||
|
# args.action = "init"
|
||||||
|
# args.cross = False
|
||||||
|
# args.log = Path()
|
||||||
|
|
||||||
|
# print("init_args")
|
||||||
|
# return init_args(args)
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def foreign_arch():
|
||||||
|
"""Fixture to return the foreign arch."""
|
||||||
|
from pmb.core.arch import Arch
|
||||||
|
if os.uname().machine == "x86_64":
|
||||||
|
return Arch.aarch64
|
||||||
|
|
||||||
|
return Arch.x86_64
|
||||||
|
|
|
@ -33,3 +33,10 @@ exclude = ["aports", "docs", "keys", "test", "test.pmb_test"]
|
||||||
# E722: do not use bare except
|
# E722: do not use bare except
|
||||||
lint.ignore=["E402", "E722"]
|
lint.ignore=["E402", "E722"]
|
||||||
line-length=100
|
line-length=100
|
||||||
|
|
||||||
|
[tool.pytest.ini_options]
|
||||||
|
addopts = [
|
||||||
|
"--import-mode=importlib",
|
||||||
|
"--basetemp=.pytest_tmp"
|
||||||
|
]
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue