blob: 23c1e1ce6271e72d6c644061d20dc9ce0615e971 [file] [log] [blame]
# 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.
from autotest_lib.client.bin import test, utils
from autotest_lib.client.common_lib import error
import logging, os, subprocess, time
from autotest_lib.client.cros import backchannel, network, flimflam_test_path
from autotest_lib.client.cros.cellular import cell_tools, mm
from autotest_lib.client.cros.cellular.pseudomodem import modem_3gpp
from autotest_lib.client.cros.cellular.pseudomodem import mm1, pseudomodem, sim
import flimflam
CONNECT_CONFIG_TIMEOUT = 120
CONNECT_SERVICE_TIMEOUT = 30
DISCONNECT_TIMEOUT = 60
class DisconnectFailTest(object):
def __init__(self, pmm_context, test):
self.pmm_context = pmm_context
self.test_modem = None
self.test = test
self.SetupTestModem()
def Run(self):
if not self.test_modem:
raise test.TestFail('Uninitialized test modem')
self.pmm_context.SetModem(self.test_modem)
self.RunTest()
def SetupTestModem(self):
raise NotImplementedError()
def RunTest(self):
raise NotImplementedError()
class DisconnectWhileStateIsDisconnectingTest(DisconnectFailTest):
def SetupTestModem(self):
class TestModem3gpp(modem_3gpp.Modem3gpp):
def Disconnect(
self, bearer_path, return_cb, raise_cb, *return_cb_args):
self.ChangeState(mm1.MM_MODEM_STATE_DISCONNECTING,
mm1.MM_MODEM_STATE_CHANGE_REASON_UNKNOWN)
time.sleep(5)
raise mm1.MMCoreError(mm1.MMCoreError.FAILED)
self.test_modem = TestModem3gpp()
def RunTest(self):
network.ResetAllModems(self.test.flim)
time.sleep(5)
# Connect to the service if not already connected.
if not self.test.IsServiceConnected():
cell_tools.ConnectToCellular(self.test.flim)
# Disconnect attempt should fail.
service = self.test.FindCellularService()
self.test.flim.DisconnectService(service=service,
wait_timeout=DISCONNECT_TIMEOUT)
# Service should remain connected.
if not self.test.IsServiceConnected():
raise error.TestError('Service should remain connected after '
'disconnect failure.')
class DisconnectWhileDisconnectInProgressTest(DisconnectFailTest):
def SetupTestModem(self):
class TestModem3gpp(modem_3gpp.Modem3gpp):
def __init__(self):
modem_3gpp.Modem3gpp.__init__(self)
self.disconnect_count = 0
def Disconnect(
self, bearer_path, return_cb, raise_cb, *return_cb_args):
# On the first call, set the state to DISCONNECTING.
self.disconnect_count += 1
if self.disconnect_count == 1:
self.ChangeState(mm1.MM_MODEM_STATE_DISCONNECTING,
mm1.MM_MODEM_STATE_CHANGE_REASON_UNKNOWN)
time.sleep(5)
else:
raise mm1.MMCoreError(mm1.MMCoreError.FAILED)
self.test_modem = TestModem3gpp()
def RunTest(self):
network.ResetAllModems(self.test.flim)
time.sleep(5)
# Connect to the service if not already connected.
if not self.test.IsServiceConnected():
cell_tools.ConnectToCellular(self.test.flim)
# Issue first disconnect. Service should remain connected.
service = self.test.FindCellularService()
self.test.flim.DisconnectService(service=service,
wait_timeout=DISCONNECT_TIMEOUT)
if not self.test.IsServiceConnected():
raise error.TestError('Service should remain connected after '
'first disconnect.')
# Modem state should be disconnecting.
manager, modem_path = mm.PickOneModem('')
modem = manager.GetModem(modem_path)
props = modem.GetAll(mm1.I_MODEM)
if not props['State'] == mm1.MM_MODEM_STATE_DISCONNECTING:
raise error.TestError('Modem should be in the DISCONNECTING state.')
# Issue second disconnect. Service should remain connected.
self.test.flim.DisconnectService(service=service,
wait_timeout=DISCONNECT_TIMEOUT)
if not self.test.IsServiceConnected():
raise error.TestError('Service should remain connected after '
'disconnect failure.')
class DisconnectFailOtherTest(DisconnectFailTest):
def SetupTestModem(self):
class TestModem3gpp(modem_3gpp.Modem3gpp):
def Disconnect(
self, bearer_path, return_cb, raise_cb, *return_cb_args):
raise mm1.MMCoreError(mm1.MMCoreError.FAILED)
self.test_modem = TestModem3gpp()
def RunTest(self):
network.ResetAllModems(self.test.flim)
time.sleep(5)
# Connect to the service if not already connected.
if not self.test.IsServiceConnected():
cell_tools.ConnectToCellular(self.test.flim)
# Disconnect attempt should fail.
service = self.test.FindCellularService()
self.test.flim.DisconnectService(service=service,
wait_timeout=DISCONNECT_TIMEOUT)
# Service should be cleaned up as if disconnect succeeded.
if not self.test.IsServiceDisconnected():
raise error.TestError('Service should be disconnected.')
class network_3GDisconnectFailure(test.test):
version = 1
def IsServiceConnected(self):
service = self.FindCellularService()
properties = service.GetProperties(utf8_strings=True)
state = properties.get('State', None)
return state in ['portal', 'online']
def IsServiceDisconnected(self):
service = self.FindCellularService()
properties = service.GetProperties(utf8_strings=True)
state = properties.get('State', None)
return state == 'idle'
def FindCellularService(self):
service = self.flim.FindCellularService()
if not service:
raise error.TestError('Could not find cellular service.')
return service
def run_once(self):
with backchannel.Backchannel():
fake_sim = sim.SIM(sim.SIM.Carrier('att'),
mm1.MM_MODEM_ACCESS_TECHNOLOGY_GSM)
with pseudomodem.TestModemManagerContext(True,
sim=fake_sim) as tmmc:
self.flim = flimflam.FlimFlam()
self.device_manager = flimflam.DeviceManager(self.flim)
self.flim.SetDebugTags(
'dbus+service+device+modem+cellular+portal+network+'
'manager+dhcp')
tests = [
DisconnectWhileStateIsDisconnectingTest(
tmmc.GetPseudoModemManager(), self),
DisconnectWhileDisconnectInProgressTest(
tmmc.GetPseudoModemManager(), self),
DisconnectFailOtherTest(tmmc.GetPseudoModemManager(), self)
]
try:
self.device_manager.ShutdownAllExcept('cellular')
for test in tests:
test.Run()
finally:
self.device_manager.RestoreDevices()