blob: 15f1a173ff7506f49642217ed177fa4373737db4 [file] [log] [blame]
# Copyright 2015 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 json
import logging
import time
from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib.cros.network import xmlrpc_datatypes
from autotest_lib.server import autotest
from autotest_lib.server.cros import stress
from autotest_lib.server.cros.network import wifi_cell_test_base
_DELAY = 10
_CLIENT_TERMINATION_FILE_PATH = '/tmp/simple_login_exit'
_START_TIMEOUT_SECONDS = 20
class network_WiFi_SuspendStress(wifi_cell_test_base.WiFiCellTestBase):
"""Uses servo to repeatedly close & open lid while running BrowserTests."""
version = 1
def parse_additional_arguments(self, commandline_args, additional_params):
"""Hook into super class to take control files parameters.
@param commandline_args dict of parsed parameters from the autotest.
@param additional_params list of tuple(HostapConfig,
AssociationParameters).
"""
self._configurations = additional_params
def logged_in(self):
"""Checks if the host has a logged in user.
@return True if a user is logged in on the device.
"""
try:
out = self._host.run('cryptohome --action=status').stdout
except:
return False
try:
status = json.loads(out.strip())
except ValueError:
logging.info('Cryptohome did not return a value.')
return False
success = any((mount['mounted'] for mount in status['mounts']))
if success:
# Chrome needs a few moments to get ready, otherwise an immediate
# suspend will power down the system.
time.sleep(5)
return success
def stress_wifi_suspend(self):
"""Perform the suspend stress."""
# servo might be taking time to come up; wait a bit
if not self._host.servo:
time.sleep(10)
if self._host.servo.get('lid_open') == 'not_applicable':
self.context.client.do_suspend(10)
else:
self._host.servo.lid_close()
self._host.wait_down(timeout=_DELAY)
self._host.servo.lid_open()
self._host.wait_up(timeout=_DELAY)
state_info = self.context.wait_for_connection(
self.context.router.get_ssid())
self._timings.append(state_info.time)
def exit_client(self):
"""End the client side test."""
self._host.run('touch %s' % _CLIENT_TERMINATION_FILE_PATH)
def run_once(self, suspends=5):
self._host = self.context.client.host
if not self._host.servo:
raise error.TestNAError(
'Servo object returned None. Check if servo is missing or bad')
# If the DUT is up and cold_reset is set to on, that means the DUT does
# not support cold_reset. We can't run the test, because it may get
# in a bad state and we won't be able to recover.
if self._host.servo.get('cold_reset') == 'on':
raise error.TestNAError('This DUT does not support cold reset, '
'exiting')
for router_conf, client_conf in self._configurations:
self.context.configure(configuration_parameters=router_conf)
assoc_params = xmlrpc_datatypes.AssociationParameters(
is_hidden=client_conf.is_hidden,
security_config=client_conf.security_config,
ssid=self.context.router.get_ssid())
self.context.assert_connect_wifi(assoc_params)
self._timings = list()
autotest_client = autotest.Autotest(self._host)
stressor = stress.CountedStressor(self.stress_wifi_suspend,
on_exit=self.exit_client)
stressor.start(suspends,
start_condition=self.logged_in,
start_timeout_secs=_START_TIMEOUT_SECONDS)
autotest_client.run_test('desktopui_SimpleLogin')
stressor.wait()
perf_dict = {'fastest': max(self._timings),
'slowest': min(self._timings),
'average': (float(sum(self._timings)) /
len(self._timings))}
for key in perf_dict:
self.output_perf_value(description=key,
value=perf_dict[key],
units='seconds',
higher_is_better=False,
graph=router_conf.perf_loggable_description)
def cleanup(self):
"""Cold reboot the device so the WiFi card is back in a good state."""
if self._host.servo and self._host.servo.get('cold_reset') == 'off':
self._host.servo.get_power_state_controller().reset()