Files
rust-package-builder/tests/test_suse.py
T
2026-10-22 16:10:02 +02:00

135 lines
6.2 KiB
Python

#!/usr/bin/env python3
"""Offline verification of SUSE nFPM metadata and catalog integration.
Run: python3 -m unittest discover -s tests -v
Does not require nfpm, root, Docker, or access to the RustProxy upstream.
"""
import importlib.util
import os
import subprocess
import tempfile
import unittest
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
class SusePackagingTests(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.tmp = tempfile.TemporaryDirectory()
cls.work = Path(cls.tmp.name)
cls.src = cls.work / "source"
(cls.src / "docker-agent").mkdir(parents=True)
agent = cls.src / "docker-agent"
(agent / "rustproxy-docker-agent.service").write_text(
"[Unit]\nDescription=Test Agent\n[Service]\nExecStart=/usr/local/bin/rustproxy-docker-agent\n")
(agent / "docker-agent.env.example").write_text("BIND_ADDRESS=127.0.0.1\n")
(agent / "README.md").write_text("Test fixture")
(cls.work / "server").write_text("#!/bin/sh\necho server\n")
(cls.work / "agent").write_text("#!/bin/sh\necho agent\n")
(cls.work / "server").chmod(0o755)
(cls.work / "agent").chmod(0o755)
cls.env = {
**os.environ,
"BUILDER_ROOT": str(ROOT),
"PACKAGE_NAME": "rustproxy",
"BINARY_NAME": "rust-proxy",
"VERSION": "0.99.1",
"PACKAGE_RELEASE": "7",
"MAINTAINER": "Test Builder <test@example.invalid>",
"DESCRIPTION": "Test RPM",
"LICENSE": "MIT",
"HOMEPAGE": "https://example.invalid",
"GPG_PRIVATE_KEY_FILE": "/not/needed/until-nfpm-signs",
}
subprocess.run(
["bash", str(ROOT / "scripts/prepare-package.sh"), str(cls.src),
str(cls.work / "package"), str(cls.work / "server")],
env=cls.env, check=True, capture_output=True, text=True,
)
subprocess.run(
["bash", str(ROOT / "scripts/prepare-agent-package.sh"), str(cls.src),
str(cls.work / "package-agent"), str(cls.work / "agent")],
env=cls.env, check=True, capture_output=True, text=True,
)
@classmethod
def tearDownClass(cls):
cls.tmp.cleanup()
def test_suse_rpm_has_native_dependencies_and_paths(self):
contents = (self.work / "package/nfpm-suse.yaml").read_text()
self.assertIn(" - shadow\n", contents)
self.assertIn(" - 'glibc >= 2.34'", contents)
self.assertNotIn("shadow-utils", contents)
self.assertIn("(python311 and python311-pip)", contents)
self.assertIn("/usr/libexec/rustproxy/python3", contents)
self.assertIn("50-suse-python.conf", contents)
self.assertIn("compression: gzip", contents)
self.assertIn("key_file:", contents)
self.assertTrue((self.work / "package/payload/usr/lib/systemd/system/rustproxy.service.d/50-suse-python.conf").exists())
self.assertIn("/usr/libexec/rustproxy", (self.work / "package/payload/usr/lib/systemd/system/rustproxy.service.d/50-suse-python.conf").read_text())
def test_suse_agent_has_native_dependencies(self):
contents = (self.work / "package-agent/nfpm-suse.yaml").read_text()
self.assertIn(" - shadow\n", contents)
self.assertNotIn("shadow-utils", contents)
self.assertIn("compression: gzip", contents)
self.assertIn("name: \"rustproxy-docker-agent\"", contents)
self.assertIn("/usr/lib/systemd/system/rustproxy-docker-agent.service", contents)
def test_suse_python_launcher(self):
wrapper = self.work / "package/payload/usr/libexec/rustproxy/python3"
result = subprocess.run([str(wrapper), "-c", "import sys; print(sys.version_info.major)"],
capture_output=True, text=True, timeout=5)
# Builder test machine has Python 3; a host without Python >=3.10
# will deliberately fail the wrapper rather than run obsolete Python.
if result.returncode == 0:
self.assertEqual(result.stdout.strip(), "3")
else:
self.assertIn("Python 3.10", result.stderr)
class SuseCatalogTests(unittest.TestCase):
def setUp(self):
spec = importlib.util.spec_from_file_location("rustproxy_dashboard", ROOT / "dashboard/app.py")
self.assertIsNotNone(spec)
self.api = importlib.util.module_from_spec(spec)
spec.loader.exec_module(self.api)
self.tmp = tempfile.TemporaryDirectory()
self.addCleanup(self.tmp.cleanup)
self.repo = Path(self.tmp.name) / "repository"
release = self.repo / "releases" / "new"
(release / "suse/x86_64/repodata").mkdir(parents=True)
(release / "suse/x86_64/repodata/repomd.xml").write_text("<repomd/>")
(release / "suse/x86_64/rustproxy-0.99.1-7.x86_64.rpm").write_bytes(b"rpm-test")
(release / "suse/x86_64/rustproxy-docker-agent-0.99.1-7.x86_64.rpm").write_bytes(b"rpm-test")
(release / "SUSE-BUILD-INFO.txt").write_text(
"app_version=0.99.1\npackage_release=7\n"
"built_at=2026-10-22T12:00:00Z\nsource_commit=abcdef123456\n"
)
(self.repo / "current").symlink_to("releases/new")
self.release = release
def test_catalog_publishes_suse_packages_only_in_suse_channel(self):
catalog = self.api.generate_catalog(self.repo)
self.assertTrue(catalog["builds"]["suse"]["published"])
self.assertEqual(catalog["builds"]["suse"]["package_version"], "0.99.1-7")
suse_pkgs = [p for p in catalog["packages"] if p["channel"] == "suse"]
self.assertEqual(len(suse_pkgs), 2)
self.assertTrue(all(p["format"] == "RPM" for p in suse_pkgs))
self.assertTrue(all(p["download_url"].endswith(".x86_64.rpm") for p in suse_pkgs))
self.assertTrue(all("/suse/x86_64/" in p["download_url"] for p in suse_pkgs))
self.assertEqual(catalog["summary"]["channel_counts"]["suse"], 2)
def test_old_build_does_not_fake_suse_publication(self):
(self.release / "SUSE-BUILD-INFO.txt").unlink()
catalog = self.api.generate_catalog(self.repo)
self.assertFalse(catalog["builds"]["suse"]["published"])
if __name__ == "__main__":
unittest.main()