EOF
- name: Run integration tests
- run: sudo --preserve-env timeout -k 30 1h python3 -m pytest --tb=no -sv -m integration tests/
- env:
- MKOSI_TEST_DISTRIBUTION: ${{ matrix.distro }}
+ run: sudo --preserve-env timeout -k 30 1h python3 -m pytest --tb=no -sv -m integration -D ${{ matrix.distro }} tests/
target-version = "py39"
line-length = 119
select = ["E", "F", "I", "UP"]
+
+[tool.pytest.ini_options]
+markers = [
+ "integration: mark a test as an integration test."
+]
+addopts = "-m \"not integration\""
+++ /dev/null
-[pytest]
-markers =
- integration: mark a test as an integration test.
-addopts = -m "not integration"
import tempfile
from collections.abc import Iterator, Sequence
from types import TracebackType
-from typing import Any, Optional
+from typing import Any, NamedTuple, Optional
import pytest
-from mkosi.distributions import Distribution, detect_distribution
-from mkosi.log import die
+from mkosi.distributions import Distribution
from mkosi.run import run
from mkosi.types import _FILE, CompletedProcess, PathString
from mkosi.util import INVOKING_USER
class Image:
- def __init__(self, options: Sequence[PathString] = []) -> None:
- self.options = options
-
- if d := os.getenv("MKOSI_TEST_DISTRIBUTION"):
- self.distribution = Distribution(d)
- elif detected := detect_distribution()[0]:
- self.distribution = detected
- else:
- die("Cannot detect host distribution, please set $MKOSI_TEST_DISTRIBUTION to be able to run the tests")
+ class Config(NamedTuple):
+ distribution: Distribution
+ release: str
- if r := os.getenv("MKOSI_TEST_RELEASE"):
- self.release = r
- else:
- self.release = self.distribution.default_release()
+ def __init__(self, config: Config, options: Sequence[PathString] = []) -> None:
+ self.options = options
+ self.config = config
def __enter__(self) -> "Image":
self.output_dir = tempfile.TemporaryDirectory(dir="/var/tmp")
return run([
"python3", "-m", "mkosi",
- "--distribution", str(self.distribution),
- "--release", self.release,
+ "--distribution", str(self.config.distribution),
+ "--release", self.config.release,
*self.options,
*options,
"--output-dir", self.output_dir.name,
check=False,
)
- rc = 0 if self.distribution == Distribution.ubuntu or self.distribution.is_centos_variant() else 123
+ if self.config.distribution == Distribution.ubuntu or self.config.distribution.is_centos_variant():
+ rc = 0
+ else:
+ rc = 123
if result.returncode != rc:
raise subprocess.CalledProcessError(result.returncode, result.args, result.stdout, result.stderr)
--- /dev/null
+# SPDX-License-Identifier: LGPL-2.1+
+from typing import Any, Optional, cast
+
+import pytest
+
+from mkosi.distributions import Distribution, detect_distribution
+
+from . import Image
+
+
+def pytest_addoption(parser: Any) -> None:
+ parser.addoption(
+ "-D",
+ "--distribution",
+ metavar="DISTRIBUTION",
+ help="Run the integration tests for the given distribution.",
+ default=detect_distribution()[0],
+ type=Distribution,
+ choices=[Distribution(d) for d in Distribution.values()],
+ )
+ parser.addoption(
+ "-R",
+ "--release",
+ metavar="RELEASE",
+ help="Run the integration tests for the given release.",
+ )
+
+
+@pytest.fixture(scope="session")
+def config(request: Any) -> Image.Config:
+ distribution = cast(Distribution, request.config.getoption("--distribution"))
+ release = cast(Optional[str], request.config.getoption("--release"))
+ if release is None:
+ release = distribution.default_release()
+
+ return Image.Config(distribution=distribution, release=release)
@pytest.mark.parametrize("format", OutputFormat)
-def test_boot(format: OutputFormat) -> None:
+def test_boot(config: Image.Config, format: OutputFormat) -> None:
with Image(
+ config,
options=[
"--kernel-command-line=systemd.unit=mkosi-check-and-shutdown.service",
"--incremental",
"--ephemeral",
],
) as image:
- if image.distribution == Distribution.rhel_ubi and format in (OutputFormat.esp, OutputFormat.uki):
+ if image.config.distribution == Distribution.rhel_ubi and format in (OutputFormat.esp, OutputFormat.uki):
pytest.skip("Cannot build RHEL-UBI images with format 'esp' or 'uki'")
options = ["--format", str(format)]
image.boot(options=options, args=args)
if (
- image.distribution == Distribution.ubuntu and
+ image.config.distribution == Distribution.ubuntu and
format in (OutputFormat.cpio, OutputFormat.uki, OutputFormat.esp)
):
# https://bugs.launchpad.net/ubuntu/+source/linux-kvm/+bug/2045561
pytest.skip("Cannot boot Ubuntu UKI/cpio images in qemu until we switch back to linux-kvm")
- if image.distribution == Distribution.rhel_ubi:
+ if image.config.distribution == Distribution.rhel_ubi:
return
if format in (OutputFormat.tar, OutputFormat.none) or format.is_extension_image():
@pytest.fixture(scope="module")
-def initrd(passphrase: Path) -> Iterator[Image]:
+def initrd(config: Image.Config, passphrase: Path) -> Iterator[Image]:
with Image(
+ config,
options=[
"--directory", "",
"--include=mkosi-initrd/",
"--extra-tree", passphrase,
],
) as initrd:
- if initrd.distribution == Distribution.rhel_ubi:
+ if initrd.config.distribution == Distribution.rhel_ubi:
pytest.skip("Cannot build RHEL-UBI initrds")
initrd.build()
def test_initrd(initrd: Image) -> None:
with Image(
+ initrd.config,
options=[
"--initrd", Path(initrd.output_dir.name) / "initrd",
"--kernel-command-line=systemd.unit=mkosi-check-and-shutdown.service",
@pytest.mark.skipif(os.getuid() != 0, reason="mkosi-initrd LVM test can only be executed as root")
def test_initrd_lvm(initrd: Image) -> None:
with Image(
+ initrd.config,
options=[
"--initrd", Path(initrd.output_dir.name) / "initrd",
"--kernel-command-line=systemd.unit=mkosi-check-and-shutdown.service",
run(["lvm", "lvcreate", "-l", "100%FREE", "-n", "lv0", "vg_mkosi"])
run(["lvm", "lvs"])
run(["udevadm", "wait", "/dev/vg_mkosi/lv0"])
- run([f"mkfs.{image.distribution.filesystem()}", "-L", "root", "/dev/vg_mkosi/lv0"])
+ run([f"mkfs.{image.config.distribution.filesystem()}", "-L", "root", "/dev/vg_mkosi/lv0"])
with tempfile.TemporaryDirectory() as mnt, mount(Path("/dev/vg_mkosi/lv0"), Path(mnt)):
# The image might have been built unprivileged so we need to fix the file ownership. Making all the
f"""\
[Partition]
Type=root
- Format={initrd.distribution.filesystem()}
+ Format={initrd.config.distribution.filesystem()}
Minimize=guess
Encrypt=key-file
CopyFiles=/
)
with Image(
+ initrd.config,
options=[
"--initrd", Path(initrd.output_dir.name) / "initrd",
"--repart-dir", repartd,
@pytest.mark.skipif(os.getuid() != 0, reason="mkosi-initrd LUKS+LVM test can only be executed as root")
-def test_initrd_luks_lvm(initrd: Image, passphrase: Path) -> None:
+def test_initrd_luks_lvm(config: Image.Config, initrd: Image, passphrase: Path) -> None:
with Image(
+ config,
options=[
"--initrd", Path(initrd.output_dir.name) / "initrd",
"--kernel-command-line=systemd.unit=mkosi-check-and-shutdown.service",
run(["lvm", "lvcreate", "-l", "100%FREE", "-n", "lv0", "vg_mkosi"])
run(["lvm", "lvs"])
run(["udevadm", "wait", "/dev/vg_mkosi/lv0"])
- run([f"mkfs.{image.distribution.filesystem()}", "-L", "root", "/dev/vg_mkosi/lv0"])
+ run([f"mkfs.{image.config.distribution.filesystem()}", "-L", "root", "/dev/vg_mkosi/lv0"])
with tempfile.TemporaryDirectory() as mnt, mount(Path("/dev/vg_mkosi/lv0"), Path(mnt)):
# The image might have been built unprivileged so we need to fix the file ownership. Making all the
Distribution.ubuntu: 32,
Distribution.arch: 47,
Distribution.opensuse: 36,
- }.get(initrd.distribution, 48)
+ }.get(initrd.config.distribution, 48)
assert (Path(initrd.output_dir.name) / "initrd").stat().st_size <= maxsize
pytestmark = pytest.mark.integration
-def test_sysext() -> None:
+def test_sysext(config: Image.Config) -> None:
with Image(
+ config,
options=[
"--incremental",
"--clean-package-metadata=no",
image.build()
with Image(
+ image.config,
options=[
"--directory", "",
"--base-tree", Path(image.output_dir.name) / "image",