Home | History | Annotate | Download | only in network_WiFi_PMKSACaching
      1 # Copyright (c) 2013 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 logging
      6 import time
      7 
      8 from autotest_lib.client.common_lib import error
      9 from autotest_lib.client.common_lib.cros import site_eap_certs
     10 from autotest_lib.client.common_lib.cros.network import iw_runner
     11 from autotest_lib.client.common_lib.cros.network import ping_runner
     12 from autotest_lib.client.common_lib.cros.network import xmlrpc_datatypes
     13 from autotest_lib.client.common_lib.cros.network import xmlrpc_security_types
     14 from autotest_lib.server.cros.network import hostap_config
     15 from autotest_lib.server.cros.network import wifi_cell_test_base
     16 
     17 
     18 class network_WiFi_PMKSACaching(wifi_cell_test_base.WiFiCellTestBase):
     19     """Test that we use PMKSA caching where appropriate."""
     20     version = 1
     21     AP0_FREQUENCY = 2412
     22     AP1_FREQUENCY = 5220
     23     TIMEOUT_SECONDS = 15
     24 
     25 
     26     def dut_sees_bss(self, bssid):
     27         """
     28         Check if a DUT can see a BSS in scan results.
     29 
     30         @param bssid: string bssid of AP we expect to see in scan results.
     31         @return True iff scan results from DUT include the specified BSS.
     32 
     33         """
     34         runner = iw_runner.IwRunner(remote_host=self.context.client.host)
     35         is_requested_bss = lambda iw_bss: iw_bss.bss == bssid
     36         scan_results = runner.scan(self.context.client.wifi_if)
     37         return scan_results and filter(is_requested_bss, scan_results)
     38 
     39 
     40     def retry(self, func, reason, timeout_seconds=TIMEOUT_SECONDS):
     41         """
     42         Retry a function until it returns true or we time out.
     43 
     44         @param func: function that takes no parameters.
     45         @param reason: string concise description of what the function does.
     46         @param timeout_seconds: int number of seconds to wait for a True
     47                 response from |func|.
     48 
     49         """
     50         logging.info('Waiting for %s.', reason)
     51         start_time = time.time()
     52         while time.time() - start_time < timeout_seconds:
     53             if func():
     54                 return
     55             time.sleep(1)
     56         else:
     57             raise error.TestFail('Timed out waiting for %s.' % reason)
     58 
     59 
     60     def run_once(self):
     61         """Body of the test."""
     62         mode_n = hostap_config.HostapConfig.MODE_11N_PURE
     63         eap_config = xmlrpc_security_types.WPAEAPConfig(
     64                 server_ca_cert=site_eap_certs.ca_cert_1,
     65                 server_cert=site_eap_certs.server_cert_1,
     66                 server_key=site_eap_certs.server_private_key_1,
     67                 client_ca_cert=site_eap_certs.ca_cert_1,
     68                 client_cert=site_eap_certs.client_cert_1,
     69                 client_key=site_eap_certs.client_private_key_1,
     70                 # PMKSA caching is only defined for WPA2.
     71                 wpa_mode=xmlrpc_security_types.WPAConfig.MODE_PURE_WPA2)
     72         ap_config0 = hostap_config.HostapConfig(
     73                 mode=mode_n, frequency=self.AP0_FREQUENCY,
     74                 security_config=eap_config)
     75         self.context.configure(ap_config0)
     76         assoc_params = xmlrpc_datatypes.AssociationParameters(
     77                 ssid=self.context.router.get_ssid(),
     78                 security_config=eap_config)
     79         self.context.assert_connect_wifi(assoc_params)
     80         # Add another AP with identical configuration except in 5 Ghz.
     81         ap_config1 = hostap_config.HostapConfig(
     82                 mode=mode_n, ssid=self.context.router.get_ssid(),
     83                 frequency=self.AP1_FREQUENCY, security_config=eap_config)
     84         self.context.configure(ap_config1, multi_interface=True)
     85         bssid0 = self.context.router.get_hostapd_mac(0)
     86         bssid1 = self.context.router.get_hostapd_mac(1)
     87         self.retry(lambda: self.dut_sees_bss(bssid1), 'DUT to see second AP')
     88         self.context.client.request_roam(bssid1)
     89         if not self.context.client.wait_for_roam(
     90                 bssid1, timeout_seconds=self.TIMEOUT_SECONDS):
     91             raise error.TestFail('Failed to roam to second BSS.')
     92 
     93         self.context.router.deconfig_aps(instance=1, silent=True)
     94         if not self.context.client.wait_for_roam(
     95                 bssid0, timeout_seconds=self.TIMEOUT_SECONDS):
     96             raise error.TestFail('Failed to fall back to first BSS.')
     97 
     98         pinger = ping_runner.PingRunner(host=self.context.client.host)
     99         self.retry(lambda: pinger.simple_ping(
    100                            self.context.router.get_wifi_ip(0)),
    101                    'DUT to be able to ping first BSS after fallback')
    102         self.context.router.confirm_pmksa_cache_use(instance=0)
    103