Skip to content

Commit

Permalink
test: add integration test for reporting errors from osbuild
Browse files Browse the repository at this point in the history
This commit adds a proper integration test that ensures that we
always report the details of a failing osbuild run. This prevents
regressions like the one from osbuild#810.

This ensures that:
a) we report the messags from a broken stage
b) we report any osbuild messages as well to catch e.g.
   crashes that are not reported via the json progress

It is archived by creating a new build container fixture that is
deliberately broken, i.e:
a) the org.osbuild.selinux stage is replaced with a fake that
   will echo some msgs and then error
b) osbuild itself is is wrapped around so that we can reliably
   echo some canary strings before the real osbuild is executed
  • Loading branch information
mvo5 committed Feb 5, 2025
1 parent db7b418 commit 8366e01
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 1 deletion.
47 changes: 47 additions & 0 deletions test/containerbuild.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,3 +97,50 @@ def build_fake_container_fixture(tmpdir_factory, build_container):
tmp_path,
])
return container_tag


@pytest.fixture(name="build_erroring_container", scope="session")
def build_erroring_container_fixture(tmpdir_factory, build_container):
"""Build a container with a erroring osbuild and returns the name"""
tmp_path = tmpdir_factory.mktemp("build-fake-container")

# this ensures there are messages from osbuild itself that
# we can reliably test for
wrapping_osbuild_path = tmp_path / "wrapping-osbuild"
wrapping_osbuild_path.write_text(textwrap.dedent("""\
#!/bin/sh -e
echo "output-from-osbuild-stdout"
>&2 echo "output-from-osbuild-stderr"
exec /usr/bin/osbuild.real "$@"
"""), encoding="utf8")

# this ensures we have a failing stage and failure messages
bad_stage_path = tmp_path / "bad-stage"
bad_stage_path.write_text(textwrap.dedent("""\
#!/bin/sh -e
echo osbuild-stage-stdout-output
>&2 echo osbuild-stage-stderr-output
exit 112
"""), encoding="utf8")

cntf_path = tmp_path / "Containerfile"
cntf_path.write_text(textwrap.dedent(f"""\n
FROM {build_container}
# ensure there is osbuild output
COPY --from={build_container} /usr/bin/osbuild /usr/bin/osbuild.real
COPY wrapping-osbuild /usr/bin/osbuild
RUN chmod 755 /usr/bin/osbuild
# we break org.osbuild.selinux as runs early and is used everywhere
COPY bad-stage /usr/lib/osbuild/stages/org.osbuild.selinux
RUN chmod +x /usr/lib/osbuild/stages/org.osbuild.selinux
"""), encoding="utf8")

container_tag = "bootc-image-builder-test--osbuild"
subprocess.check_call([
"podman", "build",
"-t", container_tag,
tmp_path,
])
return container_tag
32 changes: 31 additions & 1 deletion test/test_progress.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import subprocess

import pytest

import testutil
# pylint: disable=unused-import,duplicate-code
from test_opts import container_storage_fixture
from containerbuild import build_container_fixture, build_fake_container_fixture
from containerbuild import (
build_container_fixture,
build_erroring_container_fixture,
build_fake_container_fixture,
)


def test_progress_debug(tmp_path, build_fake_container):
Expand Down Expand Up @@ -65,3 +71,27 @@ def test_progress_term_autoselect(tmp_path, build_fake_container):
assert res.returncode == 0
# its curious that we get the output on stdout here, podman weirdness?
assert "[|] Manifest generation step" in res.stdout


@pytest.mark.skipif(not testutil.can_start_rootful_containers, reason="require a rootful containers (try: sudo)")
@pytest.mark.parametrize("progress", ["term", "verbose"])
def test_progress_error_reporting(tmp_path, build_erroring_container, progress):
output_path = tmp_path / "output"
output_path.mkdir(exist_ok=True)

cmdline = [
*testutil.podman_run_common,
"-v", "/var/lib/containers/storage:/var/lib/containers/storage",
# we have a terminal
"-t",
build_erroring_container,
"build",
f"--progress={progress}",
"quay.io/centos-bootc/centos-bootc:stream9",
]
res = subprocess.run(cmdline, capture_output=True, text=True, check=False)
assert "osbuild-stage-stdout-output" in res.stdout
assert "osbuild-stage-stderr-output" in res.stdout
assert "output-from-osbuild-stdout" in res.stdout
assert "output-from-osbuild-stderr" in res.stdout
assert res.returncode == 1

0 comments on commit 8366e01

Please sign in to comment.