• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
5import json
6import logging
7import time
8import sys
9
10from autotest_lib.client.bin import utils
11from autotest_lib.client.common_lib import error
12from autotest_lib.client.common_lib.cros.network import xmlrpc_datatypes
13from autotest_lib.server.cros import stress
14from autotest_lib.server.cros.network import wifi_cell_test_base
15from autotest_lib.server.cros.multimedia import remote_facade_factory
16
17_DELAY = 10
18_START_TIMEOUT_SECONDS = 20
19
20
21class network_WiFi_SuspendStress(wifi_cell_test_base.WiFiCellTestBase):
22    """
23    1. If the control file is control.integration, the test uses servo to
24       repeatedly close & open lid while running BrowserTests.
25    2. Any other control file , the test suspend and resume with powerd_dbus
26       command and assert wifi connectivity to router.
27    """
28    version = 1
29
30
31    def parse_additional_arguments(self, commandline_args, additional_params):
32        """Hook into super class to take control files parameters.
33
34        @param commandline_args dict of parsed parameters from the autotest.
35        @param additional_params list of tuple(HostapConfig,
36                                               AssociationParameters).
37        """
38        self._configurations = additional_params
39
40
41    def logged_in(self):
42        """Checks if the host has a logged in user.
43
44        @return True if a user is logged in on the device.
45
46        """
47        try:
48            out = self._host.run('cryptohome --action=status').stdout
49        except:
50            return False
51        try:
52            status = json.loads(out.strip())
53        except ValueError:
54            logging.info('Cryptohome did not return a value.')
55            return False
56
57        success = any((mount['mounted'] for mount in status['mounts']))
58        if success:
59            # Chrome needs a few moments to get ready, otherwise an immediate
60            # suspend will power down the system.
61            time.sleep(5)
62        return success
63
64
65    def check_servo_lid_open_support(self):
66        """ Check if DUT supports servo lid_open/close. Ref:http://b/37436993"""
67        try:
68            self._host.servo.lid_close()
69            self._host.servo.lid_open()
70        except AssertionError:
71            raise error.TestNAError('Error setting lid_open status. '
72                                    'Skipping test run on this board. %s.'
73                                    % sys.exc_info()[1])
74
75
76    def stress_wifi_suspend(self, try_servo=True):
77        """ Perform the suspend stress.
78
79        @param try_servo:option to toogle use powerd vs servo_lid to suspend.
80        """
81        # servo might be taking time to come up; wait a bit
82        if not self._host.servo and try_servo:
83           time.sleep(10)
84
85        boot_id = self._host.get_boot_id()
86        if (not try_servo or
87                self._host.servo.get('lid_open') == 'not_applicable'):
88            self.context.client.do_suspend(_DELAY)
89        else:
90            self._host.servo.lid_close()
91            self._host.wait_down(timeout=_DELAY)
92            self._host.servo.lid_open()
93            self._host.wait_up(timeout=_DELAY)
94
95        self._host.test_wait_for_resume(boot_id)
96        state_info = self.context.wait_for_connection(
97            self.context.router.get_ssid())
98        self._timings.append(state_info.time)
99
100
101    def powerd_non_servo_wifi_suspend(self):
102        """ Perform the suspend stress with powerdbus."""
103        self.stress_wifi_suspend(try_servo=False)
104
105
106    def run_once(self, suspends=5, integration=None):
107        self._host = self.context.client.host
108
109        for router_conf, client_conf in self._configurations:
110            self.context.configure(configuration_parameters=router_conf)
111            assoc_params = xmlrpc_datatypes.AssociationParameters(
112                is_hidden=client_conf.is_hidden,
113                security_config=client_conf.security_config,
114                ssid=self.context.router.get_ssid())
115            self.context.assert_connect_wifi(assoc_params)
116            self._timings = list()
117
118            if integration:
119                if not self._host.servo:
120                    raise error.TestNAError('Servo object returned None. '
121                                            'Check if servo is missing or bad')
122
123                # If the DUT is up and cold_reset is set to on, that means the
124                # DUT does not support cold_reset. We can't run the test,
125                # because it may get in a bad state and we won't be able
126                # to recover.
127                if self._host.servo.get('cold_reset') == 'on':
128                    raise error.TestNAError('This DUT does not support '
129                                            'cold reset, exiting')
130                self.factory = remote_facade_factory.RemoteFacadeFactory(
131                        self._host, no_chrome=True)
132                logging.info('Running Wifi Suspend Stress Integration test.')
133                browser_facade = self.factory.create_browser_facade()
134                browser_facade.start_default_chrome()
135                utils.poll_for_condition(condition=self.logged_in,
136                                         timeout=_START_TIMEOUT_SECONDS,
137                                         sleep_interval=1,
138                                         desc='User not logged in.')
139                self.check_servo_lid_open_support()
140                stressor = stress.CountedStressor(self.stress_wifi_suspend)
141            else:
142                logging.info('Running Non integration Wifi Stress test.')
143                stressor = stress.CountedStressor(
144                        self.powerd_non_servo_wifi_suspend)
145
146            stressor.start(suspends)
147            stressor.wait()
148
149            perf_dict = {'fastest': max(self._timings),
150                         'slowest': min(self._timings),
151                         'average': (float(sum(self._timings)) /
152                                     len(self._timings))}
153            for key in perf_dict:
154                self.output_perf_value(description=key,
155                    value=perf_dict[key],
156                    units='seconds',
157                    higher_is_better=False,
158                    graph=router_conf.perf_loggable_description)
159
160
161    def cleanup(self):
162        """Cold reboot the device so the WiFi card is back in a good state."""
163        if self._host.servo and self._host.servo.get('cold_reset') == 'off':
164            self._host.servo.get_power_state_controller().reset()
165