forked from Mirror/pmbootstrap
Using pmbootstrap v3 with the old config can cause problems, for example when having $WORK in the pmaports dir instead of the actual work path. This is not supported anymore by v3 to reduce complexity. The format of how mirrors are stored in the config also has changed. Use a separate config file, so users can go back from v3 to 2.3.x if they need to (for figuring out a regression) and so users won't run into bugs when moving from 2.3.x to v3.
167 lines
4.5 KiB
Python
167 lines
4.5 KiB
Python
import os
|
|
from pathlib import Path
|
|
import pytest
|
|
import shutil
|
|
|
|
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"
|
|
|
|
|
|
@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
|
|
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
|
|
|
|
config = get_context().config
|
|
|
|
with monkeypatch.context() as m:
|
|
# Speed things up by cloning from the local checkout if it exists.
|
|
if Config.aports[0].exists():
|
|
m.setitem(pmb.config.git_repos, "pmaports", Config.aports)
|
|
|
|
pmb.helpers.git.clone("pmaports")
|
|
|
|
assert pmb.helpers.run.user(["git", "checkout", "master"], working_dir=config.aports[0]) == 0
|