import hashlib import json from pathlib import Path import tempfile import unittest import zipfile from package_windows_cli import package from test_package_windows import executable import stage_extraction_worker as extraction class CliPackageTests(unittest.TestCase): def fixture(self, directory): root = Path(directory) (root / 'Cargo.toml').write_text('workspace') (root / 'Cargo.lock').write_text('lock') for crate in ('searchi-core', 'searchi-media', 'searchi-extract-worker'): base = root / 'crates' / crate (base / 'src').mkdir(parents=True) (base / 'Cargo.toml').write_text(crate) (base / 'src' / ('main.rs' if crate == 'searchi-extract-worker' else 'lib.rs')).write_text('// fixture') (root / 'LICENSE').write_text('license') cli = root / 'cli.exe' helper = root / 'helper.exe' executable(cli) executable(helper) resources = root / 'resources' extraction.stage(helper, extraction.fingerprint(root), resources, root) return root, cli, resources, root / 'client.zip' def test_integrity_and_minimal_contents(self): with tempfile.TemporaryDirectory() as directory: root, cli, resources, output = self.fixture(directory) self.assertEqual(package(root, cli, resources, output), 'x86_64') with zipfile.ZipFile(output) as archive: self.assertEqual(set(archive.namelist()), {'searchi-cli.exe', 'searchi-extract-worker.exe', 'extraction-worker.json', 'LICENSE.txt', 'PACKAGE.json'}) manifest = json.loads(archive.read('PACKAGE.json')) for record in manifest['files']: data = archive.read(record['path']) self.assertEqual(len(data), record['bytes']) self.assertEqual(hashlib.sha256(data).hexdigest(), record['sha256']) def test_rejected_helper_preserves_output(self): for mutation in ('missing', 'tampered', 'architecture'): with self.subTest(mutation=mutation), tempfile.TemporaryDirectory() as directory: root, cli, resources, output = self.fixture(directory) output.write_bytes(b'previous') helper = resources / 'searchi-extract-worker.exe' if mutation == 'missing': helper.unlink() elif mutation == 'tampered': helper.write_bytes(helper.read_bytes() + b'changed') else: executable(cli, 0xAA64) with self.assertRaises(ValueError): package(root, cli, resources, output) self.assertEqual(output.read_bytes(), b'previous') self.assertEqual(list(root.glob('*.partial')), []) if __name__ == '__main__': unittest.main()