Ctrl K
ComunidadGuías…

scripts/test_m2image_compliance.py

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
#!/usr/bin/env python3
import importlib.util
import json
import tempfile
import unittest
from pathlib import Path

MODULE_PATH = Path(__file__).with_name("m2image_compliance.py")
spec = importlib.util.spec_from_file_location("m2image_compliance", MODULE_PATH)
assert spec and spec.loader
compliance = importlib.util.module_from_spec(spec)
spec.loader.exec_module(compliance)


def spdx(packages, distribution="alpine"):
    return {
        "spdxVersion": "SPDX-2.3",
        "packages": [
            {
                "name": f"{distribution}-image",
                "versionInfo": "1",
                "comment": f"distribution={distribution}; architecture=x86_64",
            },
            *packages,
        ],
    }


class M2ImageComplianceTests(unittest.TestCase):
    def test_source_map_requires_source_identity(self):
        doc = spdx([{"name": "busybox", "versionInfo": "1.37.0-r31"}])
        with self.assertRaisesRegex(ValueError, "missing source-package identity"):
            compliance.source_map(doc)

    def test_source_map_records_exact_alpine_commit(self):
        doc = spdx(
            [
                {
                    "name": "busybox",
                    "versionInfo": "1.37.0-r31",
                    "comment": (
                        "package-manager-license=GPL-2.0-only; source-package=busybox; "
                        "source-version=1.37.0-r31; "
                        "source-commit=0123456789abcdef0123456789abcdef01234567"
                    ),
                }
            ]
        )
        mapped = compliance.source_map(doc)["packages"][0]
        self.assertEqual(mapped["declaredLicense"], "GPL-2.0-only")
        self.assertEqual(mapped["source"]["sourcePackage"], "busybox")
        self.assertEqual(mapped["source"]["sourceVersion"], "1.37.0-r31")
        self.assertEqual(
            mapped["source"]["repositoryCommit"],
            "0123456789abcdef0123456789abcdef01234567",
        )
        self.assertTrue(mapped["source"]["metadataUrl"].endswith("0123456789abcdef0123456789abcdef01234567"))

    def test_source_map_preserves_binary_package_architecture_from_purl(self):
        doc = spdx(
            [
                {
                    "name": "filesystem",
                    "versionInfo": "3.16-5.el9",
                    "externalRefs": [
                        {
                            "referenceCategory": "PACKAGE_MANAGER",
                            "referenceType": "purl",
                            "referenceLocator": "pkg:rpm/rocky/filesystem@3.16-5.el9?arch=noarch",
                        }
                    ],
                    "comment": "source-package=filesystem-3.16-5.el9.src.rpm",
                }
            ],
            distribution="rocky",
        )
        result = compliance.source_map(doc)
        self.assertEqual(result["image"]["architecture"], "x86_64")
        self.assertEqual(result["packages"][0]["architecture"], "noarch")

    def test_ubuntu_and_rocky_resolvers_preserve_source_evidence(self):
        ubuntu = {
            "spdxVersion": "SPDX-2.3",
            "packages": [
                {
                    "name": "ubuntu-26.04",
                    "versionInfo": "26.04",
                    "comment": "distribution=ubuntu; architecture=x86_64",
                },
                {
                    "name": "linux-image-virtual",
                    "versionInfo": "7.0.0-30.30",
                    "comment": "source-package=linux-meta; source-version=7.0.0.30.30",
                },
            ],
        }
        rocky = {
            "spdxVersion": "SPDX-2.3",
            "packages": [
                {
                    "name": "rocky-9.8",
                    "versionInfo": "9.8",
                    "comment": "distribution=rocky; architecture=x86_64",
                },
                {
                    "name": "kernel-core",
                    "versionInfo": "0:5.14.0-687.41.1.el9_8",
                    "comment": "source-package=kernel-5.14.0-687.41.1.el9_8.src.rpm",
                },
            ],
        }
        ubuntu_source = compliance.source_map(ubuntu)["packages"][0]["source"]
        rocky_source = compliance.source_map(rocky)["packages"][0]["source"]
        self.assertEqual(ubuntu_source["sourcePackage"], "linux-meta")
        self.assertEqual(ubuntu_source["sourceVersion"], "7.0.0.30.30")
        self.assertIn("launchpad.net/ubuntu/+source/linux-meta/", ubuntu_source["metadataUrl"])
        self.assertEqual(
            rocky_source["sourceArtifact"],
            "kernel-5.14.0-687.41.1.el9_8.src.rpm",
        )

    def test_rocky_gpg_pubkey_records_explicit_non_source_disposition(self):
        doc = spdx(
            [
                {
                    "name": "gpg-pubkey",
                    "versionInfo": "0:350d275d-627e00a1",
                    "comment": "source-disposition=rpm-key-metadata",
                }
            ],
            distribution="rocky",
        )
        mapped = compliance.source_map(doc)["packages"][0]
        self.assertEqual(mapped["sourceDisposition"], "rpm-key-metadata")
        self.assertNotIn("source", mapped)

    def test_non_source_disposition_is_narrowly_scoped(self):
        doc = spdx(
            [
                {
                    "name": "bash",
                    "versionInfo": "5.1",
                    "comment": "source-disposition=rpm-key-metadata",
                }
            ],
            distribution="rocky",
        )
        with self.assertRaisesRegex(ValueError, "unsupported source-disposition"):
            compliance.source_map(doc)

    def test_bundle_copies_guest_legal_material_and_canonical_gpl(self):
        with tempfile.TemporaryDirectory() as tmpdir:
            tmp = Path(tmpdir)
            legal = tmp / "guest"
            (legal / "usr/share/licenses/busybox").mkdir(parents=True)
            (legal / "usr/share/licenses/busybox/COPYING").write_text("guest gpl\n")
            (legal / "usr/share/doc/curl").mkdir(parents=True)
            (legal / "usr/share/doc/curl/copyright").write_text("curl notice\n")
            (legal / "usr/share/doc/curl/changelog.gz").write_bytes(b"not legal evidence")
            gpl = tmp / "GPL-2.0-only.txt"
            gpl.write_text("canonical gpl\n")
            sbom_path = tmp / "sbom.json"
            sbom_path.write_text(
                json.dumps(
                    spdx(
                        [
                            {
                                "name": "busybox",
                                "versionInfo": "1.37.0-r31",
                                "comment": "package-manager-license=GPL-2.0-only; source-package=busybox",
                            }
                        ]
                    )
                )
            )
            out = tmp / "bundle"
            summary = compliance.build_bundle(
                spdx_path=sbom_path,
                legal_root=legal,
                gpl2_text=gpl,
                output_dir=out,
            )
            self.assertEqual(summary["packageCount"], 1)
            self.assertEqual(summary["guestLegalFileCount"], 2)
            self.assertTrue((out / "licenses/GPL-2.0-only.txt").is_file())
            self.assertTrue((out / "licenses/guest/usr/share/licenses/busybox/COPYING").is_file())
            self.assertTrue((out / "licenses/guest/usr/share/doc/curl/copyright").is_file())
            self.assertFalse((out / "licenses/guest/usr/share/doc/curl/changelog.gz").exists())
            index = json.loads((out / "licenses/index.json").read_text())
            self.assertEqual(len(index["files"]), 3)
            self.assertTrue(all(item["sha256"] for item in index["files"]))
            self.assertEqual(
                (out / "sbom.spdx.json").read_bytes(), sbom_path.read_bytes()
            )

    def test_bundle_is_deterministic_for_same_inputs(self):
        with tempfile.TemporaryDirectory() as tmpdir:
            tmp = Path(tmpdir)
            legal = tmp / "guest"
            (legal / "usr/share/common-licenses").mkdir(parents=True)
            (legal / "usr/share/common-licenses/GPL-2").write_text("gpl common\n")
            gpl = tmp / "GPL.txt"
            gpl.write_text("canonical\n")
            sbom_path = tmp / "sbom.json"
            sbom_path.write_text(
                json.dumps(
                    spdx(
                        [
                            {
                                "name": "busybox",
                                "versionInfo": "1",
                                "comment": "source-package=busybox",
                            }
                        ]
                    ),
                    sort_keys=True,
                )
            )
            first = tmp / "first"
            second = tmp / "second"
            compliance.build_bundle(
                spdx_path=sbom_path, legal_root=legal, gpl2_text=gpl, output_dir=first
            )
            compliance.build_bundle(
                spdx_path=sbom_path, legal_root=legal, gpl2_text=gpl, output_dir=second
            )
            for rel in ("bundle.json", "source-map.json", "licenses/index.json", "README.txt"):
                self.assertEqual((first / rel).read_bytes(), (second / rel).read_bytes())


if __name__ == "__main__":
    unittest.main()