test: add test for osbuild executable

Add two simple tests to check that the osbuild executable fails with the
right exit codes when passed an invalid manifest or checkpoint.

This reuses test.OSBuild, which is extended to raise CalledProcessError
if needed.
This commit is contained in:
Lars Karlitski 2020-10-27 20:59:09 +01:00 committed by Christian Kellner
parent a5d4a8a926
commit f7949d9993
2 changed files with 42 additions and 4 deletions

View file

@ -0,0 +1,30 @@
#
# Runtime Tests for the `osbuild` executable
#
import json
import subprocess
import unittest
from .. import test
class TestExecutable(unittest.TestCase):
def setUp(self):
self.osbuild = test.OSBuild(self)
def test_invalid_manifest(self):
invalid = json.dumps({"foo": 42})
with self.osbuild as osb, self.assertRaises(subprocess.CalledProcessError) as e:
osb.compile(invalid, check=True)
self.assertEqual(e.exception.returncode, 2)
def test_invalid_checkpoint(self):
manifest = json.dumps({})
with self.osbuild as osb, self.assertRaises(subprocess.CalledProcessError) as e:
osb.compile(manifest, checkpoints=["f44f76973fb92446a2a33bfdb401361a47f70497"], check=True)
self.assertEqual(e.exception.returncode, 1)

View file

@ -269,7 +269,7 @@ class OSBuild(contextlib.AbstractContextManager):
print(data_stderr)
print("-- END ---------------------------------")
def compile(self, data_stdin, output_dir=None, checkpoints=None):
def compile(self, data_stdin, output_dir=None, checkpoints=None, check=False):
"""Compile an Artifact
This takes a manifest as `data_stdin`, executes the pipeline, and
@ -280,6 +280,10 @@ class OSBuild(contextlib.AbstractContextManager):
the output_dir parameter. If it's set to None, a temporary directory
is used and thus the caller cannot access the built artifact.
`check` determines what happens when running osbuild fails. If it is
true, subprocess.CalledProcessError is raised. Otherwise, osbuild's
output is printed to stdout and a test assertion is raised.
Returns the build result as dictionary.
"""
@ -289,7 +293,7 @@ class OSBuild(contextlib.AbstractContextManager):
output_dir_context = contextlib.nullcontext(output_dir)
with output_dir_context as osbuild_output_dir:
cmd_args = []
cmd_args = ["python3", "-m", "osbuild"]
cmd_args += ["--json"]
cmd_args += ["--libdir", "."]
@ -299,13 +303,15 @@ class OSBuild(contextlib.AbstractContextManager):
for c in (checkpoints or []):
cmd_args += ["--checkpoint", c]
cmd_args += ["-"]
# Spawn the `osbuild` executable, feed it the specified data on
# `STDIN` and wait for completion. If we are interrupted, we always
# wait for `osbuild` to shut down, so we can clean up its file-system
# trees (they would trigger `EBUSY` if we didn't wait).
try:
p = subprocess.Popen(
["python3", "-m", "osbuild"] + cmd_args + ["-"],
cmd_args,
encoding="utf-8",
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
@ -316,8 +322,10 @@ class OSBuild(contextlib.AbstractContextManager):
p.wait()
raise
# If execution failed, print results to `STDOUT`.
# If execution failed, raise exception or print results to `STDOUT`.
if p.returncode != 0:
if check:
raise subprocess.CalledProcessError(p.returncode, cmd_args, data_stdout, data_stderr)
self._print_result(p.returncode, data_stdout, data_stderr)
self._unittest.assertEqual(p.returncode, 0)