| # 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. |
| |
| import logging |
| |
| from autotest_lib.client.bin import test, utils |
| from autotest_lib.client.common_lib import error |
| from autotest_lib.client.cros import network |
| |
| from autotest_lib.client.cros.cellular import cellular |
| from autotest_lib.client.cros.cellular import cell_tools |
| from autotest_lib.client.cros.cellular import environment |
| from autotest_lib.client.cros.cellular import mm |
| |
| import time |
| |
| import flimflam |
| |
| |
| _STILL_REGISTERED_ERROR = error.TestError('modem registered to base station') |
| _NOT_REGISTERED_ERROR = error.TestError('modem not registered to base station') |
| |
| CELLULAR_TIMEOUT = 180 |
| |
| |
| class _WrongTech(Exception): |
| def __init__(self, technology): |
| self.technology = technology |
| |
| |
| class cellular_Signal(test.test): |
| version = 1 |
| |
| def TimedPollForCondition( |
| self, label, condition, exception=None, timeout=10, sleep_interval=0.5): |
| """Poll until a condition becomes true and report timing stats |
| |
| Arguments: |
| label: label for a performance statistics to be logged |
| condition: function taking no args and returning bool |
| exception: exception to throw if condition doesn't become true |
| timeout: maximum number of seconds to wait |
| sleep_interval: time to sleep between polls |
| desc: description of default TimeoutError used if 'exception' is None |
| |
| Returns: |
| The true value that caused the poll loop to terminate. |
| |
| Raises: |
| 'exception' arg |
| """ |
| start_time = time.time(); |
| utils.poll_for_condition(condition, |
| timeout=timeout, |
| exception=exception, |
| sleep_interval=sleep_interval); |
| self.write_perf_keyval({label: time.time() - start_time }) |
| |
| def run_once(self, config, technologies, wait_for_disc, verify_set_power): |
| |
| # This test only works if all the technologies are in the same |
| # family. Check that before doing anything else. |
| families = set( |
| cellular.TechnologyToFamily[tech] for tech in technologies) |
| if len(families) > 1: |
| raise error.TestError('Specify only one family not: %s' % families) |
| |
| # choose a technology other than the one we plan to start with |
| technology = technologies[-1] |
| with environment.DefaultCellularTestContext(config) as c: |
| env = c.env |
| flim = flimflam.FlimFlam() |
| flim.SetDebugTags('manager+device+modem') |
| env.StartDefault(technology) |
| network.ResetAllModems(flim) |
| logging.info('Preparing for %s' % technology) |
| cell_tools.PrepareModemForTechnology('', technology) |
| |
| # TODO(jglasgow) Need to figure out what isn't settling here. |
| # Going to wait 'til after ResetAllModems changes land. |
| time.sleep(10) |
| |
| # Clear all errors before we start. |
| # Resetting the modem above may have caused some errors on the |
| # 8960 (eg. lost connection, etc). |
| env.emulator.ClearErrors() |
| |
| service = env.CheckedConnectToCellular(timeout=CELLULAR_TIMEOUT) |
| |
| # Step through all technologies, forcing a transition |
| failed_technologies = [] |
| manager, modem_path = mm.PickOneModem('') |
| cell_modem = manager.GetModem(modem_path) |
| for tech in technologies: |
| tname = str(tech).replace('Technology:', '') |
| if verify_set_power: |
| logging.info('Powering off basestation') |
| env.emulator.SetPower(cellular.Power.OFF) |
| self.TimedPollForCondition( |
| 'Power.OFF.%s.deregister_time' % tname, |
| lambda: not cell_modem.ModemIsRegistered(), |
| timeout=CELLULAR_TIMEOUT, |
| exception=_STILL_REGISTERED_ERROR) |
| |
| logging.info('Powering on basestation') |
| env.emulator.SetPower(cellular.Power.DEFAULT) |
| self.TimedPollForCondition( |
| 'Power.DEFAULT.%s.register_time' % tname, |
| lambda: cell_modem.ModemIsRegistered(), |
| timeout=CELLULAR_TIMEOUT, |
| exception=_NOT_REGISTERED_ERROR) |
| |
| logging.info('Stopping basestation') |
| env.emulator.Stop() |
| if wait_for_disc: |
| self.TimedPollForCondition( |
| 'Stop.%s.deregister_time' % tname, |
| lambda: not cell_modem.ModemIsRegistered(), |
| timeout=CELLULAR_TIMEOUT, |
| exception=_STILL_REGISTERED_ERROR) |
| |
| logging.info('Reconfiguring for %s' % tech) |
| env.emulator.SetTechnology(tech) |
| env.emulator.Start() |
| |
| try: |
| self.TimedPollForCondition( |
| 'Start.%s.register_time' % tname, |
| lambda: cell_modem.ModemIsRegisteredUsing(tech), |
| timeout=CELLULAR_TIMEOUT, |
| exception=_WrongTech(tech)) |
| except _WrongTech, wt: |
| failed_technologies.append( |
| (wt.technology, cell_modem.GetAccessTechnology())) |
| |
| # TODO(jglasgow): verify flimflam properties (signals?) |
| |
| if failed_technologies: |
| msg = ('Failed to register using %s' % |
| ', '.join(str(x) for x in failed_technologies)) |
| raise error.TestError(msg) |