Something went wrong. Try again.
Hardware-in-the-loop development platform for the Commodore 64.
Something went wrong. Try again.
44 kB · 847 lines
Python
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848#!/usr/bin/env python3"""Tests for the shipped-documentation link checker and the doc mapping.
These tests are pure standard-library ``unittest`` and need no compiler, nonetwork, and no hardware. They exercise ``tools/check_distribution_docs.py`` andthe packager's distribution-document mapping in ``tools/package_release.py``:
- the checker's heading-anchor rules, including that a heading inside a fenced code block is not an anchor,- that every relative link and anchor in the documentation the release ships resolves inside both archives, checked against the packager's own membership resolver and against a real archive extracted from real bytes,- that a withheld repository document ships only as its reviewed sanitized copy, at the archive path the original occupies, and never as its withheld bytes,- that the packager refuses a copy whose recorded hash no longer matches and a mapping whose archive path is not denied.
What a passing run does not prove: that the wording of any document is corrector reviewed, or that the archives were built from the current checkout."""
from __future__ import annotations
import argparseimport hashlibimport jsonimport osimport sysimport tempfileimport unittestfrom pathlib import Path
ROOT = Path(__file__).resolve().parents[2]TOOLS = ROOT / "tools"if str(TOOLS) not in sys.path: sys.path.insert(0, str(TOOLS))
import check_distribution_docs as checker # noqa: E402import package_release as packaging # noqa: E402
MANIFEST_PATH = TOOLS / "release_source_manifest.json"MAPPED_DOCS = { "docs/ARCHITECTURE.md": "tools/release-docs/ARCHITECTURE.md", "docs/BUILD_ANALYSIS.md": "tools/release-docs/BUILD_ANALYSIS.md", "docs/CHECKPOINT_COMPARISON.md": "tools/release-docs/CHECKPOINT_COMPARISON.md", "docs/HTTP_API.md": "tools/release-docs/HTTP_API.md", "docs/MCP.md": "tools/release-docs/MCP.md", "docs/PORTABILITY.md": "tools/release-docs/PORTABILITY.md",}
def manifest() -> dict: return packaging.load_source_manifest(MANIFEST_PATH)
def distribution_doc_entries() -> list[dict]: """The resolved distribution-document entries the real manifest records.""" return [ { "archive_path": record["archive_path"], "copy": record["copy"], "origin": record["origin"], "size": record["size"], "sha256": record["sha256"], } for record in packaging.distribution_doc_members(ROOT, manifest()) ]
class HeadingAnchorTests(unittest.TestCase): def test_slug_matches_github_rules(self) -> None: self.assertEqual(checker.heading_id("Strict physical gate"), "strict-physical-gate") self.assertEqual(checker.heading_id("What a comparison does and does not say"), "what-a-comparison-does-and-does-not-say") self.assertEqual(checker.heading_id("`Target` trait"), "target-trait") self.assertEqual(checker.heading_id("Run bus timeline"), "run-bus-timeline")
def test_heading_inside_a_fence_is_not_an_anchor(self) -> None: text = "# Real\n\n```md\n## Fenced heading\n```\n\n~~~\n### Tilde fenced\n~~~\n" found = checker.anchors(text) self.assertIn("real", found) self.assertNotIn("fenced-heading", found) self.assertNotIn("tilde-fenced", found)
def test_relative_links_ignore_external_and_absolute(self) -> None: text = ( "[a](https://example.com/x.md) [b](mailto:a@b) [c](#local) " "[d](/absolute) [e](SIBLING.md#anchor \"title\") [f](../up.md)\n" ) self.assertEqual( checker.relative_links(text), [("SIBLING.md", "anchor"), ("../up.md", "")], )
def test_broken_anchor_and_escaping_link_are_reported(self) -> None: names = {"docs/A.md", "docs/B.md"} documents = { "docs/A.md": "# A\n\n[ok](B.md#b-anchor)\n[bad](B.md#missing)\n[escape](../../outside.md)\n", "docs/B.md": "# B\n\n## B anchor\n", } problems = checker.check_documents("test", names, documents) self.assertEqual(len(problems), 2) self.assertTrue(any("missing" in item for item in problems)) self.assertTrue(any("escapes the archive root" in item for item in problems))
def test_missing_target_is_reported(self) -> None: problems = checker.check_documents("test", {"docs/A.md"}, {"docs/A.md": "[gone](GONE.md)\n"}) self.assertEqual(len(problems), 1) self.assertIn("not an archive member", problems[0])
class ManifestMappingTests(unittest.TestCase): def test_mapping_matches_the_reviewed_copies(self) -> None: mapping = packaging.distribution_doc_mapping(manifest()) self.assertEqual(mapping, {path: mapping[path] for path in mapping}) self.assertEqual({path: mapping[path]["copy"] for path in mapping}, MAPPED_DOCS)
def test_every_mapped_copy_exists_and_matches_its_recorded_hash(self) -> None: package = manifest() records = packaging.distribution_doc_members(ROOT, package) self.assertEqual({record["archive_path"] for record in records}, set(MAPPED_DOCS)) for record in records: actual = hashlib.sha256((ROOT / record["copy"]).read_bytes()).hexdigest() self.assertEqual(record["sha256"], actual, record["copy"]) self.assertEqual(record["sha256"], packaging.distribution_doc_mapping(package)[record["archive_path"]]["sha256"])
def test_every_mapped_archive_path_is_denied_and_shipped(self) -> None: package = manifest() denied = {entry["path"] for entry in package["source_paths"]["deny"]} shipped = set(package["package_layout"]["shipped_docs"]) for archive_path in MAPPED_DOCS: self.assertIn(archive_path, denied) self.assertIn(archive_path, shipped)
def test_stale_recorded_hash_is_refused(self) -> None: package = manifest() package["package_layout"]["distribution_docs"]["entries"][0]["sha256"] = "0" * 64 with self.assertRaises(packaging.CheckFailure): packaging.distribution_doc_members(ROOT, package)
def test_archive_path_that_is_not_denied_is_refused(self) -> None: package = json.loads(json.dumps(manifest())) package["source_paths"]["deny"] = [ entry for entry in package["source_paths"]["deny"] if entry["path"] != "docs/MCP.md" ] with self.assertRaises(packaging.CheckFailure): packaging.distribution_doc_members(ROOT, package)
def test_withheld_original_never_supplies_the_shipped_bytes(self) -> None: package = manifest() with tempfile.TemporaryDirectory() as directory: root = Path(directory) for entry in package["package_layout"]["distribution_docs"]["entries"]: copy = root / entry["copy"] copy.parent.mkdir(parents=True, exist_ok=True) copy.write_bytes((ROOT / entry["copy"]).read_bytes()) withheld = root / entry["archive_path"] withheld.parent.mkdir(parents=True, exist_ok=True) withheld.write_bytes(b"Withheld original must never supply these bytes.\n") records = packaging.distribution_doc_members(root, package) for record in records: self.assertNotEqual(record["bytes"], (root / record["archive_path"]).read_bytes()) self.assertEqual(record["bytes"], (root / record["copy"]).read_bytes())
class ShippedDocumentationLinkTests(unittest.TestCase): def test_manifest_mode_archive_links_resolve(self) -> None: problems = checker.check(None, ROOT, manifest()) self.assertEqual(problems, [])
def test_generated_documents_link_only_to_root_members(self) -> None: package = manifest() _s, _sd, binary_names, binary_docs = checker.manifest_membership(ROOT, package) for name in ("README.md", "INSTALL.md", "SOURCE-AND-LICENSES.md"): self.assertIn(name, binary_docs) problems = checker.check_documents("binary archive", binary_names, binary_docs) self.assertEqual(problems, [])
def _representative_archive(self, destination: Path) -> None: """Build a real archive from the bytes the binary archive would carry.""" package = manifest() _s, _sd, binary_names, binary_docs = checker.manifest_membership(ROOT, package) prefix = packaging.versioned_names(package["release"]["reserved_preview_version"], None)["prefix"] members: list[tuple[str, bytes, int]] = [] for name in sorted(binary_names): if name in binary_docs: payload = binary_docs[name].encode("utf-8") elif name == "source-manifest.json": # The archive's own bound record: it may map nothing, but it must # be a readable JSON object or archive mode refuses it. payload = json.dumps({"distribution_docs": distribution_doc_entries()}).encode("utf-8") elif (ROOT / name).is_file(): payload = (ROOT / name).read_bytes() else: payload = b"placeholder\n" members.append((f"{prefix}/{name}", payload, packaging.ARCHIVE_MODE_FILE)) # The two binaries are members, not documents. for extra in ("bin/ultimate-tool", "bin/ultimate-tool-mcp"): members.append((f"{prefix}/{extra}", b"x\n", packaging.ARCHIVE_MODE_FILE)) packaging.write_archive(destination, members, packaging.DEFAULT_LIMITS)
def test_real_archive_members_resolve(self) -> None: with tempfile.TemporaryDirectory(prefix="ut-doc-links-") as workdir: archive = Path(workdir) / "binary.tar.gz" self._representative_archive(archive) problems = checker.check(str(archive), ROOT, None) self.assertEqual(problems, [])
def test_real_archive_reports_a_dropped_document(self) -> None: with tempfile.TemporaryDirectory(prefix="ut-doc-links-") as workdir: archive = Path(workdir) / "partial.tar.gz" self._representative_archive(archive) membership = checker.archive_membership(archive) names = membership["names"] documents = membership["documents"] # Drop a document that other shipped documents link to. names.discard("docs/HTTP_API.md") documents.pop("docs/HTTP_API.md", None) problems = checker.check_documents("binary archive", names, documents) self.assertTrue(problems) self.assertTrue(any("docs/HTTP_API.md" in item for item in problems))
def test_real_source_archive_members_resolve(self) -> None: package = manifest() source_names, source_docs, _b, _bd = checker.manifest_membership(ROOT, package) with tempfile.TemporaryDirectory(prefix="ut-doc-links-src-") as workdir: archive = Path(workdir) / "source.tar.gz" prefix = packaging.versioned_names( package["release"]["reserved_preview_version"], None )["source_prefix"] members: list[tuple[str, bytes, int]] = [] for name in sorted(source_names): if name in source_docs: payload = source_docs[name].encode("utf-8") elif name == "SOURCE-PROVENANCE.json": # The source archive's own bound record, mapping the copies it # carries to the docs/ paths they ship at. payload = json.dumps( {"schema": 1, "record_kind": "release_source_provenance", "distribution_docs": distribution_doc_entries()} ).encode("utf-8") elif (ROOT / name).is_file(): payload = (ROOT / name).read_bytes() else: payload = b"placeholder\n" members.append((f"{prefix}/{name}", payload, packaging.ARCHIVE_MODE_FILE)) packaging.write_archive(archive, members, packaging.DEFAULT_LIMITS) problems = checker.check(str(archive), ROOT, None) self.assertEqual(problems, [])
def test_the_packaged_fixture_readme_links_a_shipped_document(self) -> None: # The packaged fixtures link back into docs/; that document must ship. package = manifest() _s, _sd, binary_names, binary_docs = checker.manifest_membership(ROOT, package) # The fixture README travels in the source archive, not the binary one. source_names, source_docs, _bn, _bnd = checker.manifest_membership(ROOT, package) fixture = "fixtures/checkpoint-demo/README.md" self.assertIn(fixture, source_names) self.assertIn("docs/CHECKPOINT_COMPARISON.md", source_names)
class DistributionPrivacyScanTests(unittest.TestCase): def test_blocking_content_in_a_copy_is_refused(self) -> None: planted = { "archive_path": "docs/X.md", "bytes": ("C64U_" + "PASSWORD" + ' = "' + "hunter2" + '"').encode("utf-8"), } with self.assertRaises(packaging.CheckFailure): packaging.scan_distribution_document_privacy([planted], {"credential_assignment": "block"})
def test_review_required_content_is_recorded_against_the_archive_path(self) -> None: device = {"archive_path": "docs/Y.md", "bytes": ("25" + "A6" + "0A").encode("utf-8")} findings = packaging.scan_distribution_document_privacy([device], {"device_identity": "review_required"}) self.assertEqual( findings, [{"path": "docs/Y.md", "sentinel": "device_identity", "severity": "review_required"}], )
def test_a_clean_copy_produces_no_findings(self) -> None: clean = {"archive_path": "docs/Z.md", "bytes": b"# Clean\n\nNo identifiers here.\n"} self.assertEqual(packaging.scan_distribution_document_privacy([clean], {}), [])
def test_the_real_copies_are_scanned_by_the_packager(self) -> None: # Every mapped copy is scanned at prepare time; only the allowlisted # project-relative run directory may match, and it is not blocking. package = manifest() records = packaging.distribution_doc_members(ROOT, package) findings = packaging.scan_distribution_document_privacy( records, packaging.sentinel_policy(package), packaging.review_exemptions(package) ) self.assertEqual({item["severity"] for item in findings} - {"allow"}, set())
class PlacementResolutionTests(unittest.TestCase): def test_copy_links_resolve_from_their_archive_placement(self) -> None: names = {"tools/release-docs/X.md", "docs/X.md", "docs/SIB.md"} documents = { "tools/release-docs/X.md": "[sib](SIB.md)\n", "docs/X.md": "[sib](SIB.md)\n", "docs/SIB.md": "# Sib\n", } # Without the placement, the stored copy's sibling link does not resolve. self.assertTrue(checker.check_documents("t", names, documents)) placements = {"tools/release-docs/X.md": "docs/X.md"} self.assertEqual(checker.check_documents("t", names, documents, placements), [])
def test_copy_placements_cover_every_mapped_copy(self) -> None: self.assertEqual( checker.copy_placements(manifest()), {copy: path for path, copy in MAPPED_DOCS.items()}, )
class SourceCompletenessTests(unittest.TestCase): def test_source_includes_the_copies_and_the_checker(self) -> None: package = manifest() include = {entry["path"] for entry in package["source_paths"]["include"]} self.assertIn("tools/check_distribution_docs.py", include) self.assertIn("tools/release-docs/", include) files, _report = packaging.collect_source_files(ROOT, package) paths = {entry["path"] for entry in files} for copy in MAPPED_DOCS.values(): self.assertIn(copy, paths)
class AdversarialDistributionMappingTests(unittest.TestCase): """A copy can only ever be a reviewed Markdown document under docs/."""
def _deny(self, paths: list[str]): return [packaging.compile_path_pattern(path) for path in paths]
def _validate(self, entry: dict, deny: tuple = ("docs/X.md",), root: str = "tools/release-docs"): return packaging.validate_distribution_doc_entry(entry, self._deny(list(deny)), root)
def _entry(self, **overrides) -> dict: entry = { "archive_path": "docs/X.md", "copy": "tools/release-docs/X.md", "origin": "docs/X.md", "sha256": "0" * 64, } entry.update(overrides) return entry
def test_a_well_formed_entry_is_accepted(self) -> None: self.assertEqual(self._validate(self._entry()), ("docs/X.md", "tools/release-docs/X.md"))
def test_absolute_copy_is_refused(self) -> None: for value in ("/etc/passwd.md", "C:/docs/X.md", "tools\\release-docs\\X.md"): with self.assertRaises(packaging.CheckFailure, msg=value): self._validate(self._entry(copy=value))
def test_escaping_or_non_canonical_copy_is_refused(self) -> None: for value in ("tools/release-docs/../docs/X.md", "../X.md", "tools/release-docs/./X.md", "tools/release-docs//X.md", "tools/release-docs/"): with self.assertRaises(packaging.CheckFailure, msg=value): self._validate(self._entry(copy=value))
def test_copy_outside_the_sanitized_root_is_refused(self) -> None: with self.assertRaises(packaging.CheckFailure): self._validate(self._entry(copy="docs/X.md"))
def test_copy_must_be_markdown(self) -> None: with self.assertRaises(packaging.CheckFailure): self._validate(self._entry(copy="tools/release-docs/X.txt"))
def test_copy_equal_to_the_archive_path_is_refused(self) -> None: with self.assertRaises(packaging.CheckFailure): self._validate(self._entry(copy="docs/X.md", archive_path="docs/X.md"))
def test_archive_path_outside_docs_is_refused(self) -> None: for value in ("X.md", "docs/sub/../../X.md", "tools/release-docs/X.md"): with self.assertRaises(packaging.CheckFailure, msg=value): self._validate(self._entry(archive_path=value))
def test_archive_path_must_be_markdown(self) -> None: with self.assertRaises(packaging.CheckFailure): self._validate(self._entry(archive_path="docs/X.text"))
def test_archive_path_may_not_target_build_evidence_or_runs(self) -> None: for value in ("docs/build/X.md", "docs/outputs/X.md", "docs/.ultimate-tool/X.md", "docs/runs/X.md"): with self.assertRaises(packaging.CheckFailure, msg=value): self._validate(self._entry(archive_path=value), deny=(value,))
def test_origin_must_equal_the_archive_path(self) -> None: with self.assertRaises(packaging.CheckFailure): self._validate(self._entry(origin="docs/OTHER.md"))
def test_a_non_denied_archive_path_is_refused(self) -> None: with self.assertRaises(packaging.CheckFailure): self._validate(self._entry(), deny=("docs/OTHER.md",))
def test_a_non_canonical_sanitized_root_is_refused(self) -> None: package = {"package_layout": {"distribution_docs": {"sanitized_root": "../tools"}}} with self.assertRaises(packaging.CheckFailure): packaging.distribution_doc_root(package)
class PreWritePrivacyScanTests(unittest.TestCase): """Blocking bytes stop preparation even when the recorded hash matches."""
def _minimal_manifest(self, entry: dict) -> dict: return { "schema": 1, "release": {"reserved_preview_version": "0.0.0", "license": "GPL-3.0-or-later", "license_file": "LICENSE"}, "source_paths": { "include": [{"path": "tools/release-docs/", "kind": "release-doc-source"}], "deny": [{"path": "docs/X.md"}], "rules": {}, }, "privacy": { "sentinel_policy": [ {"id": "credential_assignment", "severity": "block"}, {"id": "device_identity", "severity": "review_required"}, ], "review_exemptions": [], }, "vendor": {"required_for_complete_source": True}, "package_layout": { "distribution_docs": {"sanitized_root": "tools/release-docs", "entries": [entry]} }, "inventory": [], "external_prerequisites": [], }
def test_blocking_copy_is_refused_before_any_archive_is_written(self) -> None: planted = ("C64U_" + "PASSWORD" + ' = "' + "hunter2" + '"').encode("utf-8") with tempfile.TemporaryDirectory(prefix="ut-doc-privacy-") as work: root = Path(work) / "repo" (root / "tools" / "release-docs").mkdir(parents=True) (root / "tools" / "release-docs" / "X.md").write_bytes(planted) (root / "LICENSE").write_text("GPL\n", encoding="utf-8") manifest_path = root / "tools" / "release_source_manifest.json" entry = { "archive_path": "docs/X.md", "copy": "tools/release-docs/X.md", "origin": "docs/X.md", "sha256": hashlib.sha256(planted).hexdigest(), } manifest = self._minimal_manifest(entry) manifest_path.write_text(json.dumps(manifest), encoding="utf-8")
# The recorded digest matches the planted bytes exactly, so the hash # check alone would accept them: only the sentinel scan refuses. records = packaging.distribution_doc_members(root, manifest) self.assertEqual(records[0]["sha256"], entry["sha256"])
output = Path(work) / "out" output.mkdir() args = argparse.Namespace( no_vendor=True, vendor_dir=None, dry_run=False, rebuild_status="not_requested", rebuild_evidence=None, ) context = { "manifest": manifest, "manifest_path": manifest_path, "source_root": root, "output": output, "names": packaging.versioned_names("0.0.0", None), "limits": packaging.DEFAULT_LIMITS, "policy": packaging.sentinel_policy(manifest), "exemptions": packaging.review_exemptions(manifest), "vendor_fixture_exemptions": {}, "runtime_bundle": None, "source": {"revision": None, "tag": None, "dirty": False, "in_git_worktree": False, "tree_state": "unrecorded"}, "version": "0.0.0", "development": True, "development_label": "test", "created_at": "1970-01-01T00:00:00Z", "generator": {"tool": "test", "sha256": "0" * 64}, } with self.assertRaises(packaging.CheckFailure): packaging.prepare_source(args, context) self.assertEqual(list(output.glob("*.tar.gz")), []) self.assertFalse((output / "source-manifest.json").exists())
def test_the_two_strategies_agree_on_the_real_manifest(self) -> None: # prepare-source and pack both scan the copy bytes with the same policy. package = manifest() records = packaging.distribution_doc_members(ROOT, package) policy = packaging.sentinel_policy(package) exemptions = packaging.review_exemptions(package) self.assertEqual( packaging.scan_distribution_document_privacy(records, policy, exemptions), packaging.scan_distribution_document_privacy( packaging.distribution_doc_members(ROOT, package), policy, exemptions ), )
class ScopeClassificationTests(unittest.TestCase): """Only first-party documentation is validated; the foreign roots are fixed."""
def test_the_foreign_roots_are_the_fixed_three(self) -> None: self.assertEqual( checker.FOREIGN_SOURCE_PREFIXES, ("runtime-notices/", "runtime-sources/", "vendor/"), )
def test_first_party_classification(self) -> None: self.assertTrue(checker.is_first_party("docs/HTTP_API.md")) self.assertTrue(checker.is_first_party("tools/release-docs/HTTP_API.md")) self.assertTrue(checker.is_first_party("fixtures/checkpoint-demo/README.md")) self.assertTrue(checker.is_first_party("mystuff/GUIDE.md")) self.assertFalse(checker.is_first_party("vendor/gimli-0.32.3/README.md")) self.assertFalse(checker.is_first_party("runtime-sources/upstream/GUIDE.md")) self.assertFalse(checker.is_first_party("runtime-notices/THIRD-PARTY-NOTICES.md"))
def test_no_manifest_or_option_can_widen_the_exclusions(self) -> None: # The roots are a module constant: a document shipping beside the # checker cannot widen them and thereby hide a broken first-party guide. self.assertIsInstance(checker.FOREIGN_SOURCE_PREFIXES, tuple) self.assertNotIn("docs/", checker.FOREIGN_SOURCE_PREFIXES) parser = checker.build_parser() options = {option for action in parser._actions for option in action.option_strings} self.assertNotIn("--exclude", options) self.assertNotIn("--prefix", options)
class ForeignScopeArchiveTests(unittest.TestCase): """A vendor/runtime document may be broken upstream without failing the check."""
VENDOR_DOC = ( "# acme\n\n" "See [ZeroSlice](ZeroSlice) and [the `crate`](crate) and [&self](&self).\n" "Runnable examples: [dump](./crates/examples/src/bin/dump.rs).\n" "\n" ) RUNTIME_DOC = "# upstream runtime\n\nSee [their guide](../../does/not/exist.md).\n" NOTICE_DOC = "# notices\n\nUpstream license text: [LICENSE](../vendor/acme/LICENSE).\n"
def _archive(self, destination: Path) -> None: prefix = "ultimate-tool-0.0.0-linux-x86_64-gnu-source" members = [ (f"{prefix}/docs/GUIDE.md", b"# Guide\n\nSee [options](OPTIONS.md) and [acme](../vendor/acme/README.md).\n", packaging.ARCHIVE_MODE_FILE), (f"{prefix}/docs/OPTIONS.md", b"# Options\n", packaging.ARCHIVE_MODE_FILE), (f"{prefix}/docs/BROKEN.md", b"# Broken\n\nSee [gone](GONE.md).\n", packaging.ARCHIVE_MODE_FILE), (f"{prefix}/vendor/acme/README.md", self.VENDOR_DOC.encode("utf-8"), packaging.ARCHIVE_MODE_FILE), (f"{prefix}/runtime-sources/upstream/GUIDE.md", self.RUNTIME_DOC.encode("utf-8"), packaging.ARCHIVE_MODE_FILE), (f"{prefix}/runtime-notices/THIRD-PARTY-NOTICES.md", self.NOTICE_DOC.encode("utf-8"), packaging.ARCHIVE_MODE_FILE), ] packaging.write_archive(destination, members, packaging.DEFAULT_LIMITS)
def test_foreign_broken_links_are_skipped_first_party_broken_still_fails(self) -> None: with tempfile.TemporaryDirectory(prefix="ut-doc-scope-") as workdir: archive = Path(workdir) / "source.tar.gz" self._archive(archive) report = checker.audit(str(archive), ROOT, None) self.assertFalse(report["ok"]) self.assertEqual(len(report["problems"]), 1) self.assertIn("docs/BROKEN.md", report["problems"][0]) self.assertNotIn("vendor/acme/README.md", "\n".join(report["problems"])) self.assertNotIn("runtime-sources/", "\n".join(report["problems"]))
def test_the_report_states_the_scope_it_applied(self) -> None: with tempfile.TemporaryDirectory(prefix="ut-doc-scope-") as workdir: archive = Path(workdir) / "source.tar.gz" self._archive(archive) entry = checker.audit(str(archive), ROOT, None)["reports"][0] self.assertEqual(entry["validated"], 3) # docs/BROKEN, docs/GUIDE, docs/OPTIONS self.assertEqual(entry["skipped"], 3) # vendor, runtime-sources, runtime-notices report = checker.audit(str(archive), ROOT, None) self.assertIn("vendor/", report["limits"]) self.assertIn("runtime-notices/", report["limits"]) self.assertIn("runtime-sources/", report["limits"])
def test_a_first_party_link_into_a_foreign_root_still_resolves(self) -> None: # GUIDE.md links ../vendor/acme/README.md; that name is indexed even # though the vendor document itself is not validated. with tempfile.TemporaryDirectory(prefix="ut-doc-scope-") as workdir: archive = Path(workdir) / "source.tar.gz" self._archive(archive) membership = checker.archive_membership(archive) self.assertIn("vendor/acme/README.md", membership["names"]) self.assertNotIn("vendor/acme/README.md", membership["documents"]) problems = checker.check_documents("t", membership["names"], membership["documents"]) self.assertEqual([p for p in problems if "GUIDE.md" in p and "docs/" in p], [])
def test_a_repaired_first_party_link_passes(self) -> None: with tempfile.TemporaryDirectory(prefix="ut-doc-scope-") as workdir: archive = Path(workdir) / "source.tar.gz" prefix = "ultimate-tool-0.0.0-linux-x86_64-gnu-source" members = [ (f"{prefix}/docs/BROKEN.md", b"# Broken\n\nSee [options](OPTIONS.md).\n", packaging.ARCHIVE_MODE_FILE), (f"{prefix}/docs/OPTIONS.md", b"# Options\n", packaging.ARCHIVE_MODE_FILE), (f"{prefix}/vendor/acme/README.md", self.VENDOR_DOC.encode("utf-8"), packaging.ARCHIVE_MODE_FILE), ] packaging.write_archive(archive, members, packaging.DEFAULT_LIMITS) self.assertEqual(checker.audit(str(archive), ROOT, None)["problems"], [])
class BoundMappingTests(unittest.TestCase): """Archive mode derives the copy mapping from the archive's own bound record."""
ALIAS_SOURCE = "tools/release-docs/X.md" ALIAS_DEST = "docs/X.md" SIBLING = "docs/SIB.md" # The copy is authored for its docs/ placement, so from its stored location # the sibling link only resolves through the bound mapping. COPY_TEXT = "# X\n\nSee [sib](SIB.md).\n" SIBLING_TEXT = "# Sib\n"
def _provenance(self, **overrides) -> dict: entry = { "archive_path": self.ALIAS_DEST, "copy": self.ALIAS_SOURCE, "origin": self.ALIAS_DEST, "size": len(self.COPY_TEXT.encode("utf-8")), "sha256": hashlib.sha256(self.COPY_TEXT.encode("utf-8")).hexdigest(), } entry.update(overrides) return {"schema": 1, "record_kind": "release_source_provenance", "distribution_docs": [entry]}
def _write(self, destination: Path, record_name="SOURCE-PROVENANCE.json", document=None, extra=None, include_copy=True, copy_bytes=None) -> None: prefix = "ultimate-tool-0.0.0-linux-x86_64-gnu-source" payload = json.dumps(self._provenance() if document is None else document).encode("utf-8") members = [ (f"{prefix}/{self.ALIAS_DEST}", self.COPY_TEXT.encode("utf-8"), packaging.ARCHIVE_MODE_FILE), (f"{prefix}/{self.SIBLING}", self.SIBLING_TEXT.encode("utf-8"), packaging.ARCHIVE_MODE_FILE), (f"{prefix}/{record_name}", payload, packaging.ARCHIVE_MODE_FILE), ] if include_copy: members.append(( f"{prefix}/{self.ALIAS_SOURCE}", self.COPY_TEXT.encode("utf-8") if copy_bytes is None else copy_bytes, packaging.ARCHIVE_MODE_FILE, )) for name, text in (extra or []): members.append((f"{prefix}/{name}", text.encode("utf-8"), packaging.ARCHIVE_MODE_FILE)) packaging.write_archive(destination, members, packaging.DEFAULT_LIMITS)
def test_source_provenance_supplies_the_placement_and_is_reported(self) -> None: with tempfile.TemporaryDirectory(prefix="ut-doc-bound-") as workdir: archive = Path(workdir) / "source.tar.gz" self._write(archive) report = checker.audit(str(archive), ROOT, None) self.assertEqual(report["problems"], []) self.assertEqual(report["reports"][0]["bound_manifest"], "SOURCE-PROVENANCE.json")
def test_binary_shape_uses_the_root_source_manifest(self) -> None: with tempfile.TemporaryDirectory(prefix="ut-doc-bound-") as workdir: archive = Path(workdir) / "binary.tar.gz" self._write(archive, record_name="source-manifest.json") report = checker.audit(str(archive), ROOT, None) self.assertEqual(report["problems"], []) self.assertEqual(report["reports"][0]["bound_manifest"], "source-manifest.json")
def test_copies_without_a_bound_record_are_refused(self) -> None: # A stored copy whose placement is unknown would be validated against the # wrong directory, so an archive that carries copies must record a mapping. with tempfile.TemporaryDirectory(prefix="ut-doc-bound-") as workdir: archive = Path(workdir) / "bare.tar.gz" prefix = "ultimate-tool-0.0.0-linux-x86_64-gnu-source" packaging.write_archive( archive, [ (f"{prefix}/{self.ALIAS_SOURCE}", self.COPY_TEXT.encode("utf-8"), packaging.ARCHIVE_MODE_FILE), (f"{prefix}/{self.ALIAS_DEST}", self.COPY_TEXT.encode("utf-8"), packaging.ARCHIVE_MODE_FILE), (f"{prefix}/{self.SIBLING}", self.SIBLING_TEXT.encode("utf-8"), packaging.ARCHIVE_MODE_FILE), ], packaging.DEFAULT_LIMITS, ) with self.assertRaises(packaging.CheckFailure): checker.archive_membership(archive)
def test_a_plain_archive_without_copies_needs_no_metadata(self) -> None: with tempfile.TemporaryDirectory(prefix="ut-doc-bound-") as workdir: archive = Path(workdir) / "plain.tar.gz" prefix = "ultimate-tool-0.0.0-linux-x86_64-gnu-source" packaging.write_archive( archive, [ (f"{prefix}/docs/A.md", b"# A\n\nSee [b](B.md).\n", packaging.ARCHIVE_MODE_FILE), (f"{prefix}/docs/B.md", b"# B\n", packaging.ARCHIVE_MODE_FILE), ], packaging.DEFAULT_LIMITS, ) report = checker.audit(str(archive), ROOT, None) self.assertIsNone(report["reports"][0]["bound_manifest"]) self.assertEqual(report["problems"], [])
def test_a_malformed_bound_record_is_refused_not_skipped(self) -> None: with tempfile.TemporaryDirectory(prefix="ut-doc-bound-") as workdir: archive = Path(workdir) / "broken.tar.gz" prefix = "ultimate-tool-0.0.0-linux-x86_64-gnu-source" packaging.write_archive( archive, [(f"{prefix}/SOURCE-PROVENANCE.json", b"{not json", packaging.ARCHIVE_MODE_FILE)], packaging.DEFAULT_LIMITS, ) with self.assertRaises(packaging.CheckFailure): checker.archive_membership(archive)
def test_the_external_root_cannot_change_the_result(self) -> None: with tempfile.TemporaryDirectory(prefix="ut-doc-bound-") as workdir: archive = Path(workdir) / "source.tar.gz" self._write(archive) empty_root = Path(workdir) / "empty" empty_root.mkdir() # A decoy root that would supply a different mapping if it were read. decoy = Path(workdir) / "decoy" (decoy / "tools").mkdir(parents=True) (decoy / "tools" / "release_source_manifest.json").write_text( json.dumps({"package_layout": {"distribution_docs": {"entries": [ {"archive_path": "docs/X.md", "copy": "tools/release-docs/OTHER.md"} ]}}}), encoding="utf-8", ) first = checker.audit(str(archive), empty_root, None) second = checker.audit(str(archive), decoy, None) self.assertEqual(first, second) self.assertEqual(first["problems"], [])
def test_a_bound_record_cannot_widen_the_validation_scope(self) -> None: with tempfile.TemporaryDirectory(prefix="ut-doc-bound-") as workdir: archive = Path(workdir) / "source.tar.gz" self._write( archive, document={ "distribution_docs": self._provenance()["distribution_docs"], "foreign_prefixes": ["docs/"], "sanitized_root": "docs", }, extra=[("docs/BROKEN.md", "# Broken\n\nSee [gone](GONE.md).\n")], ) report = checker.audit(str(archive), ROOT, None) self.assertTrue( any("docs/BROKEN.md" in problem for problem in report["problems"]), "a bound record must not be able to exempt first-party guides", ) self.assertTrue(checker.is_first_party("docs/BROKEN.md"))
def test_a_recorded_digest_that_does_not_match_is_reported(self) -> None: with tempfile.TemporaryDirectory(prefix="ut-doc-bound-") as workdir: archive = Path(workdir) / "source.tar.gz" self._write(archive, document=self._provenance(sha256="0" * 64, size=1)) report = checker.audit(str(archive), ROOT, None) self.assertTrue(any("records" in problem for problem in report["problems"]))
def test_an_input_copy_that_differs_from_the_recorded_digest_fails(self) -> None: # The alias carries the recorded bytes and the copy does not: the mapping # is contradicted by its own input copy, and that must fail even though # the alias alone would have matched. different = self.COPY_TEXT.encode("utf-8") + b"\nAn extra paragraph.\n" with tempfile.TemporaryDirectory(prefix="ut-doc-bound-") as workdir: archive = Path(workdir) / "source.tar.gz" self._write(archive, copy_bytes=different) report = checker.audit(str(archive), ROOT, None) self.assertTrue(any(self.ALIAS_SOURCE in problem for problem in report["problems"]), report["problems"])
def test_static_metadata_hash_is_verified_even_without_a_size(self) -> None: good = hashlib.sha256(self.COPY_TEXT.encode("utf-8")).hexdigest() static = lambda digest: {"package_layout": {"distribution_docs": {"entries": [ {"archive_path": self.ALIAS_DEST, "copy": self.ALIAS_SOURCE, "origin": self.ALIAS_DEST, "sha256": digest} ]}}} with tempfile.TemporaryDirectory(prefix="ut-doc-bound-") as workdir: archive = Path(workdir) / "static.tar.gz" self._write(archive, record_name="tools/release_source_manifest.json", document=static("0" * 64)) report = checker.audit(str(archive), ROOT, None) self.assertTrue(any("records" in problem for problem in report["problems"]), "a stated hash must be verified even when no size is stated") with tempfile.TemporaryDirectory(prefix="ut-doc-bound-") as workdir: archive = Path(workdir) / "static-ok.tar.gz" self._write(archive, record_name="tools/release_source_manifest.json", document=static(good)) report = checker.audit(str(archive), ROOT, None) self.assertEqual(report["problems"], []) self.assertEqual(report["reports"][0]["bound_manifest"], "tools/release_source_manifest.json")
def test_a_binary_archive_without_an_input_copy_passes(self) -> None: # The binary archive carries the alias and the mapping but no stored copy # under tools/release-docs/: the present members are the ones verified. with tempfile.TemporaryDirectory(prefix="ut-doc-bound-") as workdir: archive = Path(workdir) / "binary.tar.gz" self._write(archive, include_copy=False) membership = checker.archive_membership(archive) self.assertEqual(membership["placements"], {self.ALIAS_SOURCE: self.ALIAS_DEST}) self.assertNotIn(self.ALIAS_SOURCE, membership["names"]) report = checker.audit(str(archive), ROOT, None) self.assertEqual(report["problems"], []) self.assertEqual(report["reports"][0]["bound_manifest"], "SOURCE-PROVENANCE.json")
def test_non_canonical_bound_entries_are_refused(self) -> None: bad_entries = [ {"archive_path": "docs/X.md", "copy": "docs/X.md"}, # copy is not under COPY_ROOT {"archive_path": "docs/X.md", "copy": 5}, # copy is not a string {"archive_path": "docs/X.md", "copy": "tools/release-docs/Z.txt"}, # not Markdown {"archive_path": "elsewhere/X.md", "copy": "tools/release-docs/Z.md"}, # wrong destination {"archive_path": "docs/X.md", "copy": "tools/release-docs/Z.md", "origin": "docs/OTHER.md"}, # origin mismatch {"archive_path": "docs/X.md", "copy": "tools/release-docs/Z.md", "size": 1}, # no digest on a resolved record {"archive_path": "docs/X.md", "copy": "tools/release-docs/Z.md", "size": True, "sha256": "0" * 64}, # bool is not a size {"archive_path": "docs/X.md", "copy": "tools/release-docs/Z.md", "size": -1, "sha256": "0" * 64}, # negative size {"archive_path": "docs/X.md", "copy": "tools/release-docs/Z.md", "size": 0, "sha256": "0" * 64}, # not positive {"archive_path": "docs/X.md", "copy": "tools/release-docs/Z.md", "size": 1, "sha256": "0" * 63}, # not 64 characters {"archive_path": "docs/X.md", "copy": "tools/release-docs/Z.md", "size": 1, "sha256": "A" * 64}, # not lowercase hex {"archive_path": "docs/../X.md", "copy": "tools/release-docs/Z.md", "size": 1, "sha256": "0" * 64}, # non-canonical destination {"archive_path": "docs/X.md", "copy": "tools/release-docs/./Z.md", "size": 1, "sha256": "0" * 64}, # non-canonical copy ] for entry in bad_entries: with tempfile.TemporaryDirectory(prefix="ut-doc-bound-") as workdir: archive = Path(workdir) / "source.tar.gz" self._write(archive, document={"distribution_docs": [entry]}) with self.assertRaises(packaging.CheckFailure, msg=str(entry)): checker.archive_membership(archive)
def test_duplicate_mappings_are_refused(self) -> None: for entries in ( [{"archive_path": "docs/X.md", "copy": "tools/release-docs/X.md", "size": 1, "sha256": "0" * 64}, {"archive_path": "docs/Y.md", "copy": "tools/release-docs/X.md", "size": 1, "sha256": "0" * 64}], [{"archive_path": "docs/X.md", "copy": "tools/release-docs/X.md", "size": 1, "sha256": "0" * 64}, {"archive_path": "docs/X.md", "copy": "tools/release-docs/Y.md", "size": 1, "sha256": "0" * 64}], ): with tempfile.TemporaryDirectory(prefix="ut-doc-bound-") as workdir: archive = Path(workdir) / "source.tar.gz" self._write(archive, document={"distribution_docs": entries}) with self.assertRaises(packaging.CheckFailure): checker.archive_membership(archive)
if __name__ == "__main__": unittest.main()