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 5import logging 6 7from autotest_lib.client.bin import test, utils 8from autotest_lib.client.common_lib import error 9from autotest_lib.client.cros import network 10 11from autotest_lib.client.cros.cellular import cellular 12from autotest_lib.client.cros.cellular import cell_tools 13from autotest_lib.client.cros.cellular import environment 14from autotest_lib.client.cros.cellular import mm 15 16import time 17 18import flimflam 19 20 21_STILL_REGISTERED_ERROR = error.TestError('modem registered to base station') 22_NOT_REGISTERED_ERROR = error.TestError('modem not registered to base station') 23 24CELLULAR_TIMEOUT = 180 25 26 27class _WrongTech(Exception): 28 def __init__(self, technology): 29 self.technology = technology 30 31 32class cellular_Signal(test.test): 33 version = 1 34 35 def TimedPollForCondition( 36 self, label, condition, exception=None, timeout=10, sleep_interval=0.5): 37 """Poll until a condition becomes true and report timing stats 38 39 Arguments: 40 label: label for a performance statistics to be logged 41 condition: function taking no args and returning bool 42 exception: exception to throw if condition doesn't become true 43 timeout: maximum number of seconds to wait 44 sleep_interval: time to sleep between polls 45 desc: description of default TimeoutError used if 'exception' is None 46 47 Returns: 48 The true value that caused the poll loop to terminate. 49 50 Raises: 51 'exception' arg 52 """ 53 start_time = time.time(); 54 utils.poll_for_condition(condition, 55 timeout=timeout, 56 exception=exception, 57 sleep_interval=sleep_interval); 58 self.write_perf_keyval({label: time.time() - start_time }) 59 60 def run_once(self, config, technologies, wait_for_disc, verify_set_power): 61 62 # This test only works if all the technologies are in the same 63 # family. Check that before doing anything else. 64 families = set( 65 cellular.TechnologyToFamily[tech] for tech in technologies) 66 if len(families) > 1: 67 raise error.TestError('Specify only one family not: %s' % families) 68 69 # choose a technology other than the one we plan to start with 70 technology = technologies[-1] 71 with environment.DefaultCellularTestContext(config) as c: 72 env = c.env 73 flim = flimflam.FlimFlam() 74 flim.SetDebugTags('manager+device+modem') 75 env.StartDefault(technology) 76 network.ResetAllModems(flim) 77 logging.info('Preparing for %s' % technology) 78 cell_tools.PrepareModemForTechnology('', technology) 79 80 # TODO(jglasgow) Need to figure out what isn't settling here. 81 # Going to wait 'til after ResetAllModems changes land. 82 time.sleep(10) 83 84 # Clear all errors before we start. 85 # Resetting the modem above may have caused some errors on the 86 # 8960 (eg. lost connection, etc). 87 env.emulator.ClearErrors() 88 89 service = env.CheckedConnectToCellular(timeout=CELLULAR_TIMEOUT) 90 91 # Step through all technologies, forcing a transition 92 failed_technologies = [] 93 manager, modem_path = mm.PickOneModem('') 94 cell_modem = manager.GetModem(modem_path) 95 for tech in technologies: 96 tname = str(tech).replace('Technology:', '') 97 if verify_set_power: 98 logging.info('Powering off basestation') 99 env.emulator.SetPower(cellular.Power.OFF) 100 self.TimedPollForCondition( 101 'Power.OFF.%s.deregister_time' % tname, 102 lambda: not cell_modem.ModemIsRegistered(), 103 timeout=CELLULAR_TIMEOUT, 104 exception=_STILL_REGISTERED_ERROR) 105 106 logging.info('Powering on basestation') 107 env.emulator.SetPower(cellular.Power.DEFAULT) 108 self.TimedPollForCondition( 109 'Power.DEFAULT.%s.register_time' % tname, 110 lambda: cell_modem.ModemIsRegistered(), 111 timeout=CELLULAR_TIMEOUT, 112 exception=_NOT_REGISTERED_ERROR) 113 114 logging.info('Stopping basestation') 115 env.emulator.Stop() 116 if wait_for_disc: 117 self.TimedPollForCondition( 118 'Stop.%s.deregister_time' % tname, 119 lambda: not cell_modem.ModemIsRegistered(), 120 timeout=CELLULAR_TIMEOUT, 121 exception=_STILL_REGISTERED_ERROR) 122 123 logging.info('Reconfiguring for %s' % tech) 124 env.emulator.SetTechnology(tech) 125 env.emulator.Start() 126 127 try: 128 self.TimedPollForCondition( 129 'Start.%s.register_time' % tname, 130 lambda: cell_modem.ModemIsRegisteredUsing(tech), 131 timeout=CELLULAR_TIMEOUT, 132 exception=_WrongTech(tech)) 133 except _WrongTech, wt: 134 failed_technologies.append( 135 (wt.technology, cell_modem.GetAccessTechnology())) 136 137 # TODO(jglasgow): verify flimflam properties (signals?) 138 139 if failed_technologies: 140 msg = ('Failed to register using %s' % 141 ', '.join(str(x) for x in failed_technologies)) 142 raise error.TestError(msg) 143