"""Synthetic cold-host bootstrap transactions; no actual APT/systemd/USB.""" import hashlib import importlib.util import json import subprocess import tempfile import time import unittest from pathlib import Path from unittest.mock import patch REPO = Path(__file__).resolve().parents[3] spec = importlib.util.spec_from_file_location( "x4_node_profile", REPO / "apps/node-agent/packaging/insta360_profile.py" ) profile = importlib.util.module_from_spec(spec) spec.loader.exec_module(profile) class ProfileTests(unittest.TestCase): def setUp(self): self.temp = tempfile.TemporaryDirectory(dir=REPO / "plugins/insta360-x4/build") self.addCleanup(self.temp.cleanup) root = Path(self.temp.name) self.share, self.state, self.plugin = (root / name for name in ("share", "state", "plugin")) for directory in (self.share, self.state, self.plugin): directory.mkdir() self.bundle = { "schema": "missioncore.node.bundled-model/v1", "version": "0.1.1", "revision": "a" * 24, "bytes": 3, "sha256": hashlib.sha256(b"deb").hexdigest(), } (self.share / "profile.json").write_text(json.dumps(self.bundle)) (self.share / "mission-core-insta360-x4_0.1.1_amd64.deb").write_bytes(b"deb") self.calls = [] self.previous = None self.failure = False for name, value in ( ("SHARE", self.share), ("STATE", self.state), ("PLUGIN_STATE", self.plugin), ): context = patch.object(profile, name, value) context.start() self.addCleanup(context.stop) # Production checks uid 0. Tests remain unprivileged and only admit the # three private fixture directories, never paths on the installed OS. def trusted(path, directory=False): self.assertTrue(path == root or root in path.parents) self.assertFalse(path.is_symlink()) self.assertEqual(path.is_dir(), directory) return path for context in ( patch.object(profile, "trusted", trusted), patch.object(profile.platform, "machine", return_value="x86_64"), patch.object( profile.platform, "freedesktop_os_release", return_value={"ID": "ubuntu", "VERSION_ID": "24.04"}, ), patch.object(profile.subprocess, "run", side_effect=self.run_command), ): context.start() self.addCleanup(context.stop) def prepared(self): (self.plugin / "preparation.json").write_text( json.dumps( { "state": "complete", "revision": self.bundle["revision"], "started_at": time.time(), } ) ) def run_command(self, command, **kwargs): self.calls.append(command) name = Path(command[0]).name if name == "dpkg-query": return subprocess.CompletedProcess( command, 1 if self.previous is None else 0, "" if self.previous is None else self.previous + "\tinstall ok installed", "", ) if name == "dpkg" and command[1] == "--compare-versions": return subprocess.CompletedProcess(command, 0 if self.previous == "0.2.0" else 1) if name == "dpkg" and command[1] == "--install": if self.failure: return subprocess.CompletedProcess(command, 100, b"", b"synthetic package refusal") if self.previous: self.prepared() # Upgrade postinst owns preparation. elif name == "systemctl": self.assertEqual(command, ["/usr/bin/systemctl", "start", profile.UNIT]) self.prepared() else: self.fail("Unexpected OS command") return subprocess.CompletedProcess(command, 0, b"", b"") def names(self): return [Path(command[0]).name for command in self.calls] def test_cold_host_installs_only_bundled_package_then_fixed_prepare(self): self.assertTrue(profile.prepare()) self.assertEqual(self.names(), ["dpkg-query", "dpkg", "systemctl"]) self.assertEqual( self.calls[1], [ "/usr/bin/dpkg", "--install", str(self.share / "mission-core-insta360-x4_0.1.1_amd64.deb"), ], ) def test_existing_version_reuses_package_and_revalidates_runtime(self): self.previous = "0.1.1" self.assertTrue(profile.prepare()) self.assertFalse(any("--install" in command for command in self.calls)) self.assertIn("systemctl", self.names()) def test_debian_revision_remains_a_fixed_local_package(self): old = self.share / "mission-core-insta360-x4_0.1.1_amd64.deb" old.rename(self.share / "mission-core-insta360-x4_0.1.1-1_amd64.deb") self.bundle["version"] = "0.1.1-1" (self.share / "profile.json").write_text(json.dumps(self.bundle)) self.assertTrue(profile.prepare()) self.assertEqual(Path(self.calls[1][-1]).name, "mission-core-insta360-x4_0.1.1-1_amd64.deb") def test_upgrade_does_not_race_postinst_with_second_prepare(self): self.previous = "0.1.0" self.assertTrue(profile.prepare()) self.assertTrue(any("--install" in command for command in self.calls)) self.assertNotIn("systemctl", self.names()) def test_corruption_never_reaches_package_manager_or_driver(self): (self.share / "mission-core-insta360-x4_0.1.1_amd64.deb").write_bytes(b"bad") self.assertFalse(profile.prepare()) self.assertEqual(self.calls, []) def test_newer_driver_is_preserved(self): self.previous = "0.2.0" self.assertFalse(profile.prepare()) self.assertFalse(any("--install" in command for command in self.calls)) self.assertNotIn("systemctl", self.names()) def test_failed_package_never_opens_camera_and_keeps_error_evidence(self): self.failure = True self.assertFalse(profile.prepare()) self.assertNotIn("systemctl", self.names()) report = json.loads((self.state / "preparation.json").read_text()) self.assertEqual(report["steps"][-1]["state"], "blocked") self.assertEqual( (self.state / report["run_id"] / "1.stderr").read_bytes(), b"synthetic package refusal" ) if __name__ == "__main__": unittest.main()