Files
StarPilot/openpilot/starpilot/ui/tests/test_software_update.py
T
firestar5683 a82935f326 User interfaces and Android Auto
Integrate onroad views, configurable widgets, local settings, steering-profile contracts, Bluetooth and Android Auto with their device and runtime services.

Co-authored-by: Adeeb Shihadeh <adeebshihadeh@gmail.com>
Co-authored-by: Daniel Koepping <elkoled@gmail.com>
Co-authored-by: Danny <dannyirwin31@yahoo.com>
Co-authored-by: DimitriChrysafis <Dimitri.chrysafis@gmail.com>
Co-authored-by: Dom <168790843+firestar5683@users.noreply.github.com>
Co-authored-by: Harald Schäfer <harald.the.engineer@gmail.com>
Co-authored-by: Prabhaav Pillai <prabhaav@msu.edu>
Co-authored-by: Shane Smiskol <shane@smiskol.com>
Co-authored-by: dirwin31 <83434411+dirwin31@users.noreply.github.com>
Co-authored-by: firestarsdog <229254897+firestarsdog@users.noreply.github.com>
Co-authored-by: stef <19478336+stefpi@users.noreply.github.com>
Co-authored-by: whoisdomi <dcantu83@gmail.com>

Co-authored-by: Intelli <contact@intelli.software>
Co-authored-by: pharmacomaniac <blittle65@gmail.com>

Co-authored-by: prabhaavp <prabhaav@msu.edu>
2026-10-14 20:02:39 -05:00

85 lines
3.1 KiB
Python

from types import SimpleNamespace
from unittest.mock import patch
from openpilot.starpilot.ui.software_update import NativeSoftwareUpdate
class ImmediateThread:
def __init__(self, target, daemon):
self.target = target
def start(self):
self.target()
def test_native_selected_branch_and_rollback_use_existing_owner():
calls = []
status = {"installed": {"branch": "Dom"}, "updater": {"fast": {"detail": "Receiving objects: 50%"}}}
owner = SimpleNamespace(
status=SimpleNamespace(snapshot=lambda: dict(status)),
snapshot=lambda: {"selectedTarget": "Other", "canFastUpdate": True, "canRollback": True},
action=lambda action, payload, authorized: calls.append((action, payload, authorized())),
)
with (
patch('openpilot.starpilot.ui.software_update.SoftwareOperations', return_value=owner),
patch('openpilot.starpilot.ui.software_update.threading.Thread', ImmediateThread),
):
update = NativeSoftwareUpdate(lambda: True)
update.refresh()
assert update.detail() == "Receiving objects: 50%"
assert update.available('fast')
assert update.submit('fast')
assert update.submit('rollback')
assert calls == [('fast', {'action': 'fast', 'branch': 'Other'}, True), ('rollback', {'action': 'rollback', 'branch': 'Dom'}, True)]
def test_native_fresh_permission_loss_prevents_submission():
allowed = [True]
with patch('openpilot.starpilot.ui.software_update.SoftwareOperations') as owner:
update = NativeSoftwareUpdate(lambda: allowed[0])
allowed[0] = False
assert not update.submit('fast')
owner.return_value.action.assert_not_called()
def test_native_refresh_keeps_actions_stable_and_submission_blocks_them():
queued, calls = [], []
class DeferredThread(ImmediateThread):
def start(self):
queued.append(self.target)
status = {"installed": {"branch": "Dom"}, "updater": {"fast": {"detail": "Already up to date."}}}
owner = SimpleNamespace(
status=SimpleNamespace(snapshot=lambda: dict(status)),
snapshot=lambda: {"selectedTarget": "Dom", "canFastUpdate": True, "canRollback": True},
action=lambda action, payload, authorized: calls.append(action),
)
with (
patch('openpilot.starpilot.ui.software_update.SoftwareOperations', return_value=owner),
patch('openpilot.starpilot.ui.software_update.threading.Thread', DeferredThread),
):
update = NativeSoftwareUpdate(lambda: True)
update.refresh()
assert not update.available('fast')
queued.pop(0)()
update.error = "Transient read failure"
update.next_refresh = 0
update.refresh()
assert update.available('fast') and update.available('rollback')
update.refresh()
assert len(queued) == 1
queued.pop(0)()
assert update.detail() == "Already up to date."
update.next_refresh = 0
update.refresh()
assert update.submit('fast')
assert not update.available('fast') and not update.available('rollback')
assert not update.submit('rollback')
queued.pop(0)()
assert not update.available('fast')
assert calls == []
queued.pop(0)()
assert calls == ['fast']
assert update.available('fast') and update.available('rollback')