# SPDX-License-Identifier: MPL-2.0 import gzip import importlib.util import json from pathlib import Path import stat import struct import subprocess import sys import tempfile import unittest from unittest.mock import patch sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "tools")) import tundra spec = importlib.util.spec_from_file_location("collector", tundra.ROOT / "tools/collect-device.py") collector = importlib.util.module_from_spec(spec) spec.loader.exec_module(collector) class PackagingTests(unittest.TestCase): def test_cpio_roundtrip_and_reproducibility(self): entries = [("dev", stat.S_IFDIR | 0o755, b"", 0, 0), ("dev/console", stat.S_IFCHR | 0o600, b"", 5, 1), ("init", stat.S_IFREG | 0o755, b"init-payload", 0, 0)] a = tundra.cpio(entries) self.assertEqual(a, tundra.cpio(entries)) data = gzip.decompress(a) cursor = 0 decoded = {} while True: self.assertEqual(data[cursor:cursor + 6], b"070701") fields = [int(data[cursor + 6 + 8 * n:cursor + 14 + 8 * n], 16) for n in range(13)] cursor += 110 name = data[cursor:cursor + fields[11] - 1].decode() cursor = (cursor + fields[11] + 3) & ~3 payload = data[cursor:cursor + fields[6]] cursor = (cursor + fields[6] + 3) & ~3 if name == "TRAILER!!!": break decoded[name] = (fields, payload) self.assertEqual(decoded["init"][1], b"init-payload") self.assertEqual(decoded["dev/console"][0][9:11], [5, 1]) self.assertEqual(decoded["init"][0][1], stat.S_IFREG | 0o755) # Independent parser: GNU cpio, never extract a device node onto the host. p = subprocess.run(["cpio", "-it"], input=data, capture_output=True, check=True) self.assertIn(b"dev/console", p.stdout) self.assertIn(b"init", p.stdout) def test_cpio_rejects_escape(self): for name in ("/init", "../init", "dev/../../init"): with self.assertRaises(ValueError): tundra.cpio([(name, stat.S_IFREG | 0o755, b"", 0, 0)]) def test_manifest_inheritance_and_cycle(self): with tempfile.TemporaryDirectory() as d: root = Path(d) (root / "main.xml").write_text('') (root / "sub.xml").write_text('') self.assertEqual(tundra.flatten_manifest(root, "main.xml"), [{"path": "src/kernel", "url": "https://example.org/kernel", "revision": "tag"}]) (root / "sub.xml").write_text('') with self.assertRaises(ValueError): tundra.flatten_manifest(root, "main.xml") def test_sargo_boot_roundtrip(self): folder = tundra.ROOT / "out/sargo-stage0" metadata_file = folder / "image.json" if not metadata_file.exists(): self.skipTest("Run ./tundra prepare-sargo first") info = json.loads(metadata_file.read_text()) image = folder / info["file"] self.assertEqual(tundra.digest(image), info["sha256"]) self.assertFalse(info["flashReady"]) with tempfile.TemporaryDirectory() as d: subprocess.run([sys.executable, str(tundra.checked_source("aosp-mkbootimg") / "unpack_bootimg.py"), "--boot_img", str(image), "--out", d], check=True, capture_output=True) self.assertEqual((Path(d) / "ramdisk").read_bytes(), (folder / "initramfs.cpio.gz").read_bytes()) kernel = tundra.ROOT / "downloads/aosp-sargo-kernel" / info["kernelSource"]["commit"] / "Image.lz4-dtb" self.assertEqual(tundra.digest(Path(d) / "kernel"), tundra.digest(kernel)) self.assertEqual(struct.unpack_from("