pull/36091/head
Trey Moen 4 days ago
parent 3004059e7a
commit 07455c77d8
  1. 18
      system/hardware/base.py
  2. 46
      system/hardware/tests/test_lpa_validation.py
  3. 4
      system/hardware/tici/esim.py
  4. 3
      system/hardware/tici/tests/test_esim.py

@ -10,9 +10,6 @@ NetworkType = log.DeviceState.NetworkType
class LPAError(RuntimeError):
pass
class LPAProfileNotFoundError(LPAError):
pass
@dataclass
class Profile:
iccid: str
@ -97,24 +94,19 @@ class LPABase(ABC):
def is_comma_profile(self, iccid: str) -> bool:
return any(iccid.startswith(prefix) for prefix in ('8985235',))
def _validate_iccid(self, iccid: str) -> None:
def validate_iccid(self, iccid: str) -> None:
# https://en.wikipedia.org/wiki/E.118#ICCID
assert re.match(r'^89\d{17,18}$', iccid), 'invalid ICCID format. expected format: 8988303000000614227'
def _validate_lpa_activation_code(self, lpa_activation_code: str) -> None:
def validate_lpa_activation_code(self, lpa_activation_code: str) -> None:
assert re.match(r'^LPA:1\$.+\$.+$', lpa_activation_code), 'invalid LPA activation code format. expected format: LPA:1$domain$code'
def _validate_nickname(self, nickname: str) -> None:
def validate_nickname(self, nickname: str) -> None:
assert len(nickname) >= 1 and len(nickname) <= 16, 'nickname must be between 1 and 16 characters'
assert re.match(r'^[a-zA-Z0-9-_ ]+$', nickname), 'nickname must contain only alphanumeric characters, hyphens, underscores, and spaces'
def _validate_profile_exists(self, iccid: str) -> None:
if not any(p.iccid == iccid for p in self.list_profiles()):
raise LPAProfileNotFoundError(f'profile {iccid} does not exist')
def _validate_successful(self, msgs: list[dict]) -> None:
assert len(msgs) > 0, 'expected at least one message'
assert msgs[-1]['payload']['message'] == 'success', 'expected success notification'
def validate_profile_exists(self, iccid: str) -> None:
assert any(p.iccid == iccid for p in self.list_profiles()), f'profile {iccid} does not exist'
class HardwareBase(ABC):
@staticmethod

@ -1,9 +1,12 @@
import pytest
from openpilot.system.hardware.base import LPABase, LPAProfileNotFoundError, Profile
from openpilot.system.hardware.base import LPABase, Profile
class TestLPABase(LPABase):
class MockLPA(LPABase):
def bootstrap(self) -> None:
pass
def list_profiles(self) -> list[Profile]:
return []
@ -27,54 +30,45 @@ class TestLPABase(LPABase):
class TestLPAValidation:
def setup_method(self):
self.lpa = TestLPABase()
self.lpa = MockLPA()
def test_validate_iccid(self):
self.lpa._validate_iccid('8988303000000614227')
self.lpa.validate_iccid('8988303000000614227')
with pytest.raises(AssertionError, match='invalid ICCID format'):
self.lpa._validate_iccid('')
self.lpa.validate_iccid('')
with pytest.raises(AssertionError, match='invalid ICCID format'):
self.lpa._validate_iccid('1234567890123456789') # Doesn't start with 89
self.lpa.validate_iccid('1234567890123456789') # Doesn't start with 89
def test_validate_lpa_activation_code(self):
self.lpa._validate_lpa_activation_code('LPA:1$rsp.truphone.com$QRF-BETTERROAMING-PMRDGIR2EARDEIT5')
self.lpa.validate_lpa_activation_code('LPA:1$rsp.truphone.com$QRF-BETTERROAMING-PMRDGIR2EARDEIT5')
with pytest.raises(AssertionError, match='invalid LPA activation code format'):
self.lpa._validate_lpa_activation_code('')
self.lpa.validate_lpa_activation_code('')
with pytest.raises(AssertionError, match='invalid LPA activation code format'):
self.lpa._validate_lpa_activation_code('LPA:1$domain.com') # Missing third part
self.lpa.validate_lpa_activation_code('LPA:1$domain.com') # Missing third part
def test_validate_nickname(self):
self.lpa._validate_nickname('test_profile')
self.lpa.validate_nickname('test_profile')
with pytest.raises(AssertionError, match='nickname must be between 1 and 16 characters'):
self.lpa._validate_nickname('')
self.lpa.validate_nickname('')
with pytest.raises(AssertionError, match='nickname must contain only alphanumeric characters'):
self.lpa._validate_nickname('test.profile') # Contains invalid character
def test_validate_successful(self):
self.lpa._validate_successful([{'payload': {'message': 'success'}}])
with pytest.raises(AssertionError, match='expected at least one message'):
self.lpa._validate_successful([])
with pytest.raises(AssertionError, match='expected success notification'):
self.lpa._validate_successful([{'payload': {'message': 'error'}}])
self.lpa.validate_nickname('test.profile') # Contains invalid character
def test_validate_profile_exists(self, mocker):
existing_profiles = [Profile(iccid='8988303000000614227', nickname='test1', enabled=True, provider='Test Provider')]
mocker.patch.object(self.lpa, 'list_profiles', return_value=existing_profiles)
self.lpa._validate_profile_exists('8988303000000614227')
self.lpa.validate_profile_exists('8988303000000614227')
mocker.patch.object(self.lpa, 'list_profiles', return_value=[])
with pytest.raises(LPAProfileNotFoundError, match='profile 8988303000000614227 does not exist'):
self.lpa._validate_profile_exists('8988303000000614227')
with pytest.raises(AssertionError, match='profile 8988303000000614227 does not exist'):
self.lpa.validate_profile_exists('8988303000000614227')
mocker.patch.object(self.lpa, 'list_profiles', return_value=existing_profiles)
with pytest.raises(LPAProfileNotFoundError, match='profile 8988303000000614229 does not exist'):
self.lpa._validate_profile_exists('8988303000000614229')
with pytest.raises(AssertionError, match='profile 8988303000000614229 does not exist'):
self.lpa.validate_profile_exists('8988303000000614229')

@ -134,3 +134,7 @@ class TiciLPA(LPABase):
Process notifications stored on the eUICC, typically to activate/deactivate the profile with the carrier.
"""
self._validate_successful(self._invoke('notification', 'process', '-a', '-r'))
def _validate_successful(self, msgs: list[dict]) -> None:
assert len(msgs) > 0, 'expected at least one message'
assert msgs[-1]['payload']['message'] == 'success', 'expected success notification'

@ -1,7 +1,6 @@
import pytest
from openpilot.system.hardware import HARDWARE, TICI
from openpilot.system.hardware.base import LPAProfileNotFoundError
# https://euicc-manual.osmocom.org/docs/rsp/known-test-profile
# iccid is always the same for the given activation code
@ -14,7 +13,7 @@ def cleanup():
lpa = HARDWARE.get_sim_lpa()
try:
lpa.delete_profile(TEST_ICCID)
except LPAProfileNotFoundError:
except AssertionError:
pass
lpa.process_notifications()

Loading…
Cancel
Save