debian-forge/test/mod/test_buildroot.py
Christian Kellner d7d84a8eb1 test/mod: use proper host runner
Instead of hard-coding the use of the "org.osbuild.linux" runner,
use the new `osbuild.pipeline.detect_host_runner` function to
dynamically detect the runner for the host system. That should fix
the tests on RHEL systems, where python3 is by default not present
and even if it is manually installed, is an indirection via
alternatives (i.e. a link to /etc/alternatives), which must be
explicitly configured in the build root container for the host.
2020-10-21 11:13:28 +02:00

139 lines
4.2 KiB
Python

#
# Test for the build root
#
import pathlib
import os
import sys
import tempfile
import unittest
from osbuild.buildroot import BuildRoot
from osbuild.monitor import LogMonitor, NullMonitor
from osbuild.pipeline import detect_host_runner
from .. import test
@unittest.skipUnless(test.TestBase.can_bind_mount(), "root-only")
class TestBuildRoot(test.TestBase):
"""Check BuildRoot"""
def setUp(self):
self.tmp = tempfile.TemporaryDirectory()
def tearDown(self):
self.tmp.cleanup()
def test_basic(self):
runner = detect_host_runner()
libdir = os.path.abspath(os.curdir)
var = pathlib.Path(self.tmp.name, "var")
var.mkdir()
monitor = NullMonitor(sys.stderr.fileno())
with BuildRoot("/", runner, libdir, var=var) as root:
r = root.run(["/usr/bin/true"], monitor)
self.assertEqual(r.returncode, 0)
# Test we can use `.run` multiple times
r = root.run(["/usr/bin/true"], monitor)
self.assertEqual(r.returncode, 0)
r = root.run(["/usr/bin/false"], monitor)
self.assertNotEqual(r.returncode, 0)
def test_runner_fail(self):
runner = "org.osbuild.nonexistantrunner"
libdir = os.path.abspath(os.curdir)
var = pathlib.Path(self.tmp.name, "var")
var.mkdir()
logfile = os.path.join(self.tmp.name, "log.txt")
with BuildRoot("/", runner, libdir, var=var) as root, \
open(logfile, "w") as log:
monitor = LogMonitor(log.fileno())
r = root.run(["/usr/bin/true"], monitor)
self.assertEqual(r.returncode, 1)
with open(logfile) as f:
log = f.read()
assert log
assert r.output
self.assertEqual(log, r.output)
def test_output(self):
runner = detect_host_runner()
libdir = os.path.abspath(os.curdir)
var = pathlib.Path(self.tmp.name, "var")
var.mkdir()
data = "42. cats are superior to dogs"
monitor = NullMonitor(sys.stderr.fileno())
with BuildRoot("/", runner, libdir, var=var) as root:
r = root.run(["/usr/bin/echo", data], monitor)
self.assertEqual(r.returncode, 0)
self.assertIn(data, r.output.strip())
@unittest.skipUnless(test.TestBase.have_test_data(), "no test-data access")
def test_bind_mounts(self):
runner = detect_host_runner()
libdir = os.path.abspath(os.curdir)
var = pathlib.Path(self.tmp.name, "var")
var.mkdir()
rw_data = pathlib.Path(self.tmp.name, "data")
rw_data.mkdir()
scripts = os.path.join(self.locate_test_data(), "scripts")
monitor = NullMonitor(sys.stderr.fileno())
with BuildRoot("/", runner, libdir, var=var) as root:
ro_binds = [f"{scripts}:/scripts"]
cmd = ["/scripts/mount_flags.py",
"/scripts",
"ro"]
r = root.run(cmd, monitor, readonly_binds=ro_binds)
self.assertEqual(r.returncode, 0)
cmd = ["/scripts/mount_flags.py",
"/rw-data",
"ro"]
binds = [f"{rw_data}:/rw-data"]
r = root.run(cmd, monitor, binds=binds, readonly_binds=ro_binds)
self.assertEqual(r.returncode, 1)
@unittest.skipUnless(test.TestBase.have_test_data(), "no test-data access")
@unittest.skipUnless(os.path.exists("/sys/fs/selinux"), "no SELinux")
def test_selinuxfs_ro(self):
# /sys/fs/selinux must never be writable in the container
# because RPM and other tools must not assume the policy
# of the host is the valid policy
runner = detect_host_runner()
libdir = os.path.abspath(os.curdir)
var = pathlib.Path(self.tmp.name, "var")
var.mkdir()
scripts = os.path.join(self.locate_test_data(), "scripts")
monitor = NullMonitor(sys.stderr.fileno())
with BuildRoot("/", runner, libdir, var=var) as root:
ro_binds = [f"{scripts}:/scripts"]
cmd = ["/scripts/mount_flags.py",
"/sys/fs/selinux",
"ro"]
r = root.run(cmd, monitor, readonly_binds=ro_binds)
self.assertEqual(r.returncode, 0)