Package Apple Silicon VM exports and cached runtime switching with local cabinet controls and conagent provisioning. Preserve experimental SPIKE 2 emulation. Improve preparation concurrency, Ghidra checkpoints, signature importing, sound indexing and client-side spectrograms. Include regression tests and validation notes.
61 lines
3.6 KiB
Python
61 lines
3.6 KiB
Python
import json
|
|
from pathlib import Path
|
|
import tempfile
|
|
import unittest
|
|
from unittest.mock import patch
|
|
import zipfile
|
|
from bundles.builder import stage, write_zip, node_firmware_version
|
|
|
|
|
|
class BundleStaging(unittest.TestCase):
|
|
def test_selected_firmware_version_and_conflicts(self):
|
|
with tempfile.TemporaryDirectory() as temporary:
|
|
root=Path(temporary)
|
|
self.assertEqual(node_firmware_version(root),'1.33.0')
|
|
for name in ('pinnode-LPC1313-1_35_0.hex','node4-LPC1124_303-1_35_0.hex',
|
|
'unrelated-0_98_5.hex'):
|
|
(root/name).write_text('fixture')
|
|
self.assertEqual(node_firmware_version(root),'1.35.0')
|
|
(root/'coil4node-LPC1313-1_33_0.hex').write_text('fixture')
|
|
with self.assertRaisesRegex(ValueError,'conflicting'):
|
|
node_firmware_version(root)
|
|
|
|
def test_selected_sd_and_exact_update_files_are_staged_without_mutating_inputs(self):
|
|
with tempfile.TemporaryDirectory() as temporary:
|
|
root=Path(temporary);inventory=root/'runtimes';vendor=root/'vendor';vendor.mkdir()
|
|
(vendor/'SOURCE.json').write_text('{"commit":"fixture"}')
|
|
for identity,ver,system in [('sd81','0.81.0','sd81'),('sd83','0.83.0','sd83'),('update','0.85.0','sd81')]:
|
|
runtime=inventory/identity
|
|
(runtime/'partition-02/lib').mkdir(parents=True)
|
|
(runtime/'partition-02/lib/runtime.txt').write_text(identity)
|
|
(runtime/'game-files').mkdir()
|
|
(runtime/'game-files/game').write_bytes(b'\x7fELF'+identity.encode())
|
|
(runtime/'game-files/game').chmod(0o644)
|
|
(runtime/'game-files/assets').write_text('assets-'+identity)
|
|
(runtime/'runtime.json').write_text(json.dumps(dict(schema=2,snapshot=identity,
|
|
system_snapshot=system,architecture='aarch64',system_root='partition-02',
|
|
game_root='game-files',targets={'game':'game'},
|
|
release={'repository':'Pokémon','version':ver})))
|
|
with patch('bundles.builder.VENDOR',vendor):
|
|
record=stage(inventory,'update',root/'bundle')
|
|
self.assertEqual(record['runtime_id'],'sd83')
|
|
staged=root/'bundle/source-root'
|
|
self.assertEqual((staged/'lib/runtime.txt').read_text(),'sd83')
|
|
self.assertEqual((staged/'games/game').read_bytes(),b'\x7fELFupdate')
|
|
self.assertEqual((staged/'games/assets').read_text(),'assets-update')
|
|
self.assertTrue((staged/'games/game').stat().st_mode & 0o111)
|
|
self.assertEqual((inventory/'update/game-files/game').stat().st_mode & 0o777,0o644)
|
|
self.assertEqual((inventory/'sd83/partition-02/lib/runtime.txt').read_text(),'sd83')
|
|
|
|
def test_zip_retains_launch_modes_and_links_without_duplicate_source_tree(self):
|
|
with tempfile.TemporaryDirectory() as temporary:
|
|
root=Path(temporary);source=root/'bundle';source.mkdir()
|
|
(source/'Launch.command').write_text('#!/bin/sh\n');(source/'Launch.command').chmod(0o755)
|
|
(source/'alias').symlink_to('Launch.command')
|
|
(source/'source-root').mkdir();(source/'source-root/game').write_text('private build source')
|
|
write_zip(source,root/'bundle.zip')
|
|
with zipfile.ZipFile(root/'bundle.zip') as archive:
|
|
self.assertEqual(archive.read('alias'),b'Launch.command')
|
|
self.assertEqual((archive.getinfo('Launch.command').external_attr >> 16)&0o777,0o755)
|
|
self.assertNotIn('source-root/game',archive.namelist())
|