Home | History | Annotate | Download | only in network_WiFi_SuspendStress
      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 
     61         # servo might be taking time to come up; wait a bit
     62         if not self._host.servo:
     63            time.sleep(10)
     64 
     65         if self._host.servo.get('lid_open') == 'not_applicable':
     66             self.context.client.do_suspend(10)
     67         else:
     68             self._host.servo.lid_close()
     69             self._host.wait_down(timeout=_DELAY)
     70             self._host.servo.lid_open()
     71             self._host.wait_up(timeout=_DELAY)
     72 
     73         state_info = self.context.wait_for_connection(
     74             self.context.router.get_ssid())
     75         self._timings.append(state_info.time)
     76 
     77 
     78     def exit_client(self):
     79         """End the client side test."""
     80         self._host.run('touch %s' % _CLIENT_TERMINATION_FILE_PATH)
     81 
     82 
     83     def run_once(self, suspends=5):
     84         self._host = self.context.client.host
     85 
     86         if not self._host.servo:
     87             raise error.TestNAError(
     88                 'Servo object returned None. Check if servo is missing or bad')
     89 
     90         # If the DUT is up and cold_reset is set to on, that means the DUT does
     91         # not support cold_reset.  We can't run the test, because it may get
     92         # in a bad state and we won't be able to recover.
     93         if self._host.servo.get('cold_reset') == 'on':
     94             raise error.TestNAError('This DUT does not support cold reset, '
     95                                     'exiting')
     96         for router_conf, client_conf in self._configurations:
     97             self.context.configure(configuration_parameters=router_conf)
     98             assoc_params = xmlrpc_datatypes.AssociationParameters(
     99                 is_hidden=client_conf.is_hidden,
    100                 security_config=client_conf.security_config,
    101                 ssid=self.context.router.get_ssid())
    102             self.context.assert_connect_wifi(assoc_params)
    103 
    104             self._timings = list()
    105 
    106             autotest_client = autotest.Autotest(self._host)
    107             stressor = stress.CountedStressor(self.stress_wifi_suspend,
    108                                               on_exit=self.exit_client)
    109             stressor.start(suspends,
    110                            start_condition=self.logged_in,
    111                            start_timeout_secs=_START_TIMEOUT_SECONDS)
    112             autotest_client.run_test('desktopui_SimpleLogin')
    113             stressor.wait()
    114 
    115             perf_dict = {'fastest': max(self._timings),
    116                          'slowest': min(self._timings),
    117                          'average': (float(sum(self._timings)) /
    118                                      len(self._timings))}
    119             for key in perf_dict:
    120                 self.output_perf_value(description=key,
    121                     value=perf_dict[key],
    122                     units='seconds',
    123                     higher_is_better=False,
    124                     graph=router_conf.perf_loggable_description)
    125 
    126 
    127     def cleanup(self):
    128         """Cold reboot the device so the WiFi card is back in a good state."""
    129         if self._host.servo and self._host.servo.get('cold_reset') == 'off':
    130             self._host.servo.get_power_state_controller().reset()
    131