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