VulpesOS/tundra/tests/test_standalone_restore.py
OverSu 0041cd9660 Update shared Gaia workflows and Sargo development tooling
Fix camera switching and Contacts/SMS activity routing across shared hosts.
Integrate Marketplace installation and native standalone recovery tools,
Bluetooth runtime packages and trusted certificates.

Update English/French READMEs and the shared changelog with tested scope
and remaining radio/audio/Bluetooth limitations. Preview17 remains the
existing APK; no new native image is released.

Validation: shared JavaScript and native Python tests; Android packaging
and payload parity from an isolated publication checkout.
2026-10-08 14:27:17 +02:00

69 lines
3 KiB
Python

# SPDX-License-Identifier: MPL-2.0
import gzip
import hashlib
import importlib.util
import json
from pathlib import Path
import sys
import tempfile
import unittest
from unittest.mock import patch
spec = importlib.util.spec_from_file_location('restore', Path(__file__).resolve().parents[1]/'tools/restore-standalone-sargo.py')
restore = importlib.util.module_from_spec(spec)
spec.loader.exec_module(restore)
class RestoreTests(unittest.TestCase):
def make_backup(self, folder):
payload = b'original userdata\0' * 100
sha = hashlib.sha256(payload).hexdigest()
data = {'archive': 'userdata-original.raw.gz', 'bytes': len(payload),
'sha256': sha, 'checked': True, 'sourceWasUnmounted': True}
(folder/data['archive']).write_bytes(gzip.compress(payload))
(folder/'userdata.json').write_text(json.dumps(data))
files = {}
for name in ('boot_a.img', 'dtbo_a.img', 'vbmeta_a.img'):
content = name.encode()
(folder/name).write_bytes(content)
files[name] = {'bytes': len(content), 'sha256': hashlib.sha256(content).hexdigest()}
manifest = {'device': 'sargo', 'activeSlot': 'a', 'files': files,
'userdataSha256': sha, 'userdataBytes': len(payload)}
(folder/'recovery.json').write_text(json.dumps(manifest))
return manifest
def test_review_verifies_backup_without_phone_commands(self):
with tempfile.TemporaryDirectory() as directory:
folder = Path(directory)
self.make_backup(folder)
with patch.object(sys, 'argv', ['restore', '--backup', directory]), \
patch.object(restore.subprocess, 'run') as run, \
patch.object(restore.subprocess, 'check_output') as read:
restore.main()
run.assert_not_called()
read.assert_not_called()
def test_unbound_userdata_is_rejected(self):
with tempfile.TemporaryDirectory() as directory:
folder = Path(directory)
manifest = self.make_backup(folder)
manifest['userdataSha256'] = '0' * 64
(folder/'recovery.json').write_text(json.dumps(manifest))
with patch.object(sys, 'argv', ['restore', '--backup', directory]), \
patch.object(restore.subprocess, 'run') as run:
with self.assertRaisesRegex(ValueError, 'not bound'):
restore.main()
run.assert_not_called()
def test_altered_userdata_is_rejected(self):
with tempfile.TemporaryDirectory() as directory:
folder = Path(directory)
self.make_backup(folder)
(folder/'userdata-original.raw.gz').write_bytes(gzip.compress(b'changed'))
with patch.object(sys, 'argv', ['restore', '--backup', directory]):
with self.assertRaisesRegex(ValueError, 'Storage backup changed'):
restore.main()
if __name__ == '__main__':
unittest.main()