Home | History | Annotate | Download | only in network_WiFi_BgscanBackoff
      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.network import iw_runner
     10 from autotest_lib.client.common_lib.cros.network import ping_runner
     11 from autotest_lib.client.common_lib.cros.network import xmlrpc_datatypes
     12 from autotest_lib.server.cros.network import hostap_config
     13 from autotest_lib.server.cros.network import wifi_cell_test_base
     14 
     15 
     16 class network_WiFi_BgscanBackoff(wifi_cell_test_base.WiFiCellTestBase):
     17     """Test that background scan backs off when there is foreground traffic."""
     18     version = 1
     19 
     20     BGSCAN_SAMPLE_PERIOD_SECONDS = 100
     21     NO_BGSCAN_SAMPLE_PERIOD_SECONDS = 10
     22     CONFIGURED_BGSCAN_INTERVAL_SECONDS = 7
     23     PING_INTERVAL_SECONDS = 0.1
     24     LATENCY_MARGIN_MS = 200
     25     THRESHOLD_BASELINE_LATENCY_MS = 100
     26 
     27 
     28     def run_once(self):
     29         """Body of the test."""
     30         get_assoc_params = lambda conf: xmlrpc_datatypes.AssociationParameters(
     31                 ssid=self.context.router.get_ssid(instance=0),
     32                 bgscan_config=conf)
     33         get_ping_config = lambda period: ping_runner.PingConfig(
     34                 self.context.get_wifi_addr(),
     35                 interval=self.PING_INTERVAL_SECONDS,
     36                 count=int(period / self.PING_INTERVAL_SECONDS))
     37         self.context.configure(hostap_config.HostapConfig(channel=1))
     38         bgscan_config = xmlrpc_datatypes.BgscanConfiguration(
     39                 short_interval=self.CONFIGURED_BGSCAN_INTERVAL_SECONDS,
     40                 long_interval=self.CONFIGURED_BGSCAN_INTERVAL_SECONDS,
     41                 method=xmlrpc_datatypes.BgscanConfiguration.SCAN_METHOD_SIMPLE)
     42         self.context.assert_connect_wifi(get_assoc_params(bgscan_config))
     43         logging.info('Pinging router with background scans for %d seconds.',
     44                      self.BGSCAN_SAMPLE_PERIOD_SECONDS)
     45         result_bgscan = self.context.client.ping(
     46                 get_ping_config(self.BGSCAN_SAMPLE_PERIOD_SECONDS))
     47         logging.info('Ping statistics with bgscan: %r', result_bgscan)
     48         # Bring up a second AP, make sure that it shows up in bgscans.
     49         self.context.configure(
     50                 hostap_config.HostapConfig(channel=11,
     51                                            min_streams=1,
     52                                            ssid=self.context.router.get_ssid()),
     53                 multi_interface=True)
     54         logging.info('Without a ping running, ensure that bgscans succeed.')
     55         ap_mac = self.context.router.get_hostapd_mac(ap_num=1)
     56         logging.debug('Looking for BSS %s', ap_mac)
     57         iw = iw_runner.IwRunner(remote_host=self.context.client.host)
     58         start_time = time.time()
     59         while time.time() - start_time < self.BGSCAN_SAMPLE_PERIOD_SECONDS:
     60             bsses = iw.scan_dump(self.context.client.wifi_if)
     61             logging.debug('Found BSSes: %r', bsses)
     62             if filter(lambda bss: bss.bss == ap_mac, bsses):
     63                 break
     64 
     65             time.sleep(1)
     66         else:
     67             raise error.TestFail('Background scans should detect new BSSes '
     68                                  'within an associated ESS.')
     69 
     70         self.context.router.deconfig_aps(instance=1)
     71         self.context.client.shill.disconnect(
     72                 self.context.router.get_ssid(instance=0))
     73         # Reconfigure AP, so the new bgscan setting can be correctly applied.
     74         self.context.configure(hostap_config.HostapConfig(channel=1))
     75         # Gather some statistics about ping latencies without scanning going on.
     76         self.context.assert_connect_wifi(get_assoc_params(None))
     77         logging.info('Pinging router without background scans for %d seconds.',
     78                      self.NO_BGSCAN_SAMPLE_PERIOD_SECONDS)
     79         result_no_bgscan = self.context.client.ping(
     80                 get_ping_config(self.NO_BGSCAN_SAMPLE_PERIOD_SECONDS))
     81         logging.info('Ping statistics without bgscan: %r', result_no_bgscan)
     82         if result_no_bgscan.max_latency > self.THRESHOLD_BASELINE_LATENCY_MS:
     83             raise error.TestFail('RTT latency is too high even without '
     84                                  'background scans: %f' %
     85                                  result_no_bgscan.max_latency)
     86 
     87         # Dwell time for scanning is usually configured to be around 100 ms,
     88         # since this is also the standard beacon interval.  Tolerate spikes in
     89         # latency up to 200 ms as a way of asking that our PHY be servicing
     90         # foreground traffic regularly during background scans.
     91         if (result_bgscan.max_latency >
     92                 self.LATENCY_MARGIN_MS + result_no_bgscan.avg_latency):
     93             raise error.TestFail('Significant difference in rtt due to bgscan: '
     94                                  '%.1f > %.1f + %d' %
     95                                  (result_bgscan.max_latency,
     96                                   result_no_bgscan.avg_latency,
     97                                   self.LATENCY_MARGIN_MS))
     98