1 # Copyright 2015 The Chromium OS Authors. All rights reserved. 2 # Use of this source code is governed by a BSD-style license that can be 3 # found in the LICENSE file. 4 5 import json 6 import logging 7 import time 8 from autotest_lib.client.common_lib import error 9 from autotest_lib.client.common_lib.cros.network import xmlrpc_datatypes 10 from autotest_lib.server import autotest 11 from autotest_lib.server.cros import stress 12 from autotest_lib.server.cros.network import wifi_cell_test_base 13 14 _DELAY = 10 15 _CLIENT_TERMINATION_FILE_PATH = '/tmp/simple_login_exit' 16 _START_TIMEOUT_SECONDS = 20 17 18 19 class network_WiFi_SuspendStress(wifi_cell_test_base.WiFiCellTestBase): 20 """Uses servo to repeatedly close & open lid while running BrowserTests.""" 21 version = 1 22 23 24 def parse_additional_arguments(self, commandline_args, additional_params): 25 """Hook into super class to take control files parameters. 26 27 @param commandline_args dict of parsed parameters from the autotest. 28 @param additional_params list of tuple(HostapConfig, 29 AssociationParameters). 30 """ 31 self._configurations = additional_params 32 33 34 def logged_in(self): 35 """Checks if the host has a logged in user. 36 37 @return True if a user is logged in on the device. 38 39 """ 40 try: 41 out = self._host.run('cryptohome --action=status').stdout 42 except: 43 return False 44 try: 45 status = json.loads(out.strip()) 46 except ValueError: 47 logging.info('Cryptohome did not return a value.') 48 return False 49 50 success = any((mount['mounted'] for mount in status['mounts'])) 51 if success: 52 # Chrome needs a few moments to get ready, otherwise an immediate 53 # suspend will power down the system. 54 time.sleep(5) 55 return success 56 57 58 def stress_wifi_suspend(self): 59 """Perform the suspend stress.""" 60 if self._host.servo.get('lid_open') == 'not_applicable': 61 self.context.client.do_suspend(10) 62 else: 63 self._host.servo.lid_close() 64 self._host.wait_down(timeout=_DELAY) 65 self._host.servo.lid_open() 66 self._host.wait_up(timeout=_DELAY) 67 68 state_info = self.context.wait_for_connection( 69 self.context.router.get_ssid()) 70 self._timings.append(state_info.time) 71 72 73 def exit_client(self): 74 """End the client side test.""" 75 self._host.run('touch %s' % _CLIENT_TERMINATION_FILE_PATH) 76 77 78 def run_once(self, suspends=5): 79 self._host = self.context.client.host 80 81 if not self._host.servo: 82 raise error.TestNAError( 83 'Servo object returned None. Check if servo is missing or bad') 84 85 # If the DUT is up and cold_reset is set to on, that means the DUT does 86 # not support cold_reset. We can't run the test, because it may get 87 # in a bad state and we won't be able to recover. 88 if self._host.servo.get('cold_reset') == 'on': 89 raise error.TestNAError('This DUT does not support cold reset, ' 90 'exiting') 91 for router_conf, client_conf in self._configurations: 92 self.context.configure(configuration_parameters=router_conf) 93 assoc_params = xmlrpc_datatypes.AssociationParameters( 94 is_hidden=client_conf.is_hidden, 95 security_config=client_conf.security_config, 96 ssid=self.context.router.get_ssid()) 97 self.context.assert_connect_wifi(assoc_params) 98 99 self._timings = list() 100 101 autotest_client = autotest.Autotest(self._host) 102 stressor = stress.CountedStressor(self.stress_wifi_suspend, 103 on_exit=self.exit_client) 104 stressor.start(suspends, 105 start_condition=self.logged_in, 106 start_timeout_secs=_START_TIMEOUT_SECONDS) 107 autotest_client.run_test('desktopui_SimpleLogin') 108 stressor.wait() 109 110 perf_dict = {'fastest': max(self._timings), 111 'slowest': min(self._timings), 112 'average': (float(sum(self._timings)) / 113 len(self._timings))} 114 for key in perf_dict: 115 self.output_perf_value(description=key, 116 value=perf_dict[key], 117 units='seconds', 118 higher_is_better=False, 119 graph=router_conf.perf_loggable_description) 120 121 122 def cleanup(self): 123 """Cold reboot the device so the WiFi card is back in a good state.""" 124 if self._host.servo and self._host.servo.get('cold_reset') == 'off': 125 self._host.servo.get_power_state_controller().reset() 126