Home | History | Annotate | Download | only in network_WiFi_ReconnectInDarkResume
      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 contextlib
      6 import logging
      7 import time
      8 
      9 from autotest_lib.client.common_lib import error
     10 from autotest_lib.server.cros.network import hostap_config
     11 from autotest_lib.server.cros.network import lucid_sleep_test_base
     12 from autotest_lib.server.cros.network import wifi_client
     13 
     14 class network_WiFi_ReconnectInDarkResume(
     15         lucid_sleep_test_base.LucidSleepTestBase):
     16     """Test that known WiFi access points wake up the system."""
     17 
     18     version = 1
     19 
     20     def run_once(self,
     21                  disconnect_before_suspend=False,
     22                  reconnect_to_same_ap=True,
     23                  num_iterations=1):
     24         """Body of the test
     25 
     26         @param disconnect_before_suspend: whether we disconnect the DUT before
     27         or after first suspending it.
     28         @param reconnect_to_same_ap: if this is true, during suspend, we bring
     29         up the same AP that the DUT was last connected to before the first
     30         suspend for the DUT to reconnect to.
     31         @param num_iterations: number of times to bring the AP down and up
     32         during dark resume. In each iteration, we bring the AP down once, and
     33         bring it up again once.
     34 
     35         """
     36         client = self.context.client
     37         router = self.context.router
     38 
     39         # We configure and connect to two APs (i.e. same AP configured with two
     40         # different SSIDs) so that the DUT has two preferred networks.
     41         first_ap_ssid = self.configure_and_connect_to_ap(
     42                 hostap_config.HostapConfig(channel=1))
     43         router.deconfig_aps()
     44         second_ap_ssid = self.configure_and_connect_to_ap(
     45                 hostap_config.HostapConfig(channel=1))
     46 
     47         if reconnect_to_same_ap:
     48             reconnect_ap_ssid = second_ap_ssid
     49         else:
     50             reconnect_ap_ssid = first_ap_ssid
     51 
     52         # Enable the dark connect feature in shill, and set the scan period.
     53         with contextlib.nested(
     54                 client.wake_on_wifi_features(
     55                         wifi_client.WAKE_ON_WIFI_DARKCONNECT),
     56                 client.net_detect_scan_period_seconds(
     57                         wifi_client.NET_DETECT_SCAN_WAIT_TIME_SECONDS)):
     58             logging.info('Set up WoWLAN')
     59 
     60             bring_ap_down_in_suspend = True
     61             if disconnect_before_suspend:
     62                 # If we disconnect before suspend, we do not need to bring the
     63                 # AP down again on the first suspend.
     64                 bring_ap_down_in_suspend = False
     65                 logging.info('Bringing AP %s down.' % router.get_ssid())
     66                 router.deconfig_aps()
     67                 time.sleep(wifi_client.DISCONNECT_WAIT_TIME_SECONDS)
     68 
     69             with self.dr_utils.suspend():
     70                 for iter_num in xrange(1, num_iterations+1):
     71                     logging.info('Iteration %d of %d' %
     72                             (iter_num, num_iterations))
     73                     # Wait for suspend actions to finish.
     74                     time.sleep(wifi_client.SUSPEND_WAIT_TIME_SECONDS)
     75 
     76                     if bring_ap_down_in_suspend:
     77                         logging.info('Bringing AP %s down.' % router.get_ssid())
     78                         router.deconfig_aps()
     79                         # Wait for the DUT to receive the disconnect, wake in
     80                         # dark resume, then suspend again. Wait a little more
     81                         # after that so we don't trigger the next dark resume
     82                         # too soon and  set off the throttling mechanism.
     83                         time.sleep(wifi_client.DISCONNECT_WAIT_TIME_SECONDS +
     84                                    wifi_client.DARK_RESUME_WAIT_TIME_SECONDS +
     85                                    60)
     86                     else:
     87                         # We will bring the AP back up after this, so we
     88                         # will need to bring the AP down on any subsequent
     89                         # iterations to test wake on disconnect.
     90                         bring_ap_down_in_suspend = True
     91 
     92                     # Bring the AP back up to wake up the DUT.
     93                     logging.info('Bringing AP %s up.' % reconnect_ap_ssid)
     94                     self.context.configure(hostap_config.HostapConfig(
     95                             ssid=reconnect_ap_ssid, channel=1))
     96 
     97                     # Wait long enough for the NIC on the DUT to perform a net
     98                     # detect scan, discover the AP with the white-listed SSID,
     99                     # wake up in dark resume, connect, then suspend again.
    100                     time.sleep(wifi_client.NET_DETECT_SCAN_WAIT_TIME_SECONDS +
    101                                wifi_client.DARK_RESUME_WAIT_TIME_SECONDS)
    102 
    103             client.check_connected_on_last_resume()
    104 
    105             num_dark_resumes = self.dr_utils.count_dark_resumes()
    106             if disconnect_before_suspend and num_iterations == 1:
    107                 # Only expect a single wake on SSID dark resume in this case
    108                 # since no wake on disconnect would have been triggered.
    109                 expected_num_dark_resumes = 1
    110             else:
    111                 # Expect at least one disconnect dark resume and one SSID dark
    112                 # resume per iteration.
    113                 # Note: this is not foolproof; excess wakes on some iteration
    114                 # can make up for a shortfall in dark resumes in another
    115                 # iteration.
    116                 expected_num_dark_resumes = 2 * num_iterations
    117             if num_dark_resumes < expected_num_dark_resumes:
    118                 raise error.TestFail('Client only came up in %d dark resumes '
    119                                      'during the test (expected: at least %d)' %
    120                                      (num_dark_resumes,
    121                                       expected_num_dark_resumes))
    122