1# Lint as: python2, python3 2# Copyright (c) 2012 The Chromium OS Authors. All rights reserved. 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5 6from __future__ import absolute_import 7from __future__ import division 8from __future__ import print_function 9 10import dbus 11import logging 12 13from six.moves import range 14 15from autotest_lib.client.bin import test 16from autotest_lib.client.common_lib import error 17from autotest_lib.client.cros.cellular.pseudomodem import modem_3gpp 18from autotest_lib.client.cros.cellular.pseudomodem import modem_cdma 19from autotest_lib.client.cros.cellular.pseudomodem import pm_errors 20from autotest_lib.client.cros.cellular.pseudomodem import utils as pm_utils 21from autotest_lib.client.cros.networking import cellular_proxy 22from autotest_lib.client.cros.networking import shill_proxy 23 24 25def _GetModemSuperClass(family): 26 """ 27 Obtains the correct Modem base class to use for the given family. 28 29 @param family: The modem family. Should be one of |3GPP|/|CDMA|. 30 @returns: The relevant Modem base class. 31 @raises error.TestError, if |family| is not one of '3GPP' or 'CDMA'. 32 33 """ 34 if family == '3GPP': 35 return modem_3gpp.Modem3gpp 36 elif family == 'CDMA': 37 return modem_cdma.ModemCdma 38 else: 39 raise error.TestError('Invalid pseudomodem family: %s', family) 40 41 42def GetFailConnectModem(family): 43 """ 44 Returns the correct modem subclass based on |family|. 45 46 @param family: A string containing either '3GPP' or 'CDMA'. 47 48 """ 49 modem_class = _GetModemSuperClass(family) 50 51 class FailConnectModem(modem_class): 52 """Custom fake Modem that always fails to connect.""" 53 @pm_utils.log_dbus_method(return_cb_arg='return_cb', 54 raise_cb_arg='raise_cb') 55 def Connect(self, properties, return_cb, raise_cb): 56 logging.info('Connect call will fail.') 57 raise_cb(pm_errors.MMCoreError(pm_errors.MMCoreError.FAILED)) 58 59 return FailConnectModem() 60 61 62class cellular_ConnectFailure(test.test): 63 """ 64 Tests that 3G connect failures are handled by shill properly. 65 66 This test will fail if a connect failure does not immediately cause the 67 service to enter the Failed state. 68 69 """ 70 version = 1 71 72 def _connect_to_3g_network(self, config_timeout): 73 """ 74 Attempts to connect to a 3G network using shill. 75 76 @param config_timeout: Timeout (in seconds) before giving up on 77 connect. 78 79 @raises: error.TestFail if connection fails. 80 81 """ 82 service = self.test_env.shill.find_cellular_service_object() 83 84 try: 85 service.Connect() 86 except dbus.DBusException as e: 87 logging.info('Expected error: %s', e) 88 89 _, state, _ = self.test_env.shill.wait_for_property_in( 90 service, 91 shill_proxy.ShillProxy.SERVICE_PROPERTY_STATE, 92 ('ready', 'portal', 'online', 'failure'), 93 config_timeout) 94 95 if state != 'failure': 96 raise error.TestFail('Service state should be failure not %s' % 97 state) 98 99 100 def run_once(self, test_env, connect_count=4): 101 with test_env: 102 self.test_env = test_env 103 for count in range(connect_count): 104 logging.info('Connect attempt %d', count + 1) 105 self._connect_to_3g_network(config_timeout= 106 cellular_proxy.CellularProxy.SERVICE_CONNECT_TIMEOUT) 107