stages(bootupd): add tests for existing behavior
Also refactor bind mounts into a helper.
This commit is contained in:
parent
eb657b08b3
commit
dacf5733ea
2 changed files with 64 additions and 28 deletions
|
|
@ -9,6 +9,7 @@ and GRUB for BIOS firmware on x86_64.
|
|||
The project is deployed in Fedora CoreOS and derivatives
|
||||
"""
|
||||
|
||||
import contextlib
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
|
@ -67,6 +68,19 @@ SCHEMA_2 = r"""
|
|||
"""
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def bind_mounts(sources, dest_root):
|
||||
for src in sources:
|
||||
dst = os.path.join(dest_root, src.lstrip("/"))
|
||||
subprocess.run(["mount", "--rbind", src, dst], check=True)
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
for src in sources:
|
||||
dst = os.path.join(dest_root, src.lstrip("/"))
|
||||
subprocess.run(["umount", "--recursive", dst], check=False)
|
||||
|
||||
|
||||
def main(args, options):
|
||||
deployment = options.get("deployment", None)
|
||||
static_configs = options.get("static-configs", False)
|
||||
|
|
@ -101,22 +115,11 @@ def main(args, options):
|
|||
# want to make sure the version used matches the target and not
|
||||
# risk any inconsistencies with the build root). Let's set up
|
||||
# and chroot to run the bootupctl command from the target.
|
||||
submounts = ['dev', 'proc', 'sys', 'run', 'var', 'tmp']
|
||||
for mnt in submounts:
|
||||
subprocess.run(['mount', '--rbind',
|
||||
os.path.join("/", mnt),
|
||||
os.path.join(root, mnt)],
|
||||
check=True)
|
||||
try:
|
||||
with bind_mounts(['/dev', '/proc', '/sys', '/run', '/var', '/tmp'], root):
|
||||
cmd = ['chroot', root, '/usr/bin/bootupctl', 'backend', 'install']
|
||||
cmd.extend(bootupd_args)
|
||||
cmd.append(mounts)
|
||||
subprocess.run(cmd, check=True)
|
||||
finally:
|
||||
for mnt in submounts:
|
||||
subprocess.run(['umount', '--recursive',
|
||||
os.path.join(root, mnt)],
|
||||
check=False)
|
||||
|
||||
return 0
|
||||
|
||||
|
|
|
|||
|
|
@ -1,39 +1,42 @@
|
|||
#!/usr/bin/python3
|
||||
|
||||
import os.path
|
||||
import subprocess
|
||||
from unittest import mock
|
||||
from unittest.mock import call, patch
|
||||
|
||||
import pytest
|
||||
|
||||
import osbuild.meta
|
||||
from osbuild.testutil import has_executable, make_fake_input_tree
|
||||
from osbuild.testutil.imports import import_module_from_path
|
||||
|
||||
|
||||
@pytest.mark.parametrize("test_data,expected_err", [
|
||||
# bad
|
||||
({"deployment": "totally"}, "'totally' is not of type 'object'"),
|
||||
({"deployment": "must-be-object"}, "'must-be-object' is not of type 'object'"),
|
||||
({"deployment": {"osname": "some-os"}}, "'ref' is a required property"),
|
||||
({"deployment": {"ref": "some-ref"}}, "'osname' is a required property"),
|
||||
({"deployment": {"osname": "some-os", "ref": "some-ref", "serial": "yo"}}, "'yo' is not of type 'number'"),
|
||||
({"deployment": {"osname": "some-os", "ref": "some-ref", "serial": "must-be-number"}},
|
||||
"'must-be-number' is not of type 'number'"),
|
||||
({"random": "property"}, "Additional properties are not allowed"),
|
||||
({"bios": {}}, "'device' is a required property"),
|
||||
({"bios": "yes"}, "'yes' is not of type 'object'"),
|
||||
({"bios": "must-be-object"}, "'must-be-object' is not of type 'object'"),
|
||||
# good
|
||||
({}, ""),
|
||||
({"deployment": {
|
||||
"osname": "some-os",
|
||||
"ref": "some-ref",
|
||||
"serial": 1,
|
||||
},
|
||||
"static-configs": True,
|
||||
"bios": {
|
||||
"device": "/dev/sda",
|
||||
}}, "")
|
||||
({
|
||||
"deployment":
|
||||
{
|
||||
"osname": "some-os",
|
||||
"ref": "some-ref",
|
||||
"serial": 1,
|
||||
},
|
||||
"static-configs": True,
|
||||
"bios":
|
||||
{
|
||||
"device": "/dev/sda",
|
||||
},
|
||||
}, "")
|
||||
|
||||
])
|
||||
def test_schema_validation_bootupd(test_data, expected_err):
|
||||
def test_bootupd_schema_validation(test_data, expected_err):
|
||||
name = "org.osbuild.bootupd"
|
||||
root = os.path.join(os.path.dirname(__file__), "../..")
|
||||
mod_info = osbuild.meta.ModuleInfo.load(root, "Stage", name)
|
||||
|
|
@ -54,3 +57,33 @@ def test_schema_validation_bootupd(test_data, expected_err):
|
|||
assert len(res.errors) == 1, [e.as_dict() for e in res.errors]
|
||||
err_msgs = [e.as_dict()["message"] for e in res.errors]
|
||||
assert expected_err in err_msgs[0]
|
||||
|
||||
|
||||
@patch("subprocess.run")
|
||||
def test_bootupd_defaults(mocked_run):
|
||||
stage_path = os.path.join(os.path.dirname(__file__), "../org.osbuild.bootupd")
|
||||
stage = import_module_from_path("bootupd_stage", stage_path)
|
||||
|
||||
args = {
|
||||
"paths": {
|
||||
"mounts": "/run/osbuild/mounts",
|
||||
},
|
||||
}
|
||||
options = {}
|
||||
stage.main(args, options)
|
||||
|
||||
assert mocked_run.call_args_list == [
|
||||
call(["mount", "--rbind", "/dev", "/run/osbuild/mounts/dev"], check=True),
|
||||
call(["mount", "--rbind", "/proc", "/run/osbuild/mounts/proc"], check=True),
|
||||
call(["mount", "--rbind", "/sys", "/run/osbuild/mounts/sys"], check=True),
|
||||
call(["mount", "--rbind", "/run", "/run/osbuild/mounts/run"], check=True),
|
||||
call(["mount", "--rbind", "/var", "/run/osbuild/mounts/var"], check=True),
|
||||
call(["mount", "--rbind", "/tmp", "/run/osbuild/mounts/tmp"], check=True),
|
||||
call(["chroot", "/run/osbuild/mounts", "/usr/bin/bootupctl", "backend", "install", "/run/osbuild/mounts"], check=True),
|
||||
call(["umount", "--recursive", "/run/osbuild/mounts/dev"], check=False),
|
||||
call(["umount", "--recursive", "/run/osbuild/mounts/proc"], check=False),
|
||||
call(["umount", "--recursive", "/run/osbuild/mounts/sys"], check=False),
|
||||
call(["umount", "--recursive", "/run/osbuild/mounts/run"], check=False),
|
||||
call(["umount", "--recursive", "/run/osbuild/mounts/var"], check=False),
|
||||
call(["umount", "--recursive", "/run/osbuild/mounts/tmp"], check=False),
|
||||
]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue