mirror of
https://gitlab.postmarketos.org/postmarketOS/pmbootstrap.git
synced 2025-07-13 03:19:47 +03:00
test: move all tests into separate module (MR 2551)
When installing pmboostrap, all tests are installed alongside it. There doesn't seem to be any way to selectively exclude some files inside python modules, so move all test into a separate module instead. This is the typical convention in python projects. See: https://gitlab.alpinelinux.org/alpine/aports/-/merge_requests/79862 Fixes: https://gitlab.postmarketos.org/postmarketOS/pmbootstrap/-/issues/2541
This commit is contained in:
parent
c2bcc81589
commit
5a152aebae
16 changed files with 11 additions and 11 deletions
190
test/conftest.py
Normal file
190
test/conftest.py
Normal file
|
@ -0,0 +1,190 @@
|
|||
# Copyright 2024 Caleb Connolly
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
import os
|
||||
from pathlib import Path
|
||||
import pytest
|
||||
import shutil
|
||||
import tempfile
|
||||
|
||||
import pmb.core
|
||||
from pmb.core.context import get_context
|
||||
from pmb.types import PmbArgs
|
||||
from pmb.helpers.args import init as init_args
|
||||
|
||||
_testdir = Path(__file__).parent / "data/tests"
|
||||
|
||||
|
||||
# request can be specified using parameterize from test cases
|
||||
# e.g. @pytest.mark.parametrize("config_file", ["no-repos"], indirect=True)
|
||||
# will set request.param to "no-repos"
|
||||
@pytest.fixture
|
||||
def config_file(tmp_path_factory, request):
|
||||
"""Fixture to create a temporary pmbootstrap_v3.cfg file."""
|
||||
tmp_path = tmp_path_factory.mktemp("pmbootstrap")
|
||||
|
||||
flavour = "default"
|
||||
if hasattr(request, "param") and request.param:
|
||||
flavour = request.param
|
||||
|
||||
out_file = tmp_path / "pmbootstrap_v3.cfg"
|
||||
workdir = tmp_path / "work"
|
||||
workdir.mkdir()
|
||||
|
||||
configs = {"default": f"aports = {workdir / 'cache_git' / 'pmaports'}", "no-repos": "aports = "}
|
||||
|
||||
file = _testdir / "pmbootstrap_v3.cfg"
|
||||
print(f"CONFIG: {out_file}")
|
||||
cfg = configs[flavour]
|
||||
contents = open(file).read().format(workdir, cfg)
|
||||
|
||||
open(out_file, "w").write(contents)
|
||||
return out_file
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def device_package(config_file):
|
||||
"""Fixture to create a temporary deviceinfo file."""
|
||||
mock_device = "qemu-amd64"
|
||||
pkgdir = config_file.parent / f"device-{mock_device}"
|
||||
pkgdir.mkdir()
|
||||
|
||||
for file in ["APKBUILD", "deviceinfo"]:
|
||||
shutil.copy(_testdir / f"{file}.{mock_device}", pkgdir / file)
|
||||
|
||||
return pkgdir
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def find_required_programs():
|
||||
"""Fixture to find required programs for pmbootstrap."""
|
||||
|
||||
pmb.config.require_programs()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_devices_find_path(device_package, monkeypatch):
|
||||
"""Fixture to mock pmb.helpers.devices.find_path()"""
|
||||
|
||||
def mock_find_path(device, file=""):
|
||||
print(f"mock_find_path({device}, {file})")
|
||||
out = device_package / file
|
||||
if not out.exists():
|
||||
return None
|
||||
|
||||
return out
|
||||
|
||||
monkeypatch.setattr("pmb.helpers.devices.find_path", mock_find_path)
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def logfile(tmp_path_factory):
|
||||
"""Setup logging for all tests."""
|
||||
from pmb.helpers import logging
|
||||
|
||||
tmp_path = tmp_path_factory.getbasetemp()
|
||||
logfile = tmp_path / "log_testsuite.txt"
|
||||
logging.init(logfile, verbose=True)
|
||||
|
||||
return 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/set_context() is a bad hack :(
|
||||
@pytest.fixture
|
||||
def mock_context(monkeypatch):
|
||||
"""Mock set_context() to bypass sanity checks. Ideally we would
|
||||
mock get_context() as well, but since every submodule of pmb imports
|
||||
it like "from pmb.core.context import get_context()", we can't
|
||||
actually override it with monkeypatch.setattr(). So this is the
|
||||
best we can do... set_context() is only called from one place and is
|
||||
done so with the full namespace, so this works."""
|
||||
|
||||
def mock_set_context(ctx):
|
||||
print(f"mock_set_context({ctx})")
|
||||
setattr(pmb.core.context, "__context", ctx)
|
||||
|
||||
monkeypatch.setattr("pmb.core.context.set_context", mock_set_context)
|
||||
|
||||
|
||||
# FIXME: get_context() at runtime somehow doesn't return the
|
||||
# custom context we set up here.
|
||||
@pytest.fixture
|
||||
def pmb_args(config_file, mock_context, logfile):
|
||||
"""This is (still) a hack, since a bunch of the codebase still
|
||||
expects some global state to be initialised. We do that here."""
|
||||
|
||||
args = PmbArgs()
|
||||
args.config = config_file
|
||||
args.aports = None
|
||||
args.timeout = 900
|
||||
args.details_to_stdout = False
|
||||
args.quiet = False
|
||||
args.verbose = True
|
||||
args.offline = False
|
||||
args.action = "init"
|
||||
args.cross = False
|
||||
args.log = logfile
|
||||
|
||||
init_args(args)
|
||||
|
||||
print(f"WORK: {get_context().config.work}")
|
||||
|
||||
# Sanity check
|
||||
assert ".pytest_tmp" in get_context().config.work.parts
|
||||
|
||||
|
||||
@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
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def pmaports(pmb_args, monkeypatch):
|
||||
"""Fixture to clone pmaports."""
|
||||
|
||||
from pmb.core import Config
|
||||
from pmb.core.context import get_context
|
||||
|
||||
cfg = get_context().config
|
||||
|
||||
# As an optimisation, we check the default workdir for pmaports
|
||||
# and clone it from there if it exists. This saves a bunch of bandwidth
|
||||
# and time.
|
||||
if Config.aports[-1].exists():
|
||||
# Override the URL to the local path so we can later look up the
|
||||
# remote by URL
|
||||
pmb.config.git_repos["pmaports"] = [str(Config.aports[-1])]
|
||||
|
||||
if not cfg.aports[-1].exists():
|
||||
pmb.helpers.git.clone("pmaports")
|
||||
# Now operate on the cloned repo
|
||||
assert pmb.helpers.run.user(["git", "checkout", "master"], working_dir=cfg.aports[-1]) == 0
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def tmp_file(tmp_path):
|
||||
return Path(tempfile.mkstemp(dir=tmp_path)[1])
|
Loading…
Add table
Add a link
Reference in a new issue