blob: d7d19e35695de064a1a53c1c66e3f15f1fb42006 [file] [log] [blame]
# Copyright (c) 2013 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.
from autotest_lib.client.bin import site_utils, test
from autotest_lib.client.common_lib import error
import dbus
import dbus.types
import os
import time
from autotest_lib.client.cros import backchannel
# Disable warning about flimflam_test_path not being used. It is used to set up
# the path to the flimflam module.
# pylint: disable=W0611
from autotest_lib.client.cros import flimflam_test_path
# pylint: enable=W0611
from autotest_lib.client.cros import network
from autotest_lib.client.cros.cellular import cell_tools
from autotest_lib.client.cros.cellular import mm
from autotest_lib.client.cros.cellular import mm1_constants
from autotest_lib.client.cros.cellular.pseudomodem import pseudomodem_context
import flimflam
I_ACTIVATION_TEST = 'Interface.CDMAActivationTest'
ACTIVATION_STATE_TIMEOUT = 10
MODEM_STATE_TIMEOUT = 10
TEST_MODEMS_MODULE_PATH = os.path.join(os.path.dirname(__file__), 'files',
'modems.py')
class ActivationTest(object):
"""
Super class that implements setup code that is common to the individual
tests.
"""
def __init__(self, test):
self.test = test
self.modem_properties_interface = None
def run(self):
"""
Restarts the pseudomodem with the modem object to be used for this
test and runs the test.
"""
with pseudomodem_context.PseudoModemManagerContext(
True,
flags_map=self._pseudomodem_flags()):
self._run_test()
def _get_modem_properties_interface(self):
if not self.modem_properties_interface:
self.modem_properties_interface = \
self.test.modem().PropertiesInterface()
return self.modem_properties_interface
def _set_modem_activation_state(self, state):
interface = self._get_modem_properties_interface()
interface.Set(
mm1_constants.I_MODEM_CDMA,
'ActivationState',
dbus.types.UInt32(state))
def _get_modem_activation_state(self):
interface = self._get_modem_properties_interface()
return interface.Get(mm1_constants.I_MODEM_CDMA,
'ActivationState')
def _pseudomodem_flags(self):
"""
Subclasses must override this method to setup the flags map passed to
pseudomodem to suite their needs.
"""
raise NotImplementedError()
def _run_test(self):
raise NotImplementedError()
class ActivationStateTest(ActivationTest):
"""
This test verifies that the service "ActivationState" property matches the
cdma activation state exposed by ModemManager.
"""
def _pseudomodem_flags(self):
return {'family' : 'CDMA'}
def _run_test(self):
network.ResetAllModems(self.test.flim)
# The modem state should be REGISTERED.
self.test.check_modem_state(mm1_constants.MM_MODEM_STATE_REGISTERED)
# Service should appear as 'activated'.
self.test.check_service_activation_state('activated')
# Service activation state should change to 'not-activated'.
self._set_modem_activation_state(
mm1_constants.MM_MODEM_CDMA_ACTIVATION_STATE_NOT_ACTIVATED)
self.test.check_service_activation_state('not-activated')
# Service activation state should change to 'activating'.
self._set_modem_activation_state(
mm1_constants.MM_MODEM_CDMA_ACTIVATION_STATE_ACTIVATING)
self.test.check_service_activation_state('activating')
# Service activation state should change to 'partially-activated'.
st = mm1_constants.MM_MODEM_CDMA_ACTIVATION_STATE_PARTIALLY_ACTIVATED
self._set_modem_activation_state(st)
self.test.check_service_activation_state('partially-activated')
# Service activation state should change to 'activated'.
self._set_modem_activation_state(
mm1_constants.MM_MODEM_CDMA_ACTIVATION_STATE_ACTIVATED)
self.test.check_service_activation_state('activated')
class ActivationSuccessTest(ActivationTest):
"""
This test verifies that the service finally bacomes "activated" when the
service is told to initiate OTASP activation.
"""
def _pseudomodem_flags(self):
return {'test-module' : TEST_MODEMS_MODULE_PATH,
'test-modem-class' : 'UnactivatedCdmaModem'}
def _run_test(self):
network.ResetAllModems(self.test.flim)
# The modem state should be REGISTERED.
self.test.check_modem_state(mm1_constants.MM_MODEM_STATE_REGISTERED)
# Service should appear as 'not-activated'.
self.test.check_service_activation_state('not-activated')
# Call 'CompleteActivation' on the service. The service should become
# 'activating'.
service = self.test.find_cellular_service()
service.CompleteCellularActivation()
self.test.check_service_activation_state('activating')
# The modem should reset in 5 seconds. Wait 5 more seconds to make sure
# a new service gets created.
time.sleep(10)
self.test.check_service_activation_state('activated')
class ActivationFailureRetryTest(ActivationTest):
"""
This test verifies that if "ActivateAutomatic" fails, a retry will be
scheduled.
"""
NUM_ACTIVATE_RETRIES = 5
def _pseudomodem_flags(self):
return {'test-module' : TEST_MODEMS_MODULE_PATH,
'test-modem-class' : 'ActivationRetryModem',
'test-modem-arg' : [self.NUM_ACTIVATE_RETRIES]}
def _run_test(self):
network.ResetAllModems(self.test.flim)
# The modem state should be REGISTERED.
self.test.check_modem_state(mm1_constants.MM_MODEM_STATE_REGISTERED)
# Service should appear as 'not-activated'.
self.test.check_service_activation_state('not-activated')
# Call 'CompleteActivation' on the service. The service should remain
# 'not-activated'.
service = self.test.find_cellular_service()
service.CompleteCellularActivation()
modem_props = self._get_modem_properties_interface()
while modem_props.Get(I_ACTIVATION_TEST, 'ActivateCount') < \
self.NUM_ACTIVATE_RETRIES:
self.test.check_service_activation_state('not-activated')
# Activation should succeed after the latest retry.
self.test.check_service_activation_state('activating')
# The modem should reset in 5 seconds. Wait 5 more seconds to make sure
# a new service gets created.
time.sleep(10)
self.test.check_service_activation_state('activated')
class network_CDMAActivate(test.test):
"""
Tests various scenarios that may arise during the post-payment CDMA
activation process when shill accesses the modem via ModemManager.
"""
version = 1
def modem(self):
"""
Returns a D-Bus proxy for the current modem object exposed by the
modem manager.
@return A dbus.service.Object instance.
"""
manager, modem_path = mm.PickOneModem('')
return manager.GetModem(modem_path)
def modem_state(self):
"""
Gets the current modem state from the current modem manager.
@return The modem state, as a uint32 value.
"""
modem = self.modem()
props = modem.GetAll(mm1_constants.I_MODEM)
return props['State']
def check_modem_state(self, expected_state, timeout=MODEM_STATE_TIMEOUT):
"""
Polls until the modem has the expected state within |timeout| seconds.
@param expected_state: The modem state the modem is expected to be in.
@param timeout: The timeout interval for polling.
@raises error.TestFail, if the modem doesn't transition to
|expected_state| within |timeout|.
"""
site_utils.poll_for_condition(
lambda: self.modem_state() == expected_state,
exception=error.TestFail('Timed out waiting for modem state ' +
str(expected_state)),
timeout=timeout);
def find_cellular_service(self):
"""
Searches for a cellular service and returns it.
@return A dbus.service.Object instance.
@raises error.TestFail, if no cellular service is found.
"""
service = self.flim.FindCellularService()
if not service:
raise error.TestFail('Could not find cellular service.')
return service
def check_service_activation_state(self, expected_state):
"""
Waits until the current cellular service has the expected activation
state within ACTIVATION_STATE_TIMEOUT seconds.
@param expected_state: The activation state the service is expected to
be in.
@raises error.TestFail, if no cellular service is found or the service
activation state doesn't match |expected_state| within timeout.
"""
service = self.find_cellular_service()
state = self.flim.WaitForServiceState(
service=service,
expected_states=[expected_state],
timeout=ACTIVATION_STATE_TIMEOUT,
property_name='Cellular.ActivationState')[0]
if state != expected_state:
raise error.TestFail(
'Service activation state should be \'%s\', but it is '
'\'%s\'.' % (expected_state, state))
def run_once(self):
with backchannel.Backchannel():
self.flim = flimflam.FlimFlam()
self.device_manager = flimflam.DeviceManager(self.flim)
self.flim.SetDebugTags(
'dbus+service+device+modem+cellular+portal+network+'
'manager+dhcp')
tests = [
ActivationStateTest(self),
ActivationSuccessTest(self),
ActivationFailureRetryTest(self)
]
with cell_tools.OtherDeviceShutdownContext('cellular'):
for test in tests:
test.run()