|
1 | 1 | from __future__ import annotations
|
2 | 2 |
|
3 | 3 | import io
|
| 4 | +import json |
4 | 5 | import logging
|
5 | 6 | import os
|
6 | 7 | import re
|
@@ -506,6 +507,97 @@ def test_numpy(self, anylinux: AnyLinuxContainer, python: PythonContainer) -> No
|
506 | 507 | # at once in the same Python program:
|
507 | 508 | python.run("import numpy; import foo")
|
508 | 509 |
|
| 510 | + def test_numpy_sbom( |
| 511 | + self, anylinux: AnyLinuxContainer, python: PythonContainer |
| 512 | + ) -> None: |
| 513 | + policy = anylinux.policy |
| 514 | + |
| 515 | + # Build and repair numpy |
| 516 | + orig_wheel = build_numpy(anylinux, anylinux.io_folder) |
| 517 | + assert orig_wheel == ORIGINAL_NUMPY_WHEEL |
| 518 | + assert "manylinux" not in orig_wheel |
| 519 | + |
| 520 | + # Repair the wheel using the manylinux container |
| 521 | + anylinux.repair(orig_wheel) |
| 522 | + repaired_wheel = anylinux.check_wheel("numpy", version=NUMPY_VERSION) |
| 523 | + assert_show_output(anylinux, repaired_wheel, policy, False) |
| 524 | + |
| 525 | + # Install the wheel so the SBOM document is added to the environment. |
| 526 | + python.install_wheel(repaired_wheel) |
| 527 | + |
| 528 | + # Load the auditwheel SBOM from .dist-info/sboms |
| 529 | + site_packages = python.run( |
| 530 | + "import site; print(site.getsitepackages()[0])" |
| 531 | + ).strip() |
| 532 | + assert re.match( |
| 533 | + r"\A/usr/local/lib/python[0-9.]+/site-packages\Z", site_packages |
| 534 | + ) |
| 535 | + sbom_data = python.run( |
| 536 | + f"-c \"print(open('{site_packages}/numpy-{NUMPY_VERSION}.dist-info/sboms/auditwheel.cdx.json').read())\"" |
| 537 | + ).strip() |
| 538 | + sbom = json.loads(sbom_data) |
| 539 | + |
| 540 | + # Separate all the components that vary over test runs. |
| 541 | + sbom_tools = sbom["metadata"].pop("tools") |
| 542 | + sbom_components = sbom.pop("components") |
| 543 | + sbom_dependencies = sbom.pop("dependencies") |
| 544 | + |
| 545 | + assert sbom == { |
| 546 | + "bomFormat": "CycloneDX", |
| 547 | + "specVersion": "1.4", |
| 548 | + "version": 1, |
| 549 | + "metadata": { |
| 550 | + "component": { |
| 551 | + "type": "library", |
| 552 | + "bom-ref": f"pkg:pypi/numpy@{NUMPY_VERSION}", |
| 553 | + "name": "numpy", |
| 554 | + "version": NUMPY_VERSION, |
| 555 | + "purl": f"pkg:pypi/numpy@{NUMPY_VERSION}", |
| 556 | + }, |
| 557 | + # "tools": [{...}, ...], |
| 558 | + }, |
| 559 | + # "components": [{...}, ...], |
| 560 | + # "dependencies": [{...}, ...], |
| 561 | + } |
| 562 | + |
| 563 | + assert len(sbom_tools) == 1 |
| 564 | + assert sbom_tools[0]["name"] == "auditwheel" |
| 565 | + assert "version" in sbom_tools[0] |
| 566 | + |
| 567 | + assert sbom_components[0] == { |
| 568 | + "bom-ref": f"pkg:pypi/numpy@{NUMPY_VERSION}", |
| 569 | + "name": "numpy", |
| 570 | + "purl": f"pkg:pypi/numpy@{NUMPY_VERSION}", |
| 571 | + "type": "library", |
| 572 | + "version": NUMPY_VERSION, |
| 573 | + } |
| 574 | + |
| 575 | + component_purls = { |
| 576 | + component["purl"].split("@")[0] for component in sbom_components[1:] |
| 577 | + } |
| 578 | + if policy.startswith("musllinux"): |
| 579 | + assert component_purls == { |
| 580 | + "pkg:apk/alpine/libgcc", |
| 581 | + "pkg:apk/alpine/libgfortran", |
| 582 | + "pkg:apk/alpine/libquadmath", |
| 583 | + "pkg:apk/alpine/libstdc%2B%2B", |
| 584 | + "pkg:apk/alpine/openblas", |
| 585 | + } |
| 586 | + elif policy == "manylinux_2_34_x86_64": |
| 587 | + assert component_purls == { |
| 588 | + "pkg:rpm/almalinux/libgfortran", |
| 589 | + "pkg:rpm/almalinux/libquadmath", |
| 590 | + "pkg:rpm/almalinux/openblas-serial", |
| 591 | + } |
| 592 | + else: |
| 593 | + assert component_purls == { |
| 594 | + "pkg:rpm/almalinux/libgfortran", |
| 595 | + "pkg:rpm/almalinux/libquadmath", |
| 596 | + "pkg:rpm/almalinux/openblas", |
| 597 | + } |
| 598 | + |
| 599 | + assert len(sbom_dependencies) == len(component_purls) + 1 |
| 600 | + |
509 | 601 | def test_exclude(self, anylinux: AnyLinuxContainer) -> None:
|
510 | 602 | """Test the --exclude argument to avoid grafting certain libraries."""
|
511 | 603 | test_path = "/auditwheel_src/tests/integration/testrpath"
|
|
0 commit comments