blob: 6c19d4e033e4b3122af8520b4a5d6c4e9cfb2957 [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.
import dbus
import dbus.mainloop.glib
import logging
import random
import time
from autotest_lib.client.bin import test
from autotest_lib.client.common_lib import error
from autotest_lib.client.cros import backchannel
from autotest_lib.client.cros.cellular import cell_tools
from autotest_lib.client.cros.cellular.pseudomodem import pseudomodem
from autotest_lib.client.cros import flimflam_test_path
import flimflam
class network_3GSafetyDance(test.test):
"""
Stress tests all connection manager 3G operations.
This test runs a long series of 3G operations in pseudorandom order. All of
these 3G operations must return a convincing result (EINPROGRESS or no
error).
"""
version = 1
def _filterexns(self, fn):
v = None
try:
v = fn()
except dbus.exceptions.DBusException, error:
if error._dbus_error_name in self.okerrors:
return v
else:
raise error
return v
def _enable(self):
logging.info('Enable')
self._filterexns(lambda:
self.flim.EnableTechnology('cellular'))
def _disable(self):
logging.info('Disable')
self._filterexns(lambda:
self.flim.DisableTechnology('cellular'))
def _ignoring(self, status):
if ('AlreadyConnected' in status['reason'] or
'Bearer already being connected' in status['reason'] or
'Bearer already being disconnected' in status['reason'] or
'InProgress' in status['reason']):
return True
if 'NotSupported' in status['reason']:
# We should only ignore this error if we've previously disabled
# cellular technology and the service subsequently disappeared
# when we tried to connect again.
return not self.flim.FindCellularService(timeout=0)
return False
def _connect(self):
logging.info('Connect')
self.service = self.flim.FindCellularService(timeout=5)
if self.service:
(success, status) = self._filterexns(lambda:
self.flim.ConnectService(service=self.service,
assoc_timeout=120,
config_timeout=120))
if not success and not self._ignoring(status):
raise error.TestFail('Could not connect: %s' % status)
def _disconnect(self):
logging.info('Disconnect')
self.service = self.flim.FindCellularService(timeout=5)
if self.service:
(success, status) = self._filterexns(lambda:
self.flim.DisconnectService(service=self.service,
wait_timeout=60))
if not success:
raise error.TestFail('Could not disconnect: %s' % status)
def _op(self):
n = random.randint(0, len(self.ops) - 1)
self.ops[n]()
time.sleep(random.randint(5, 20) / 10.0)
def _run_once_internal(self, ops=30, seed=None):
if not seed:
seed = int(time.time())
self.okerrors = [
'org.chromium.flimflam.Error.InProgress',
'org.chromium.flimflam.Error.AlreadyConnected',
'org.chromium.flimflam.Error.AlreadyEnabled',
'org.chromium.flimflam.Error.AlreadyDisabled'
]
self.ops = [ self._enable,
self._disable,
self._connect,
self._disconnect ]
self.flim = flimflam.FlimFlam()
self.manager = flimflam.DeviceManager(self.flim)
self.device = self.flim.FindCellularDevice()
if not self.device:
raise error.TestFail('Could not find cellular device.')
self.flim.SetDebugTags(
'dbus+service+device+modem+cellular+portal+network+'
'manager+dhcp')
# Ensure that auto connect is turned off so that flimflam does
# not interfere with running the test
with cell_tools.AutoConnectContext(self.device, self.flim, False):
# Start in a known state.
self._disable()
logging.info('Seed: %d', seed)
random.seed(seed)
for _ in xrange(ops):
self._op()
def run_once(self, ops=30, seed=None,
pseudo_modem=False,
pseudomodem_family='3GPP'):
# Use a backchannel so that flimflam will restart when the
# test is over. This ensures flimflam is in a known good
# state even if this test fails.
with backchannel.Backchannel():
with pseudomodem.TestModemManagerContext(
pseudo_modem, family=pseudomodem_family):
self._run_once_internal(ops, seed)