blob: b8d255fa184b9ba637725de286e37655a6897610 [file] [log] [blame]
# Copyright (c) 2020 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import dbus
import logging
import random
from autotest_lib.client.bin import test
from autotest_lib.client.common_lib import error
from autotest_lib.client.cros.cellular import cellular_logging
from autotest_lib.client.cros.cellular import hermes_constants
from autotest_lib.client.cros.networking import hermes_proxy
from autotest_lib.client.cros.networking import mm1_proxy
log = cellular_logging.SetupCellularLogging('HermesEuiccEnableDisableTest')
class cellular_HermesEuiccEnableDisable(test.test):
"""
Tests Enable and Disable functions on active/inactive Euicc present
This test fails when not able to Enable/Disable a given Euicc profile
"""
version = 1
def _connect_to_hermes(self):
"""
Attempts to connect to a DBus object.
@raises: error.TestFail if connection fails.
"""
self.hermes_manager = 'None'
try:
self.hermes_manager = \
hermes_proxy.HermesManagerProxy().get_hermes_manager()
except dbus.DBusException as e:
logging.error('get_hermes_manager error: %s', e)
raise error.TestFail('Connect to Hermes failed')
if self.hermes_manager is 'None':
raise error.TestFail('In Test Could not get connection to Hermes')
def EnableTest(self, euicc_path):
""" Validates enable profile api DBus call """
try:
euicc = self.hermes_manager.get_euicc(euicc_path)
# Profile objects maybe stale if IsActive is false
# Switch to the euicc we are interested in before
# performing an op.
euicc.request_installed_profiles()
if not euicc:
raise error.TestFail('No active euicc,'
'try install profile and euicc on dut')
installed_profiles = euicc.get_installed_profiles()
if not installed_profiles:
raise error.TestFail('No active profile,'
'try install profiles on euicc')
inactive_profile_found = False
# Find inactive profile and enable
for profile in installed_profiles.values():
logging.info("profile to enable is : %s", profile)
props = profile.properties()
state = props.get('State')
if hermes_constants.ProfileStateToString(state) == 'INACTIVE':
inactive_profile_found = True
profile.enable()
logging.info('EnableTest succeeded')
break
if not inactive_profile_found:
raise error.TestFail('EnableTest failed - No inactive profile')
#Check profile state Active or not and all other profiles disabled
except dbus.DBusException as e:
logging.error('Profile enable error: %s', e)
raise error.TestFail('Enable Failed')
def DisableTest(self, euicc_path):
""" Validates disable profile api DBus call """
try:
euicc = self.hermes_manager.get_euicc(euicc_path)
euicc.request_installed_profiles()
if not euicc:
raise error.TestFail('No active euicc,'
'try install euicc and profile on dut')
installed_profiles = euicc.get_installed_profiles()
if not installed_profiles:
raise error.TestFail('No active profile,'
'try install profiles on euicc')
active_profile_found = False
# Find active profile and disable
for profile in installed_profiles.values():
logging.info("profile to disable is : %s", profile)
props = profile.properties()
state = props.get('State')
if hermes_constants.ProfileStateToString(state) == 'ACTIVE':
active_profile_found = True
profile.disable()
logging.info('DisableTest succeeded')
break
if not active_profile_found:
raise error.TestFail('DisableTest failed - No active profile')
except dbus.DBusException as e:
logging.error('Resulted profile disable error: %s', e)
raise error.TestFail('Disable Failed')
def InstallProfileTest(self, euicc_path):
"""
Validates InstallProfileFromActivationCode api on test euicc
use SMDP calls to find iccid, activation code from pending profiles
and install those profiles, this requires profiles generated based
on EID of test esims in lab devices
"""
if self.is_prod_ci:
raise error.TestFail(
'No support for InstallProfileTest with prod CI')
try:
# get all pending profiles which are generated on DUT EID
# Read all profiles activation code from pending profile dict
# Install a profile from activation code, keep iccid as well
# Check the presence of this profile after installation
activation_code = None
confirmation_code = ""
iccid = None
euicc = None
euicc = self.hermes_manager.get_euicc(euicc_path)
if not euicc:
logging.error('No Euicc enumerated')
return False
logging.info('euicc chosen: %s', euicc_path)
profiles_pending = euicc.get_pending_profiles()
if not profiles_pending:
logging.error("No pending profile found")
return False
profile_path_to_install = list(profiles_pending.keys())[0]
profile_to_install = profiles_pending[profile_path_to_install]
logging.debug('First pending profile: %s', profile_path_to_install)
props = profile_to_install.properties()
iccid = props.get('Iccid')
activation_code = props.get('ActivationCode')
logging.info('Installing iccid: %s act_code:%s conf_code:%s',
iccid, activation_code, confirmation_code)
# Install
euicc.install_profile_from_activation_code(
activation_code, confirmation_code)
# Check if iccid found in installed profiles, installation success
profiles_installed = euicc.get_installed_profiles()
if not profiles_installed:
logging.error("Zero profiles installed")
raise error.TestFail('InstallProfileTest failed No Installed'
'profile found')
for profile in profiles_installed.values():
props = profile.properties()
if iccid == props.get('Iccid'):
self.iccid_installed = iccid
self.profile_installed = profile
logging.info('InstallProfileTest succeeded')
return True
logging.error("Installed profile not found test failed")
raise error.TestFail('InstallProfileTest failed, Just installed'
'Iccid not found')
except dbus.DBusException as e:
logging.error("Failed to install a pending profile")
if e.get_dbus_name() not in self.ok_errors:
raise error.TestFail('InstallProfileTest failed with %s',
repr(e))
def InstallPendingProfileTest(self, euicc_path):
"""
Validates InstallPendingProfile api on test euicc
Find a profile from list of esim pending profiles which is not
installed yet and install that profile
Required to create pending profiles for each EID(euicc sim) in lab dut.
create profiles from stork giving lab devices EID puts profiles in
pending state for that euicc when RequestPendingProfiles called.
Do install and immediately uninstall to keep those profiles in
pending state
"""
profile_to_install = None
euicc = self.hermes_manager.get_euicc(euicc_path)
if not euicc:
logging.info('No euicc on DUT: %s', euicc)
profiles_pending = euicc.get_pending_profiles()
if not profiles_pending:
logging.info("No pending profile found")
return False
profile_path_to_install = list(profiles_pending.keys())[0]
profile_to_install = profiles_pending[profile_path_to_install]
logging.debug('First pending profile: %s', profile_path_to_install)
props = profile_to_install.properties()
iccid = props.get('Iccid')
activation_code = props.get('ActivationCode')
logging.info('Installing profile:%s iccid: %s act_code: %s',
profile_path_to_install, iccid, activation_code)
try:
# Install
profile = euicc.install_pending_profile(
profile_path_to_install, "")
logging.info('Installed pending profile is %s', profile)
if not profile:
logging.error('No profile object returned after install')
return False
except dbus.DBusException as e:
logging.error("Failed to install pending profile error:%s", e)
raise error.TestFail('Failed to install pending profile')
# Find above installed profile, if not exists raise test failure
installed_profiles = euicc.get_installed_profiles()
if installed_profiles[profile_path_to_install] is None:
raise error.TestFail('Install pending profile failed :%s',
profile_path_to_install)
# Do uninstall the just installed profile if it has > 2 profiles
if len(installed_profiles) > 2:
logging.info('Uninstalling installed pending profile')
euicc.uninstall_profile(profile)
logging.info('InstallPendingProfileTest succeeded')
return True
def UninstallTest(self, euicc_path):
"""
Validates UninstallProfile api by uninstalling any randomly
selected installed profile
"""
if self.is_prod_ci:
raise error.TestFail("Cannot run uninstall test on eUICC's "
"with prod CI")
logging.info('UninstallTest start')
# Getinstalled profiles list and randomly uninstall a profile
try:
euicc = self.hermes_manager.get_euicc(euicc_path)
if not euicc:
logging.info('No euicc to uninstall any profile')
return False
profiles_installed = euicc.get_installed_profiles()
uninstalled_profile = None
for profile_path, profile in profiles_installed.items():
# Hermes does not support uninstalling test profiles yet.
if hermes_constants.ProfileClassToString(
profile.profileclass) != 'TESTING':
logging.info("profile to uninstall is : %s", profile_path)
euicc.uninstall_profile(profile_path)
uninstalled_profile = profile_path
logging.info('UninstallTest succeeded')
break
if not uninstalled_profile:
raise error.TestFail(
'UninstallTest failed - No uninstallable profile')
#Try to find the uninstalled profile, if exists raise test failure
profiles_installed = {}
profiles_installed = euicc.get_installed_profiles()
for profile in profiles_installed.keys():
if uninstalled_profile in profile:
raise error.TestFail('Uninstall profile Failed')
logging.info('UninstallTest succeeded')
return True
except dbus.DBusException as e:
raise error.TestFail('Failed to uninstall profile %s', e)
def run_once(self, is_prod_ci=False):
""" Enable Disable Euicc by enabling or disabling a profile """
self.is_prod_ci = is_prod_ci
self.ok_errors = ['org.freedesktop.ModemManager1.Error.Core.InProgress'
'Timed out connecting to ModemManager1']
try:
mm1_proxy.ModemManager1Proxy.get_proxy().inhibit_device(
dbus.Boolean('true'))
except dbus.exceptions.DBusException as error:
if error.get_dbus_name() not in self.ok_errors:
raise error
logging.info('Connect to Hermes attempt')
self._connect_to_hermes()
self.hermes_manager.refresh_profiles()
# Always euicc/0 is prod one and euicc/1 is for test esim profiles
self.prod_euicc_path = "/org/chromium/Hermes/euicc/0"
self.test_euicc_path = "/org/chromium/Hermes/euicc/1"
euicc_path = self.prod_euicc_path if self.is_prod_ci \
else self.test_euicc_path
self.hermes_manager.set_test_mode(not self.is_prod_ci)
if not self.is_prod_ci:
is_smds_test = random.choice([True, False])
logging.info('is_smds_test %s', is_smds_test)
if is_smds_test:
self.InstallPendingProfileTest(euicc_path)
else:
self.InstallProfileTest(euicc_path)
self.EnableTest(euicc_path)
self.DisableTest(euicc_path)
if not self.is_prod_ci:
self.UninstallTest(euicc_path)
logging.info('Test Completed')