| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 |
- from __future__ import annotations
- import hashlib
- import json
- from pathlib import Path
- from jsonschema import Draft7Validator
- from referencing import Registry, Resource
- ROOT = Path(__file__).resolve().parents[1]
- SBOM = ROOT / "docs" / "security" / "data-rule-runtime-sbom.json"
- SCHEMAS = ROOT / "docs" / "security" / "cyclonedx-1.5-schema"
- def _load(name: str):
- return json.loads((SCHEMAS / name).read_text(encoding="utf-8"))
- def test_data_rule_runtime_sbom_validates_against_cyclonedx_15_schema():
- expected_schema_digests = {
- "bom-1.5.schema.json": (
- "a00fcba23a44b72179ac1f288be4c3529"
- "b59f6e1b3719709a40685f177516b46"
- ),
- "spdx.schema.json": (
- "c87aa7bb5eb503d40b52ec6bf00de8045"
- "df15da7a13cea48d290cf6d36a8d2ea"
- ),
- "jsf-0.82.schema.json": (
- "2faf5eb3651f2ae5f46091a131770d8d8"
- "47bbd121139d19c85fc7051bfa58c46"
- ),
- }
- for name, expected in expected_schema_digests.items():
- assert hashlib.sha256((SCHEMAS / name).read_bytes()).hexdigest() == (
- expected
- )
- document = json.loads(SBOM.read_text(encoding="utf-8"))
- schema = _load("bom-1.5.schema.json")
- registry = Registry().with_resources(
- [
- (
- "http://cyclonedx.org/schema/spdx.schema.json",
- Resource.from_contents(_load("spdx.schema.json")),
- ),
- (
- "http://cyclonedx.org/schema/jsf-0.82.schema.json",
- Resource.from_contents(_load("jsf-0.82.schema.json")),
- ),
- ]
- )
- Draft7Validator.check_schema(schema)
- errors = sorted(
- Draft7Validator(
- schema,
- registry=registry,
- ).iter_errors(document),
- key=lambda error: list(error.absolute_path),
- )
- assert errors == []
- def test_data_rule_runtime_sbom_pins_official_oss_dependencies():
- document = json.loads(SBOM.read_text(encoding="utf-8"))
- components = {
- component["name"]: component
- for component in document["components"]
- }
- assert document["bomFormat"] == "CycloneDX"
- assert document["specVersion"] == "1.5"
- assert set(components) == {
- "minio",
- "polars",
- "polars-runtime-32",
- "psutil",
- "pyarrow",
- }
- for name, version, license_id, source in (
- (
- "polars",
- "1.42.1",
- "MIT",
- "https://github.com/pola-rs/polars",
- ),
- (
- "polars-runtime-32",
- "1.42.1",
- "MIT",
- "https://github.com/pola-rs/polars",
- ),
- (
- "pyarrow",
- "21.0.0",
- "Apache-2.0",
- "https://github.com/apache/arrow",
- ),
- (
- "psutil",
- "5.9.8",
- "BSD-3-Clause",
- "https://github.com/giampaolo/psutil",
- ),
- (
- "minio",
- "7.2.10",
- "Apache-2.0",
- "https://github.com/minio/minio-py",
- ),
- ):
- component = components[name]
- assert component["version"] == version
- assert component["licenses"] == [
- {"license": {"id": license_id}}
- ]
- assert component["externalReferences"] == [
- {"type": "vcs", "url": source}
- ]
- assert component["properties"][0]["name"] == "dataops:purpose"
- assert not {"license", "officialSource", "purpose"} & set(component)
- requirements = (ROOT / "requirements.txt").read_text(encoding="utf-8")
- for requirement in (
- "polars==1.42.1",
- "pyarrow==21.0.0",
- "psutil==5.9.8",
- "minio==7.2.10",
- ):
- assert requirement in requirements
|