Home | History | Annotate | Download | only in network_CDMAActivate
      1 # Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
      2 # Use of this source code is governed by a BSD-style license that can be
      3 # found in the LICENSE file.
      4 
      5 import dbus
      6 import dbus.types
      7 import os
      8 import time
      9 
     10 from autotest_lib.client.bin import test
     11 from autotest_lib.client.bin import utils
     12 from autotest_lib.client.common_lib import error
     13 from autotest_lib.client.cros.cellular import mm1_constants
     14 from autotest_lib.client.cros.cellular import test_environment
     15 from autotest_lib.client.cros.networking import pm_proxy
     16 
     17 I_ACTIVATION_TEST = 'Interface.CDMAActivationTest'
     18 ACTIVATION_STATE_TIMEOUT = 10
     19 MODEM_STATE_TIMEOUT = 10
     20 TEST_MODEMS_MODULE_PATH = os.path.join(os.path.dirname(__file__), 'files',
     21                                        'modems.py')
     22 
     23 class ActivationTest(object):
     24     """
     25     Super class that implements setup code that is common to the individual
     26     tests.
     27 
     28     """
     29     def __init__(self, test):
     30         self.test = test
     31         self.modem_properties_interface = None
     32 
     33 
     34     def run(self):
     35         """
     36         Restarts the pseudomodem with the modem object to be used for this
     37         test and runs the test.
     38 
     39         """
     40         self.pseudomm = pm_proxy.PseudoMMProxy.get_proxy()
     41         self._run_test()
     42 
     43 
     44     def _set_modem_activation_state(self, state):
     45         self.pseudomm.get_modem().iface_properties.Set(
     46                 mm1_constants.I_MODEM_CDMA,
     47                 'ActivationState',
     48                 dbus.types.UInt32(state))
     49 
     50 
     51     def _get_modem_activation_state(self):
     52         modem = self.pseudomm.get_modem()
     53         return modem.properties(mm1_constants.I_MODEM_CDMA)['ActivationState']
     54 
     55 
     56     def pseudomodem_flags(self):
     57         """
     58         Subclasses must override this method to setup the flags map passed to
     59         pseudomodem to suite their needs.
     60 
     61         """
     62         raise NotImplementedError()
     63 
     64 
     65     def _run_test(self):
     66         raise NotImplementedError()
     67 
     68 class ActivationStateTest(ActivationTest):
     69     """
     70     This test verifies that the service "ActivationState" property matches the
     71     cdma activation state exposed by ModemManager.
     72 
     73     """
     74     def pseudomodem_flags(self):
     75         return {'family' : 'CDMA'}
     76 
     77 
     78     def _run_test(self):
     79         self.test.reset_modem()
     80 
     81         # The modem state should be REGISTERED.
     82         self.test.check_modem_state(mm1_constants.MM_MODEM_STATE_REGISTERED)
     83 
     84         # Service should appear as 'activated'.
     85         self.test.check_service_activation_state('activated')
     86 
     87         # Service activation state should change to 'not-activated'.
     88         self._set_modem_activation_state(
     89                 mm1_constants.MM_MODEM_CDMA_ACTIVATION_STATE_NOT_ACTIVATED)
     90         self.test.check_service_activation_state('not-activated')
     91 
     92         # Service activation state should change to 'activating'.
     93         self._set_modem_activation_state(
     94                 mm1_constants.MM_MODEM_CDMA_ACTIVATION_STATE_ACTIVATING)
     95         self.test.check_service_activation_state('activating')
     96 
     97         # Service activation state should change to 'partially-activated'.
     98         st = mm1_constants.MM_MODEM_CDMA_ACTIVATION_STATE_PARTIALLY_ACTIVATED
     99         self._set_modem_activation_state(st)
    100         self.test.check_service_activation_state('partially-activated')
    101 
    102         # Service activation state should change to 'activated'.
    103         self._set_modem_activation_state(
    104                 mm1_constants.MM_MODEM_CDMA_ACTIVATION_STATE_ACTIVATED)
    105         self.test.check_service_activation_state('activated')
    106 
    107 
    108 class ActivationSuccessTest(ActivationTest):
    109     """
    110     This test verifies that the service finally bacomes "activated" when the
    111     service is told to initiate OTASP activation.
    112 
    113     """
    114     def pseudomodem_flags(self):
    115         return {'test-module' : TEST_MODEMS_MODULE_PATH,
    116                 'test-modem-class' : 'UnactivatedCdmaModem'}
    117 
    118 
    119     def _run_test(self):
    120         self.test.reset_modem()
    121 
    122         # The modem state should be REGISTERED.
    123         self.test.check_modem_state(mm1_constants.MM_MODEM_STATE_REGISTERED)
    124 
    125         # Service should appear as 'not-activated'.
    126         self.test.check_service_activation_state('not-activated')
    127 
    128         # Call 'CompleteActivation' on the service. The service should become
    129         # 'activating'.
    130         service = self.test.test_env.shill.find_cellular_service_object()
    131         service.CompleteCellularActivation()
    132         self.test.check_service_activation_state('activating')
    133 
    134         # The modem should reset in 5 seconds. Wait 5 more seconds to make sure
    135         # a new service gets created.
    136         time.sleep(10)
    137         self.test.check_service_activation_state('activated')
    138 
    139 
    140 class ActivationFailureRetryTest(ActivationTest):
    141     """
    142     This test verifies that if "ActivateAutomatic" fails, a retry will be
    143     scheduled.
    144 
    145     """
    146     NUM_ACTIVATE_RETRIES = 5
    147     def pseudomodem_flags(self):
    148         return {'test-module' : TEST_MODEMS_MODULE_PATH,
    149                 'test-modem-class' : 'ActivationRetryModem',
    150                 'test-modem-arg' : [self.NUM_ACTIVATE_RETRIES]}
    151 
    152 
    153     def _run_test(self):
    154         self.test.reset_modem()
    155 
    156         # The modem state should be REGISTERED.
    157         self.test.check_modem_state(mm1_constants.MM_MODEM_STATE_REGISTERED)
    158 
    159         # Service should appear as 'not-activated'.
    160         self.test.check_service_activation_state('not-activated')
    161 
    162         # Call 'CompleteActivation' on the service.
    163         service = self.test.test_env.shill.find_cellular_service_object()
    164         service.CompleteCellularActivation()
    165 
    166         # Wait for shill to retry the failed activations, except the last retry
    167         # will succeed.
    168         # NOTE: Don't check for transitory service activation states while this
    169         # is happening because shill will reset the modem once the activation
    170         # succeeds which will cause the existing service to get deleted.
    171         modem = self.pseudomm.get_modem()
    172         utils.poll_for_condition(
    173                 lambda: (modem.properties(I_ACTIVATION_TEST)['ActivateCount'] ==
    174                          self.NUM_ACTIVATE_RETRIES),
    175                 exception=error.TestFail(
    176                         'Shill did not retry failed activation'),
    177                 timeout=10)
    178 
    179         # The modem should reset in 5 seconds. Wait 5 more seconds to make sure
    180         # a new service gets created.
    181         time.sleep(10)
    182         self.test.check_service_activation_state('activated')
    183 
    184 
    185 class network_CDMAActivate(test.test):
    186     """
    187     Tests various scenarios that may arise during the post-payment CDMA
    188     activation process when shill accesses the modem via ModemManager.
    189 
    190     """
    191     version = 1
    192 
    193     def check_modem_state(self, expected_state, timeout=MODEM_STATE_TIMEOUT):
    194         """
    195         Polls until the modem has the expected state within |timeout| seconds.
    196 
    197         @param expected_state: The modem state the modem is expected to be in.
    198         @param timeout: The timeout interval for polling.
    199 
    200         @raises pm_proxy.ModemManager1ProxyError if the modem doesn't
    201                 transition to |expected_state| within |timeout|.
    202 
    203         """
    204         modem = pm_proxy.PseudoMMProxy.get_proxy().get_modem()
    205         modem.wait_for_states([expected_state], timeout_seconds=timeout)
    206 
    207 
    208     def check_service_activation_state(self, expected_state):
    209         """
    210         Waits until the current cellular service has the expected activation
    211         state within ACTIVATION_STATE_TIMEOUT seconds.
    212 
    213         @param expected_state: The activation state the service is expected to
    214                                be in.
    215         @raises error.TestFail, if no cellular service is found or the service
    216                 activation state doesn't match |expected_state| within timeout.
    217 
    218         """
    219         success, state, _ = self.test_env.shill.wait_for_property_in(
    220                 self.test_env.shill.find_cellular_service_object(),
    221                 'Cellular.ActivationState',
    222                 [expected_state],
    223                 ACTIVATION_STATE_TIMEOUT)
    224         if not success:
    225             raise error.TestFail(
    226                     'Service activation state should be \'%s\', but it is '
    227                     '\'%s\'.' % (expected_state, state))
    228 
    229 
    230     def reset_modem(self):
    231         """
    232         Resets the one and only modem in the DUT.
    233 
    234         """
    235         modem = self.test_env.shill.find_cellular_device_object()
    236         self.test_env.shill.reset_modem(modem)
    237 
    238 
    239     def run_once(self):
    240         tests = [
    241             ActivationStateTest(self),
    242             ActivationSuccessTest(self),
    243             ActivationFailureRetryTest(self)
    244         ]
    245 
    246         for test in tests:
    247             self.test_env = test_environment.CellularPseudoMMTestEnvironment(
    248                     pseudomm_args=(test.pseudomodem_flags(),))
    249             with self.test_env:
    250                 test.run()
    251