from __future__ import annotations import argparse import importlib.util import json from pathlib import Path 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", ) class RuntimeDistributionBuildTests(unittest.TestCase): 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()