Live-USB durch eigenständige Anwendung ersetzen
Some checks failed
Tests / test (push) Has been cancelled

This commit is contained in:
2026-10-15 10:26:33 +02:00
parent 692bbbb815
commit 1f91db25b5
23 changed files with 205 additions and 1228 deletions

View File

@@ -4,41 +4,64 @@ from pathlib import Path
import tempfile
import unittest
from unittest.mock import patch
ROOT = Path(__file__).resolve().parents[1]
spec = importlib.util.spec_from_file_location('release_manifest', ROOT / 'scripts/release-manifest.py')
spec = importlib.util.spec_from_file_location(
'release_manifest', ROOT / 'scripts/release-manifest.py'
)
release = importlib.util.module_from_spec(spec)
spec.loader.exec_module(release)
class ReleaseTests(unittest.TestCase):
def test_source_id_is_stable(self):
self.assertEqual(release.source_id(), release.source_id())
self.assertTrue(release.source_id().startswith('csr-'))
self.assertEqual(set(release.COMPONENTS.values()), {'intake-gui', 'pc-intake'})
def test_profile_rejects_stale_binary(self):
def make_release(self, root):
for name in release.COMPONENTS.values():
binary = root / name
binary.write_bytes(name.encode())
binary.chmod(0o755)
manifest = {
'schema_version': 1,
'build_id': 'csr-test',
'binaries': {
name: {'sha256': release.digest(root / name)}
for name in release.COMPONENTS.values()
},
}
(root / 'release.json').write_text(json.dumps(manifest))
def test_release_rejects_stale_binary(self):
with tempfile.TemporaryDirectory() as tmp:
profile = Path(tmp)
base = profile / 'airootfs'
(base / 'etc/csr-intake').mkdir(parents=True)
(base / 'usr/local/bin').mkdir(parents=True)
binary = base / 'usr/local/bin/intake-gui'
binary.write_bytes(b'original binary'); binary.chmod(0o755)
manifest = {'build_id':'csr-test','binaries':{'intake-gui':{'sha256':release.digest(binary)}}}
(base / 'etc/csr-intake/release.json').write_text(json.dumps(manifest))
binary.write_bytes(b'stale binary')
root = Path(tmp)
self.make_release(root)
(root / 'intake-gui').write_bytes(b'stale binary')
with self.assertRaisesRegex(ValueError, 'hash mismatch'):
release.verify(profile)
release.verify(root)
def test_complete_profile_is_verified(self):
def test_complete_release_is_verified(self):
with tempfile.TemporaryDirectory() as tmp:
profile=Path(tmp); base=profile/'airootfs'
for file in ['etc/csr-intake/release.json', 'usr/local/bin/intake-gui', 'usr/local/bin/intake-login', 'usr/local/bin/intake-prepare', 'etc/systemd/system/getty@tty1.service.d/autologin.conf', 'etc/systemd/system/multi-user.target.wants/NetworkManager.service']:
path=base/file;path.parent.mkdir(parents=True,exist_ok=True);path.write_text('fixture')
binary=base/'usr/local/bin/intake-gui';binary.chmod(0o755)
(base/'etc/csr-intake/release.json').write_text(json.dumps({'build_id':'csr-test','binaries':{'intake-gui':{'sha256':release.digest(binary)}}}))
packages=['networkmanager','curl','ca-certificates','python','usbutils','smartmontools','alsa-utils','ffmpeg','stress-ng','xdg-utils','firefox']
(profile/'packages.x86_64').write_text('\n'.join(packages))
with patch.object(release.subprocess,'check_output',return_value='GUI csr-test'):
release.verify(profile)
(profile/'packages.x86_64').write_text('networkmanager')
with self.assertRaisesRegex(ValueError,'Missing live package'):
release.verify(profile)
root = Path(tmp)
self.make_release(root)
with patch.object(release.subprocess, 'check_output', return_value='GUI csr-test'):
release.verify(root)
(root / 'pc-intake').chmod(0o644)
with self.assertRaisesRegex(ValueError, 'not executable'):
release.verify(root)
def test_release_requires_exact_component_set(self):
with tempfile.TemporaryDirectory() as tmp:
root = Path(tmp)
self.make_release(root)
manifest = json.loads((root / 'release.json').read_text())
manifest['binaries'].pop('pc-intake')
(root / 'release.json').write_text(json.dumps(manifest))
with self.assertRaisesRegex(ValueError, 'missing or unexpected'):
release.verify(root)
if __name__ == '__main__':
unittest.main()