blob: 6366649691c0fbf78af89a7e8ea285b7cd14acad [file] [log] [blame]
# Copyright (c) 2021 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
import time
from autotest_lib.client.bin import test
from autotest_lib.client.common_lib import error
from autotest_lib.client.cros import upstart
from autotest_lib.client.cros.cellular import cellular_logging
from autotest_lib.client.cros.cellular import hermes_constants
from autotest_lib.client.cros.cellular import hermes_utils
from autotest_lib.client.cros.cellular import mm1_constants
from autotest_lib.client.cros.networking import mm1_proxy
log = cellular_logging.SetupCellularLogging('HermesRestartSlotSwitchTest')
class cellular_Hermes_Restart_SlotSwitch(test.test):
"""
This test randomly restarts hermes or switches slots in between hermes
operations.
The test fails if any of the hermes operations fail.
Prerequisites
1) For test CI:
Before running this test on test CI, a profile needs to be created on
go/stork-profile. The profile needs to be linked to the EID of the dut.
Profiles with class=operational and type=Android GTS test are known to work
well with this test.
We rely on the SMDS event to find the activation code for the test.
There is a limit of 99 downloads before the profile needs to be deleted and
recreated.(b/181723689)
2) For prod CI:
Install a production profile before running the test.
"""
version = 1
def restart_hermes(self):
""" Restarts Hermes daemon """
logging.debug('->restart_hermes start')
upstart.restart_job('hermes')
# hermes takes 15+ sec to load all apis, wait on hermes dbus not enough
time.sleep(hermes_constants.HERMES_RESTART_WAIT_SECONDS)
self.hermes_manager = hermes_utils.connect_to_hermes()
euicc = self.hermes_manager.get_euicc(self.euicc_path)
euicc.use_test_certs(not self.is_prod_ci)
logging.debug('restart_hermes done')
if not self.hermes_manager:
logging.error('restart_hermes failed, no hermes daemon')
raise error.TestFail('restart_hermes operation failed')
def slot_switch(self):
""" Perform SIM slot switch """
try:
# Get current slot and available slots and switch to slot 1 or 2
# using MM
logging.info('->slot_switch start')
hermes_utils.mm_inhibit(False, self.mm_proxy)
modem_proxy = self.mm_proxy.get_modem()
sim_slots = modem_proxy.get_sim_slots()
logging.debug('sim slots available: %d', sim_slots)
current_slot = modem_proxy.get_primary_sim_slot()
switch_to_slot = random.choice([1,2])
logging.info('current sim slot: %d switching to slot: %d',
current_slot, switch_to_slot)
modem_proxy.set_primary_slot(switch_to_slot)
# Wait for modem, as slot switch causes modem DBus reload
self.mm_proxy.wait_for_modem(
mm1_constants.MM_REPROBE_PROCESSING_TIME)
# TODO(b/182337446):
# Investigate why ModemManager1Proxy.get_proxy().get_modem()
# fails if called immediately after self.mm_proxy.wait_for_modem(
# mm1_constants.MM_REPROBE_PROCESSING_TIME)
time.sleep(mm1_constants.MM_REPROBE_PROCESSING_TIME)
self.mm_proxy = mm1_proxy.ModemManager1Proxy.get_proxy()
modem_proxy = self.mm_proxy.get_modem()
if not modem_proxy:
raise error.TestFail('slot_switch failed. No modem found')
new_slot = modem_proxy.get_primary_sim_slot()
logging.info('primary slot after switch: %d', new_slot)
# Shill changes the modemmanager slot if the active slot is empty,
# and the non-active slot has a sim. Thus we cannot confirm that MM
# comes back on new_slot. b/181346457
hermes_utils.mm_inhibit(True, self.mm_proxy)
logging.info('slot_switch success & the current active slot is: '
'%d\n', new_slot)
except dbus.DBusException as e:
logging.error('slot_switch failed')
raise error.TestFail('slot_switch failed', e)
def randomize_hermes_state(self):
"""
Randomly restart hermes and switch slots in between hermes operations.
@return Fails the test if any operation fails
"""
logging.info('==randomize_hermes_state start==')
# Call Restart hermes, Slot switch in random
operations = [self.restart_hermes, self.slot_switch]
logging.debug('randomly calling operations on hermes')
num_operations = random.randrange(len(operations)+1)
random.shuffle(operations)
operations = operations[:num_operations]
logging.info('The following operations will be performed in a '
'sequence : %s ', operations)
try:
[f() for f in operations]
logging.info('==randomize_hermes_state - done==')
except dbus.DBusException as e:
logging.error('randomize_hermes_state operation failed')
raise error.TestFail('Could not randomize hermes state', e)
def hermes_operations_test(self, euicc_path):
"""
Perform hermes operations with restart, slotswitch in between
Do Install, Enable, Disable, Uninstall operations combined with random
operations hermes restart, sim slot switch
@param euicc_path: available euicc dbus path as string
@return Fails the test if any operation fails
"""
try:
logging.info('hermes_operations_test start')
# Do restart, slotswitch and install, enable, disable, uninstall
self.randomize_hermes_state()
installed_iccid = None
logging.info('INSTALL:\n')
installed_iccid = hermes_utils.install_profile(
euicc_path, self.hermes_manager, self.is_prod_ci)
self.randomize_hermes_state()
logging.info('ENABLE:\n')
hermes_utils.enable_or_disable_profile_test(
euicc_path, self.hermes_manager, installed_iccid, True)
self.randomize_hermes_state()
logging.info('DISABLE:\n')
hermes_utils.enable_or_disable_profile_test(
euicc_path, self.hermes_manager, installed_iccid, False)
if not self.is_prod_ci:
self.randomize_hermes_state()
logging.info('UNINSTALL:\n')
hermes_utils.uninstall_profile_test(
euicc_path, self.hermes_manager, installed_iccid)
logging.info('===hermes_operations_test succeeded===\n')
except dbus.DBusException as e:
logging.error('hermes_operations with random hermes state failed')
raise error.TestFail('randomize_hermes_state with '
'hermes_operations failed', e)
def run_once(self, test_env, is_prod_ci=False):
"""
Perform hermes ops with random restart, refresh, sim slot switch
"""
self.test_env = test_env
self.is_prod_ci = is_prod_ci
self.mm_proxy, self.hermes_manager, self.euicc_path = \
hermes_utils.initialize_test(is_prod_ci)
self.hermes_operations_test(self.euicc_path)
logging.info('HermesRestartSlotSwitchTest Completed')