同步移动端工程、设备控制改进与发布资料
This commit is contained in:
@@ -133,6 +133,31 @@ def test_failed_install_restores_system_bytes_and_running_state(host):
|
||||
assert ['systemctl', 'start', c.FRP] in host
|
||||
|
||||
|
||||
def test_mobile_rollback_restores_files_masks_and_running_state(host):
|
||||
journal, record = make_journal()
|
||||
record['mobile_services'] = {
|
||||
'aw859-bluetooth.service': {'enabled_state': 'masked', 'active': False},
|
||||
'bluetooth.service': {'enabled_state': 'enabled', 'active': True},
|
||||
}
|
||||
record['files']['bluetooth-original'] = None
|
||||
for name in c.MOBILE_FILES:
|
||||
c.FILES[name].write_bytes(b'changed-by-mobile-install')
|
||||
c.restore_components(journal, record)
|
||||
assert not c.FILES['bluetooth-original'].exists()
|
||||
for name in set(c.MOBILE_FILES) - {'bluetooth-original'}:
|
||||
assert c.FILES[name].read_bytes() == ('old-' + name).encode()
|
||||
assert ['systemctl', 'mask', 'aw859-bluetooth.service'] in host
|
||||
assert ['systemctl', 'enable', 'bluetooth.service'] in host
|
||||
assert ['systemctl', 'start', 'bluetooth.service'] in host
|
||||
assert ['systemctl', 'start', 'aw859-bluetooth.service'] not in host
|
||||
|
||||
|
||||
def test_legacy_component_journal_does_not_touch_bluetooth(host):
|
||||
journal, record = make_journal()
|
||||
c.restore_components(journal, record)
|
||||
assert not any(unit in args for args in host for unit in c.MOBILE_SERVICES)
|
||||
|
||||
|
||||
def test_power_loss_between_data_renames_recovers_original(host):
|
||||
journal, record = make_journal()
|
||||
(c.DATA/'user-content').write_bytes(b'unchanged')
|
||||
@@ -181,6 +206,35 @@ def test_normal_migration_does_not_touch_components(host):
|
||||
assert host == []
|
||||
|
||||
|
||||
def test_mobile_only_patch_enters_durable_component_transaction(host, monkeypatch):
|
||||
from types import SimpleNamespace
|
||||
source = c.RELEASES / '1.1.2-mobilepatch'
|
||||
source.mkdir()
|
||||
(source / 'VERSION').write_text('1.1.2', encoding='utf-8')
|
||||
(source / 'scripts').mkdir()
|
||||
(source / 'scripts/install_mobile_bluetooth.sh').write_text('# test fixture', encoding='utf-8')
|
||||
candidate = c.DATA.with_name('matrix-screen-controller.ota.mobilepatch')
|
||||
candidate.mkdir()
|
||||
c.RUNTIME.mkdir(parents=True, exist_ok=True)
|
||||
(c.RUNTIME / 'ota-request.json').write_text(json.dumps({
|
||||
'job_id': 'mobilepatch', 'current_version': '1.1.1', 'target_version': '1.1.2'
|
||||
}), encoding='utf-8')
|
||||
monkeypatch.setattr(c.os, 'geteuid', lambda: 0, raising=False)
|
||||
monkeypatch.setattr(c.os, 'uname', lambda: SimpleNamespace(machine='aarch64'), raising=False)
|
||||
monkeypatch.setattr(c, 'check_installed', lambda *args: None)
|
||||
monkeypatch.setattr(c, 'protect_runtime', lambda: None)
|
||||
monkeypatch.setattr(c, 'mirror_permissions', lambda *args: None)
|
||||
# Host test verifies transaction ordering; POSIX durability is covered by
|
||||
# real Linux lifecycle checks, not Windows read-only descriptor fsync.
|
||||
monkeypatch.setattr(c.os, 'fsync', lambda *args: None)
|
||||
c.begin(source, candidate)
|
||||
record = json.loads((c.DATA / c.JOURNAL / 'state.json').read_text(encoding='utf-8'))
|
||||
assert set(record['mobile_services']) == set(c.MOBILE_SERVICES)
|
||||
assert (candidate / c.JOURNAL / 'state.json').is_file()
|
||||
assert ['/bin/sh', str(source / 'scripts/install_mobile_bluetooth.sh')] in host
|
||||
assert not any('install_frpc_system.sh' in str(arg) for args in host for arg in args)
|
||||
|
||||
|
||||
def release_project(tmp_path, monkeypatch):
|
||||
from scripts import export_release as exporter
|
||||
source = tmp_path / 'software'
|
||||
|
||||
Reference in New Issue
Block a user