blob: 34d4ab2f0042958780e197c0e2dd367bd2ac0e34 [file] [log] [blame]
# Copyright (c) 2010 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, time
from autotest_lib.client.bin import test
from autotest_lib.client.bin import utils
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 import network
from autotest_lib.client.cros import flimflam_test_path
import flimflam
class network_Portal(test.test):
version = 1
def GetConnectedService(self, service_name):
service = self.flim.FindElementByNameSubstring('Service',
service_name)
if service:
properties = service.GetProperties(utf8_strings=True)
state = properties['State']
if state in ('online', 'portal', 'ready'):
self.service = service
return True
return False
def TestConnect(self, service_name, expected_state, timeout_seconds=30):
"""Connect to a service and verifies the portal state
Args:
service_name: substring to match against services
expected_state: expected state of service after connecting
Returns:
True if the service is in the expected state
False otherwise
Raises:
error.TestFail on non-recoverable failure
"""
logging.info('TestConnect(%s, %s)' % (service_name, expected_state))
self.service.Disconnect()
state = self.flim.WaitForServiceState(
service=self.service,
expected_states=['idle', 'failure'],
timeout=5)[0]
self.service.Connect()
state = self.flim.WaitForServiceState(
service=self.service,
expected_states=['portal', 'online', 'failure'],
timeout=timeout_seconds)[0]
if state != expected_state:
logging.error('Service state should be %s but is %s' %
(expected_state, state))
return False
return True
def run_once(self, force_failure, test_iterations=10, service_name='wifi'):
"""Run a test of the portal code.
Args:
force_failure: keyed values for different flavors of tests
'portal' - blackhole the hosts used for http ensure that
the connection manager detects a portal.
'dns' - blackhole the DNS servers and ensure that
the connection manager detects a portal.
False - Do not force any failes and ensure that the
connection manager detects the service is online.
'partial-dns'
- blackhole the first DNS server and ensure that the
connection manager detects the service is online.
"""
errors = 0
if force_failure == 'portal':
# depends on getting a consistent IP address from DNS
# depends on portal detection using www.google.com or
# clients3.google.com
hosts = [('clients3.google.com', 'OUTPUT'),
('www.google.com', 'OUTPUT')]
expected_state = 'portal'
else:
hosts = []
expected_state = 'online'
with backchannel.Backchannel():
# Immediately after the backchannel is setup there may be no
# services. Try for up to 20 seconds to find one.
# Getting to the ready state on an encrypted network can
# be slow.
self.flim = flimflam.FlimFlam()
self.flim.SetDebugTags('portal+service')
utils.poll_for_condition(
lambda: self.GetConnectedService(service_name),
error.TestFail(
'No service named "%s" available' % service_name),
timeout=20)
nameservers = []
if force_failure == 'dns':
nameservers = network.NameServersForService(self.flim,
self.service)
expected_state = 'portal'
elif force_failure == 'partial-dns':
nameservers = network.NameServersForService(self.flim,
self.service)
nameservers = nameservers[0:1]
hosts += [(host, 'INPUT') for host in nameservers]
with cell_tools.BlackholeContext(hosts):
for _ in range(test_iterations):
if not self.TestConnect(service_name, expected_state):
errors += 1
if errors:
raise error.TestFail('%d failures to enter state %s ' % (
errors, expected_state))
#
# Test the portal retry timer which should transition the
# service to online (at most) 1 minute after the portal
# restriction is removed.
#
if expected_state == 'portal':
with cell_tools.BlackholeContext(hosts):
if not self.TestConnect(service_name, 'portal'):
raise error.TestFail('Failed to enter state portal')
state = self.flim.WaitForServiceState(
service=self.service,
expected_states=['online'],
timeout=60)[0]
if state != 'online':
raise error.TestFail('Failed to enter state online')
# Check that we recheck and find a portal if the
# PortalList changes
with cell_tools.BlackholeContext(hosts):
self.flim.SetCheckPortalList('wifi,ethernet,cellular')
state = self.flim.WaitForServiceState(
service=self.service,
expected_states=['portal'],
timeout=60)[0]
if state != 'portal':
raise error.TestFail('Expected to enter state portal')