Files
govoplan/tests/test_runtime_distribution_build.py
T
zemion ff8ee991c3
Dependency Audit / dependency-audit (push) Successful in 1m45s
Deployment Installer / deployment-installer (push) Successful in 6s
Security Audit / security-audit (push) Successful in 10m49s
Harden runtime distribution acceptance
2026-08-03 17:32:52 +02:00

202 lines
7.4 KiB
Python

from __future__ import annotations
import argparse
import importlib.util
import json
import os
from pathlib import Path
import shutil
import sys
import tempfile
import unittest
ROOT = Path(__file__).resolve().parents[1]
def _load(name: str, path: Path):
spec = importlib.util.spec_from_file_location(name, path)
assert spec is not None and spec.loader is not None
module = importlib.util.module_from_spec(spec)
sys.modules[name] = module
spec.loader.exec_module(module)
return module
OCI = _load("resolve_oci_platforms", ROOT / "tools/release/resolve-oci-platforms.py")
FINALIZE = _load(
"finalize_runtime_distribution",
ROOT / "tools/release/finalize-runtime-distribution.py",
)
DEPLOYER_BUILD = _load(
"build_deployer_zipapp",
ROOT / "tools/deployment/build-deployer-zipapp.py",
)
class RuntimeDistributionBuildTests(unittest.TestCase):
def test_deployment_zipapp_is_reproducible_across_source_mtimes(self) -> None:
with tempfile.TemporaryDirectory(prefix="govoplan-reproducible-zipapp-") as value:
root = Path(value)
source = root / "source"
shutil.copytree(ROOT / "tools/deployment", source)
first = root / "first.pyz"
second = root / "second.pyz"
original_root = DEPLOYER_BUILD.ROOT
try:
DEPLOYER_BUILD.ROOT = source
self.assertEqual(0, DEPLOYER_BUILD.main(["--output", str(first)]))
for path in source.rglob("*.py"):
os.utime(path, (2_000_000_000, 2_000_000_000))
self.assertEqual(0, DEPLOYER_BUILD.main(["--output", str(second)]))
finally:
DEPLOYER_BUILD.ROOT = original_root
self.assertEqual(first.read_bytes(), second.read_bytes())
def test_workflow_signs_with_the_release_environment(self) -> None:
workflow = (ROOT / ".gitea/workflows/runtime-distribution.yml").read_text(
encoding="utf-8"
)
self.assertIn(
".runtime-build/bin/python tools/release/generate-runtime-distribution.py",
workflow,
)
self.assertNotIn(
"\n python tools/release/generate-runtime-distribution.py",
workflow,
)
def test_workflow_verifies_portable_bootstrap_artifacts_before_execution(
self,
) -> None:
workflow = (ROOT / ".gitea/workflows/runtime-distribution.yml").read_text(
encoding="utf-8"
)
self.assertIn(
"(cd runtime-output && sha256sum govoplan-deploy.pyz > "
"govoplan-deploy.pyz.sha256)",
workflow,
)
self.assertIn("openssl pkeyutl -verify -pubin", workflow)
self.assertIn("govoplan-deploy.tampered.pyz", workflow)
self.assertLess(
workflow.index("openssl pkeyutl -verify -pubin"),
workflow.index("python runtime-output/govoplan-deploy.pyz init"),
)
def test_workflow_retains_both_platform_runtime_smoke_receipts(self) -> None:
workflow = (ROOT / ".gitea/workflows/runtime-distribution.yml").read_text(
encoding="utf-8"
)
self.assertIn('for ARCH in amd64 arm64; do', workflow)
self.assertIn("tools/checks/runtime-image-smoke.py", workflow)
self.assertIn("runtime-smoke-amd64.json", workflow)
self.assertIn("runtime-smoke-arm64.json", workflow)
def test_resolves_platforms_and_builds_evidence_descriptor(self) -> None:
index = {
"schemaVersion": 2,
"manifests": [
{
"digest": "sha256:" + "1" * 64,
"platform": {"os": "linux", "architecture": "amd64"},
},
{
"digest": "sha256:" + "2" * 64,
"platform": {"os": "linux", "architecture": "arm64"},
},
],
}
metadata = OCI.resolve_platforms(
index,
repository="registry.example/govoplan/api",
index_digest="sha256:" + "a" * 64,
)
self.assertEqual(
"registry.example/govoplan/api@sha256:" + "1" * 64,
metadata["platforms"]["linux/amd64"],
)
with tempfile.TemporaryDirectory(prefix="govoplan-runtime-finalize-") as value:
root = Path(value)
composition = {
"schema_version": "1",
"python": {
"packages": [
{
"package": "govoplan-core",
"version": "1.2.3",
"sha256": "8" * 64,
}
],
"module_ids": ["access"],
"wheelhouse_sha256": "9" * 64,
"wheel_count": 1,
},
"web": {"sha256": "7" * 64, "file_count": 4},
}
(root / "composition.json").write_text(json.dumps(composition))
(root / "api.json").write_text(json.dumps(metadata))
web_metadata = {
"index": "registry.example/govoplan/web@sha256:" + "b" * 64,
"platforms": {
"linux/amd64": "registry.example/govoplan/web@sha256:" + "3" * 64,
"linux/arm64": "registry.example/govoplan/web@sha256:" + "4" * 64,
},
}
(root / "web.json").write_text(json.dumps(web_metadata))
deployer = root / "govoplan-deploy.pyz"
deployer.write_bytes(b"zipapp")
args = argparse.Namespace(
composition=root / "composition.json",
api_metadata=root / "api.json",
web_metadata=root / "web.json",
deployer=deployer,
deployer_url="https://downloads.example/govoplan-deploy.pyz",
artifact_base_url="https://downloads.example/runtime/v1.2.3",
source_commit="f" * 40,
version="1.2.3",
channel="stable",
sequence=1,
expires_days=30,
dependency=[
"postgres=docker.io/library/postgres@sha256:" + "5" * 64,
"redis=docker.io/library/redis@sha256:" + "6" * 64,
],
output_directory=root / "evidence",
descriptor=root / "descriptor.json",
)
descriptor = FINALIZE.finalize(args)
self.assertEqual(["access"], descriptor["composition"]["module_ids"])
self.assertEqual(
"registry.example/govoplan/api@sha256:" + "a" * 64,
descriptor["images"]["api"]["index"],
)
self.assertTrue((root / "evidence/api-sbom.cdx.json").is_file())
self.assertTrue((root / "evidence/web-provenance.json").is_file())
def test_rejects_incomplete_oci_index(self) -> None:
with self.assertRaisesRegex(ValueError, "linux/amd64 and linux/arm64"):
OCI.resolve_platforms(
{
"manifests": [
{
"digest": "sha256:" + "1" * 64,
"platform": {"os": "linux", "architecture": "amd64"},
}
]
},
repository="registry.example/govoplan/api",
index_digest="sha256:" + "a" * 64,
)
if __name__ == "__main__":
unittest.main()