Record the finite dependency search, Wi-Fi maintenance blocker, and pinned icon provenance. Add bounded host orchestration and fixture coverage, and update release documentation with current evidence.
85 lines
3.2 KiB
Python
85 lines
3.2 KiB
Python
#!/usr/bin/env python3
|
|
# SPDX-License-Identifier: GPL-3.0-only
|
|
"""Assemble two real bundles in temporary directories and verify every byte."""
|
|
|
|
import argparse
|
|
import hashlib
|
|
import json
|
|
from pathlib import Path
|
|
import subprocess
|
|
import sys
|
|
import tempfile
|
|
|
|
PROJECT = Path(__file__).absolute().parents[2]
|
|
|
|
|
|
def contents(root):
|
|
return {p.relative_to(root).as_posix(): p.read_bytes()
|
|
for p in root.rglob("*") if p.is_file()}
|
|
|
|
|
|
def validate(files, catalog_data):
|
|
manifest = json.loads(files["manifest.json"])
|
|
catalog = json.loads(catalog_data)
|
|
assert manifest["catalog_sha256"] == hashlib.sha256(catalog_data).hexdigest()
|
|
assert manifest["snapshot"] == catalog["snapshot"]
|
|
assert len(manifest["inputs"]) == len(catalog["inputs"])
|
|
expected_entries = {(x["root"], x["path"]): x for x in catalog["inputs"]}
|
|
expected_files = {"manifest.json"}
|
|
seen = set()
|
|
for entry in manifest["inputs"]:
|
|
key = (entry["root"], entry["path"])
|
|
assert key not in seen
|
|
seen.add(key)
|
|
original = expected_entries[key]
|
|
assert {k: entry[k] for k in original} == original
|
|
path = "inputs/" + entry["root"] + "/" + entry["path"]
|
|
if entry["range"] is not None:
|
|
path += ".notice.txt"
|
|
assert entry["output"] == path
|
|
expected_files.add(path)
|
|
data = files[path]
|
|
assert len(data) == entry["output_size"]
|
|
assert hashlib.sha256(data).hexdigest() == entry["output_sha256"]
|
|
assert seen == set(expected_entries)
|
|
assert len(manifest["generated"]) == 1
|
|
assert manifest["generated"][0]["path"] == "README.txt"
|
|
for entry in manifest["generated"]:
|
|
expected_files.add(entry["path"])
|
|
data = files[entry["path"]]
|
|
assert len(data) == entry["size"]
|
|
assert hashlib.sha256(data).hexdigest() == entry["sha256"]
|
|
assert set(files) == expected_files, "unexpected or missing bundle files"
|
|
return len(manifest["inputs"])
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description=__doc__)
|
|
parser.add_argument("--sdk-root", type=Path, required=True)
|
|
parser.add_argument("--toolchain-root", type=Path, required=True)
|
|
args = parser.parse_args()
|
|
catalog = (PROJECT / "third_party/release-notices/inputs.json").read_bytes()
|
|
with tempfile.TemporaryDirectory(prefix="actual-release-notices-") as temporary:
|
|
base = Path(temporary)
|
|
outputs = []
|
|
for name in ("first", "second"):
|
|
output = base / name
|
|
subprocess.run([
|
|
sys.executable, str(PROJECT / "tools/release_notices.py"),
|
|
"--sdk-root", str(args.sdk_root),
|
|
"--toolchain-root", str(args.toolchain_root), "--output", str(output),
|
|
], check=True, timeout=60)
|
|
files = contents(output)
|
|
count = validate(files, catalog)
|
|
outputs.append(files)
|
|
assert outputs[0] == outputs[1], "bundle names/bytes differ"
|
|
files = outputs[0]
|
|
print(f"PASS: two actual bundles; {count} inputs; {len(files)} files; "
|
|
f"{sum(map(len, files.values()))} bytes; all payloads verified and deterministic")
|
|
print("manifest SHA-256:", hashlib.sha256(files["manifest.json"]).hexdigest())
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|