| # 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 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.networking import cellular_proxy |
| from autotest_lib.client.cros.networking import shill_context |
| from autotest_lib.client.cros.networking import shill_proxy |
| |
| |
| class cellular_SafetyDance(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.get_dbus_name() in self.okerrors: |
| return v, error.get_dbus_message() |
| else: |
| raise error |
| return v, '' |
| |
| def _enable(self): |
| logging.info('Enable') |
| self._filterexns(lambda: |
| self.test_env.shill.manager.EnableTechnology('cellular')) |
| |
| def _disable(self): |
| logging.info('Disable') |
| self._filterexns(lambda: |
| self.test_env.shill.manager.DisableTechnology('cellular')) |
| |
| def _ignoring(self, reason): |
| if ('AlreadyConnected' in reason or |
| 'Not connected' in reason or |
| 'Bearer already being connected' in reason or |
| 'Bearer already being disconnected' in reason or |
| 'InProgress' in reason): |
| return True |
| if 'NotSupported' in 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.test_env.shill.find_cellular_service_object() |
| return False |
| |
| def _connect(self): |
| logging.info('Connect') |
| try: |
| service = self.test_env.shill.wait_for_cellular_service_object( |
| timeout_seconds=5) |
| except shill_proxy.ShillProxyError: |
| return |
| |
| success, reason = self._filterexns(lambda: |
| self.test_env.shill.connect_service_synchronous( |
| service=service, |
| timeout_seconds= |
| cellular_proxy.CellularProxy.SERVICE_CONNECT_TIMEOUT)) |
| if not success and not self._ignoring(reason): |
| raise error.TestFail('Could not connect: %s' % reason) |
| |
| def _disconnect(self): |
| logging.info('Disconnect') |
| try: |
| service = self.test_env.shill.wait_for_cellular_service_object( |
| timeout_seconds=5) |
| except shill_proxy.ShillProxyError: |
| return |
| |
| success, reason = self._filterexns(lambda: |
| self.test_env.shill.disconnect_service_synchronous( |
| service=service, |
| timeout_seconds= |
| cellular_proxy.CellularProxy. |
| SERVICE_DISCONNECT_TIMEOUT)) |
| if not success and not self._ignoring(reason): |
| raise error.TestFail('Could not disconnect: %s' % reason) |
| |
| 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.device = self.test_env.shill.find_cellular_device_object() |
| if not self.device: |
| raise error.TestFail('Could not find cellular device.') |
| |
| # Start in a disabled state. |
| self._disable() |
| logging.info('Seed: %d', seed) |
| random.seed(seed) |
| for _ in xrange(ops): |
| self._op() |
| |
| def run_once(self, test_env, ops=30, seed=None): |
| self.test_env = test_env |
| with test_env, shill_context.ServiceAutoConnectContext( |
| test_env.shill.find_cellular_service_object, False): |
| self._run_once_internal(ops, seed) |
| |
| # Enable device to restore autoconnect settings. |
| self._enable() |
| test_env.shill.wait_for_cellular_service_object() |