blob: bff8784ffc1e5e895a04cc8c4acc51b3f9ed835e [file] [log] [blame]
# Copyright (c) 2012 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.
"""Encapsulates interactions with the cellular testbed."""
import contextlib, logging, urllib2
# We'd really prefer not to depend on autotest proper here
from autotest_lib.client.bin import utils
from autotest_lib.client.cros import backchannel, flimflam_test_path
from autotest_lib.client.cros.cellular import cellular, cell_tools
from autotest_lib.client.cros.cellular import emulator_config
import flimflam
TIMEOUT = 60
class Error(Exception):
pass
class Environment(object):
"""Dispatch class: reads config and returns appropriate concrete type."""
def __new__(cls, config, *args, **kwargs):
return EmulatedEnvironment(config, *args, **kwargs)
class EmulatedEnvironment(object):
def __init__(self, config):
self.config = config
self.flim = None
self.emulator = None
def __enter__(self):
self.flim = flimflam.FlimFlam()
return self
def __exit__(self, exception, value, traceback):
if self.emulator:
self.emulator.Close()
return False
def StartDefault(self, technology):
(self.emulator, self.verifier) = emulator_config.StartDefault(
self.config, technology)
def CheckHttpConnectivity(self):
"""Check that the device can fetch HTTP pages."""
http_config = self.config.cell['http_connectivity']
response = urllib2.urlopen(http_config['url'], timeout=TIMEOUT).read()
if ('url_required_contents' in http_config and
http_config['url_required_contents'] not in response):
logging.error('Could not find %s in \n\t%s\n',
http_config['url_required_contents'], response)
raise Error('Content downloaded, but it was incorrect')
def CheckedConnectToCellular(self, timeout=TIMEOUT):
"""Connect to cellular, check if we are connected, return a service"""
(service, _) = cell_tools.ConnectToCellular(self.flim, timeout=timeout)
self.verifier.AssertDataStatusIn([
cellular.UeGenericDataStatus.CONNECTED])
return service
def CheckedDisconnectFromCellular(self, service):
"""Disconnect from cellular and check that we're disconnected."""
self.flim.DisconnectService(service)
def _ModemIsFullyDisconnected():
return self.verifier.IsDataStatusIn([
cellular.UeGenericDataStatus.REGISTERED,
cellular.UeGenericDataStatus.NONE,])
utils.poll_for_condition(
_ModemIsFullyDisconnected,
timeout=20,
exception=Error('modem not disconnected from base station'))
class DefaultCellularTestContext(object):
"""Wraps useful contexts for a cellular test in a single context."""
def __init__(self, config):
self._nested = contextlib.nested(
backchannel.Backchannel(),
cell_tools.OtherDeviceShutdownContext('cellular'),
Environment(config))
def __enter__(self):
(self.backchannel,
self.other_device_shutdown_context,
self.env) = self._nested.__enter__()
return self
def __exit__(self, exception, value, traceback):
return self._nested.__exit__(exception, value, traceback)