#!/usr/bin/env python3 """Packaging invariants; stdlib synthetic files, no Cargo, builds or GUI.""" import importlib.util import json from pathlib import Path import struct import tarfile import tempfile import unittest from unittest.mock import patch spec = importlib.util.spec_from_file_location('packaging', Path(__file__).with_name('package-artifacts.py')) packaging = importlib.util.module_from_spec(spec) spec.loader.exec_module(packaging) class PackageContracts(unittest.TestCase): def setUp(self): self.temporary = tempfile.TemporaryDirectory(prefix='arcadia-packaging-test-') self.root = Path(self.temporary.name) def tearDown(self): self.temporary.cleanup() def file(self, name, data=b'test'): path = self.root / name path.parent.mkdir(parents=True, exist_ok=True) path.write_bytes(data) return path def elf(self, needed=b'libc.so.6', interpreter=b'/lib64/ld-linux-x86-64.so.2', runpath=False): # One load maps the file, followed by interpreter and dynamic segments. data = bytearray(1024) data[:6] = b'\x7fELF\x02\x01' struct.pack_into(' 1 and args[1] == 'r:gz': self.file('stage/late.txt', b'late') return result with patch.object(packaging.tarfile, 'open', side_effect=open_and_add): with self.assertRaisesRegex(ValueError, 'Stage changed'): packaging.make_archive(self.root / 'stage', self.root / 'archive.tar.gz', 'fixture') def test_input_rejects_a_reparse_ancestor(self): source = self.file('ordinary/file.txt') original = Path.lstat def reparse(path, **kwargs): if path == source.parent: result = original(path, **kwargs) return type('ReparseStat', (), {'st_mode': result.st_mode, 'st_file_attributes': 1024})() return original(path, **kwargs) with patch.object(Path, 'lstat', reparse), patch.object(packaging.stat, 'FILE_ATTRIBUTE_REPARSE_POINT', 1024, create=True): with self.assertRaisesRegex(ValueError, 'reparse ancestor'): packaging.ordinary(source) def test_local_document_links_are_complete_and_cannot_escape(self): self.file('docs/README.md', b'[guide](guide%20one.md#section)\n[web](https://example.com)\n') self.file('docs/guide one.md', b'# section\n') self.assertEqual(packaging.check_documents(self.root / 'docs')['checked_local_document_links'], 1) self.file('docs/README.md', b'[missing](missing.md)') with self.assertRaises(ValueError): packaging.check_documents(self.root / 'docs') self.file('docs/README.md', b'[escape](../outside.md)') with self.assertRaises(ValueError): packaging.check_documents(self.root / 'docs') def test_rst_directives_and_fenced_examples_are_not_links(self): self.file('docs/a.rst', b'.. code-block:: rust\n\n sample\n') self.file('docs/a.md', b'```text\n[example](absent.md)\n```\n`[sample](absent.md)`\n') self.assertEqual(packaging.check_documents(self.root / 'docs')['checked_local_document_links'], 0) def test_html_attribute_case_spacing_and_unquoted_links_are_checked(self): self.file('docs/a.html', b'Missing') with self.assertRaises(ValueError): packaging.check_documents(self.root / 'docs') self.file('docs/missing.html', b'ok') self.file('docs/a.html', b'Present') self.assertEqual(packaging.check_documents(self.root / 'docs')['checked_local_document_links'], 1) def test_elf_accepts_reviewed_glibc_and_refuses_unknown_runtime(self): self.assertEqual(packaging.inspect_elf(self.elf())['needed'], ['libc.so.6']) with self.assertRaisesRegex(ValueError, 'Unreviewed'): packaging.inspect_elf(self.elf(needed=b'private-runtime.so')) with self.assertRaisesRegex(ValueError, 'RPATH'): packaging.inspect_elf(self.elf(runpath=True)) def test_elf_rejects_wrong_architecture_truncation_and_loader(self): with self.assertRaisesRegex(ValueError, 'glibc dynamic loader'): packaging.inspect_elf(self.elf(interpreter=b'/lib/ld-musl-x86_64.so.1')) elf = self.elf() data = bytearray(elf.read_bytes()) struct.pack_into('