Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions bci_tester/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -856,6 +856,14 @@ def create_BCI(
for versions, tag in ((("15.6",), "9"), (("tumbleweed",), "10"))
]

OSC_CONTAINERS = [
create_BCI(
build_tag=f"{APP_CONTAINER_PREFIX}/osc:latest",
bci_type=ImageType.APPLICATION,
available_versions=["tumbleweed"],
)
]

CONTAINERS_WITH_ZYPPER = (
[
BASE_CONTAINER,
Expand Down Expand Up @@ -888,6 +896,7 @@ def create_BCI(
+ RUBY_CONTAINERS
+ RUST_CONTAINERS
+ SPACK_CONTAINERS
+ OSC_CONTAINERS
+ (DOTNET_CONTAINERS if LOCALHOST.system_info.arch == "x86_64" else [])
)

Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ markers = [
'openjdk-devel_17',
'openjdk-devel_21',
'openjdk-devel_22',
'osc_latest',
'pcp_5',
'pcp_6',
'php_8',
Expand Down
2 changes: 2 additions & 0 deletions tests/test_metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
from bci_tester.data import OPENJDK_DEVEL_17_CONTAINER
from bci_tester.data import OPENJDK_DEVEL_21_CONTAINER
from bci_tester.data import OPENJDK_DEVEL_22_CONTAINER
from bci_tester.data import OSC_CONTAINERS
from bci_tester.data import OS_SP_VERSION
from bci_tester.data import OS_VERSION
from bci_tester.data import PCP_CONTAINERS
Expand Down Expand Up @@ -237,6 +238,7 @@ def _get_container_label_prefix(
+ [
(DISTRIBUTION_CONTAINER, "registry", ImageType.APPLICATION),
]
+ [(osc_ctr, "osc", ImageType.APPLICATION) for osc_ctr in OSC_CONTAINERS]
+ (
[
(DOTNET_SDK_6_0_CONTAINER, "dotnet.sdk", ImageType.LANGUAGE_STACK),
Expand Down
179 changes: 179 additions & 0 deletions tests/test_osc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
"""Smoke tests for the osc container"""

import os.path
import re
from pathlib import Path
from typing import List
from typing import Union

import pytest
from pytest_container import DerivedContainer
from pytest_container import OciRuntimeBase
from pytest_container import container_and_marks_from_pytest_param
from pytest_container.container import BindMount
from pytest_container.container import ContainerData
from pytest_container.container import ContainerLauncher
from pytest_container.container import ContainerVolume
from pytest_container.container import VolumeFlag
from pytest_container.runtime import LOCALHOST

from bci_tester.data import OSC_CONTAINERS

pytestmark = pytest.mark.skipif(
(not LOCALHOST.package("osc").is_installed)
or (
"api.opensuse.org"
not in LOCALHOST.check_output("osc config general apiurl")
),
reason="osc not installed or not configured to communicate with OBS",
)

OSC_WITH_CONFIG_CTR = []
_volume_mounts: List[Union[BindMount, ContainerVolume]] = [
BindMount(
host_path=os.path.expanduser("~/.config/osc/oscrc"),
container_path="/root/.config/osc/oscrc",
flags=[
VolumeFlag.READ_ONLY,
VolumeFlag.SELINUX_PRIVATE,
],
),
BindMount(
host_path=os.path.expanduser("~/.local/state/osc/cookiejar"),
container_path="/root/.local/state/osc/cookiejar",
),
]

for param in OSC_CONTAINERS:
_ctr, _marks = container_and_marks_from_pytest_param(param)
OSC_WITH_CONFIG_CTR.append(
pytest.param(
DerivedContainer(
base=_ctr,
extra_launch_args=["--privileged"],
volume_mounts=_volume_mounts,
),
marks=_marks,
id=param.id,
)
)

CONTAINER_IMAGES = OSC_WITH_CONFIG_CTR


def test_osc_ls_factory(auto_container: ContainerData):
"""Simple smoke test for :command:`osc ls openSUSE:Factory` working."""
assert "aaa_base" in auto_container.connection.check_output(
"osc ls openSUSE:Factory"
)


def test_osc_checkout(auto_container_per_test: ContainerData):
"""Try to run :command:`osc co devel:microos/slirp4netns` and check whether
``slirp4netns.spec`` exists.

"""
prj, pkg = "devel:microos", "slirp4netns"
auto_container_per_test.connection.check_output(f"osc co {prj}/{pkg}")

assert auto_container_per_test.connection.file(
str(
auto_container_per_test.inspect.config.workingdir
/ prj
/ pkg
/ f"{pkg}.spec"
)
).exists


def test_osc_build_rootlesskit(auto_container_per_test: ContainerData):
"""Checkout ``devel:microos/rootlesskit``, change into that directory, build
the package and verify that the resulting binaries are valid rpms.

"""
prj, pkg = "devel:microos", "rootlesskit"
auto_container_per_test.connection.check_output(f"osc co {prj}/{pkg}")
osc_build_out: str = auto_container_per_test.connection.check_output(
f"cd {prj}/{pkg}; osc build"
)

rpm_count = 0

for line in reversed(osc_build_out.strip().splitlines()):
if line.startswith("["):
break

if line.startswith("/var/tmp/") and line.endswith("rpm"):
rpm_count += 1
assert auto_container_per_test.connection.file(line).exists
auto_container_per_test.connection.check_output(f"rpm -q {line}")

assert rpm_count > 0, "Must have at least one built rpm"


@pytest.mark.parametrize("ctr_image", OSC_CONTAINERS)
def test_osc_packagecache_volume(
pytestconfig: pytest.Config,
container_runtime: OciRuntimeBase,
ctr_image: DerivedContainer,
tmp_path: Path,
) -> None:
"""Test a build of ``devel:microos/rootleskit`` with the
:file:`/var/tmp/osbuild-packagecache` directory bind mounted to the host
into a temporary directory. Then create a new container sharing the
package-cache, rebuild ``devel:microos/rootleskit`` and check that the
package cache is reused.

"""
ctr_with_volume = DerivedContainer(
base=ctr_image,
extra_launch_args=["--privileged"],
volume_mounts=(
_volume_mounts
+ [
BindMount(
container_path="/var/tmp/osbuild-packagecache",
host_path=str(tmp_path),
)
]
),
)

prj, pkg = "devel:microos", "rootlesskit"

assert len(os.listdir(tmp_path)) == 0

# launch the container via the launcher and not the fixture, as we cannot
# launch two containers after another
with ContainerLauncher.from_pytestconfig(
ctr_with_volume, container_runtime, pytestconfig
) as launcher:
launcher.launch_container()
con = launcher.container_data.connection
con.check_output(f"osc co {prj}/{pkg}")
assert "100.0% cache miss." in con.check_output(
f"cd {prj}/{pkg}; osc build"
)

# there should be now _something_ in the cache
assert len(os.listdir(tmp_path)) > 0

# and now the cache should be used
with ContainerLauncher.from_pytestconfig(
ctr_with_volume, container_runtime, pytestconfig
) as launcher:
launcher.launch_container()
con = launcher.container_data.connection
con.check_output(f"osc co {prj}/{pkg}")

cache_misses = re.search(
r"^(?P<percent>\d+(\.\d)?)% cache miss.",
con.check_output(f"cd {prj}/{pkg}; osc build"),
flags=re.MULTILINE,
)

assert (
cache_misses
and cache_misses.group("percent")
and float(cache_misses.group("percent")) < 100.0
)
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[tox]
envlist = {py36,py39,py310,py311,py312}-unit, all, base, fips, init, dotnet, python, ruby, node, go, openjdk, openjdk_devel, rust, php, busybox, 389ds, metadata, minimal, multistage, repository, doc, lint, get_urls, pcp, distribution, postgres, git, helm, nginx, kernel_module, mariadb, tomcat, spack, gcc, prometheus, grafana, kiwi, postfix
envlist = {py36,py39,py310,py311,py312}-unit, all, base, fips, init, dotnet, python, ruby, node, go, openjdk, openjdk_devel, rust, php, busybox, 389ds, metadata, minimal, multistage, repository, doc, lint, get_urls, pcp, distribution, postgres, git, helm, nginx, kernel_module, mariadb, tomcat, spack, gcc, prometheus, grafana, kiwi, postfix, osc
isolated_build = True
skip_missing_interpreters = True
skip_install = True
Expand Down
Loading