普通文本  |  143行  |  5.65 KB

# 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)