1#!/usr/bin/env python3.4 2# 3# Copyright 2016 - The Android Open Source Project 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16 17import logging 18import time 19 20import acts.signals as signals 21 22from acts import asserts 23from acts import base_test 24from acts.controllers import android_device 25from acts.controllers import attenuator 26from acts.test_decorators import test_tracker_info 27from acts.test_utils.wifi import wifi_test_utils as wutils 28from acts.test_utils.wifi.WifiBaseTest import WifiBaseTest 29 30WifiEnums = wutils.WifiEnums 31 32AP_1 = 0 33AP_2 = 1 34AP_1_2G_ATTENUATOR = 0 35AP_1_5G_ATTENUATOR = 1 36AP_2_2G_ATTENUATOR = 2 37AP_2_5G_ATTENUATOR = 3 38ATTENUATOR_INITIAL_SETTING = 60 39# WifiNetworkSelector imposes a 10 seconds gap between two selections 40NETWORK_SELECTION_TIME_GAP = 12 41 42 43class WifiNetworkSelectorTest(WifiBaseTest): 44 """These tests verify the behavior of the Android Wi-Fi Network Selector 45 feature. 46 """ 47 48 def __init__(self, controllers): 49 WifiBaseTest.__init__(self, controllers) 50 51 def setup_class(self): 52 self.dut = self.android_devices[0] 53 wutils.wifi_test_device_init(self.dut) 54 req_params = [] 55 opt_param = ["open_network", "reference_networks"] 56 self.unpack_userparams( 57 req_param_names=req_params, opt_param_names=opt_param) 58 59 if "AccessPoint" in self.user_params: 60 self.legacy_configure_ap_and_start(ap_count=2) 61 62 def setup_test(self): 63 #reset and clear all saved networks on the DUT 64 wutils.reset_wifi(self.dut) 65 #move the APs out of range 66 for attenuator in self.attenuators: 67 attenuator.set_atten(ATTENUATOR_INITIAL_SETTING) 68 #turn on the screen 69 self.dut.droid.wakeLockAcquireBright() 70 self.dut.droid.wakeUpNow() 71 self.dut.ed.clear_all_events() 72 73 def teardown_test(self): 74 #turn off the screen 75 self.dut.droid.wakeLockRelease() 76 self.dut.droid.goToSleepNow() 77 78 def on_fail(self, test_name, begin_time): 79 self.dut.take_bug_report(test_name, begin_time) 80 self.dut.cat_adb_log(test_name, begin_time) 81 82 def teardown_class(self): 83 if "AccessPoint" in self.user_params: 84 del self.user_params["reference_networks"] 85 del self.user_params["open_network"] 86 87 """ Helper Functions """ 88 89 def add_networks(self, ad, networks): 90 """Add Wi-Fi networks to an Android device and verify the networks were 91 added correctly. 92 93 Args: 94 ad: the AndroidDevice object to add networks to. 95 networks: a list of dicts, each dict represents a Wi-Fi network. 96 """ 97 for network in networks: 98 ret = ad.droid.wifiAddNetwork(network) 99 asserts.assert_true(ret != -1, "Failed to add network %s" % 100 network) 101 ad.droid.wifiEnableNetwork(ret, 0) 102 configured_networks = ad.droid.wifiGetConfiguredNetworks() 103 logging.debug("Configured networks: %s", configured_networks) 104 105 def connect_and_verify_connected_bssid(self, expected_bssid): 106 """Start a scan to get the DUT connected to an AP and verify the DUT 107 is connected to the correct BSSID. 108 109 Args: 110 expected_bssid: Network bssid to which connection. 111 112 Returns: 113 True if connection to given network happen, else return False. 114 """ 115 #wait for the attenuator to stablize 116 time.sleep(10) 117 #force start a single scan so we don't have to wait for the 118 #WCM scheduled scan. 119 wutils.start_wifi_connection_scan(self.dut) 120 #wait for connection 121 time.sleep(20) 122 #verify connection 123 actual_network = self.dut.droid.wifiGetConnectionInfo() 124 logging.info("Actual network: %s", actual_network) 125 try: 126 asserts.assert_equal(expected_bssid, 127 actual_network[WifiEnums.BSSID_KEY]) 128 except: 129 msg = "Device did not connect to any network." 130 raise signals.TestFailure(msg) 131 132 """ Tests Begin """ 133 134 @test_tracker_info(uuid="ffa5e278-db3f-4e17-af11-6c7a3e7c5cc2") 135 def test_network_selector_automatic_connection(self): 136 """ 137 1. Add one saved network to DUT. 138 2. Move the DUT in range. 139 3. Verify the DUT is connected to the network. 140 """ 141 #add a saved network to DUT 142 networks = [self.reference_networks[AP_1]['5g']] 143 self.add_networks(self.dut, networks) 144 #move the DUT in range 145 self.attenuators[AP_1_5G_ATTENUATOR].set_atten(0) 146 #verify 147 self.connect_and_verify_connected_bssid(self.reference_networks[AP_1][ 148 '5g']['bssid']) 149 150 @test_tracker_info(uuid="3ea818f2-10d7-4aad-bfab-7d8fb25aae78") 151 def test_network_selector_basic_connection_prefer_5g(self): 152 """ 153 1. Add one saved SSID with 2G and 5G BSSIDs of similar RSSI. 154 2. Move the DUT in range. 155 3. Verify the DUT is connected to the 5G BSSID. 156 """ 157 #add a saved network with both 2G and 5G BSSIDs to DUT 158 # TODO: bmahadev Change this to a single SSID once we migrate tests to 159 # use dynamic AP. 160 networks = [self.reference_networks[AP_1]['2g'], 161 self.reference_networks[AP_1]['5g']] 162 self.add_networks(self.dut, networks) 163 #move the DUT in range 164 self.attenuators[AP_1_2G_ATTENUATOR].set_atten(0) 165 self.attenuators[AP_1_5G_ATTENUATOR].set_atten(0) 166 #verify 167 self.connect_and_verify_connected_bssid(self.reference_networks[AP_1][ 168 '5g']['bssid']) 169 170 @test_tracker_info(uuid="bebb29ca-4486-4cde-b390-c5f8f2e1580c") 171 def test_network_selector_prefer_stronger_rssi(self): 172 """ 173 1. Add two saved SSIDs to DUT, same band, one has stronger RSSI 174 than the other. 175 2. Move the DUT in range. 176 3. Verify the DUT is connected to the SSID with stronger RSSI. 177 """ 178 #add a 2G and a 5G saved network to DUT 179 networks = [ 180 self.reference_networks[AP_1]['2g'], self.reference_networks[AP_2][ 181 '2g'] 182 ] 183 self.add_networks(self.dut, networks) 184 #move the DUT in range 185 self.attenuators[AP_1_2G_ATTENUATOR].set_atten(20) 186 self.attenuators[AP_2_2G_ATTENUATOR].set_atten(40) 187 #verify 188 self.connect_and_verify_connected_bssid(self.reference_networks[AP_1][ 189 '2g']['bssid']) 190 191 @test_tracker_info(uuid="f9f72dc5-034f-4fe2-a27d-df1b6cae76cd") 192 def test_network_selector_prefer_secure_over_open_network(self): 193 """ 194 1. Add two saved networks to DUT, same band, similar RSSI, one uses 195 WPA2 security, the other is open. 196 2. Move the DUT in range. 197 3. Verify the DUT is connected to the secure network that uses WPA2. 198 """ 199 #add a open network and a secure saved network to DUT 200 networks = [ 201 self.open_network[AP_1]['5g'], self.reference_networks[AP_1]['5g'] 202 ] 203 self.add_networks(self.dut, networks) 204 #move the DUT in range 205 #TODO: control open network attenuator 206 self.attenuators[AP_1_5G_ATTENUATOR].set_atten(0) 207 #verify 208 self.connect_and_verify_connected_bssid(self.reference_networks[AP_1][ 209 '5g']['bssid']) 210 211 @test_tracker_info(uuid="ab2c527c-0f9c-4f09-a13f-e3f461b7da52") 212 def test_network_selector_blacklist_by_connection_failure(self): 213 """ 214 1. Add two saved secured networks X and Y to DUT. X has stronger 215 RSSI than Y. X has wrong password configured. 216 2. Move the DUT in range. 217 3. Verify the DUT is connected to network Y. 218 """ 219 #add two saved networks to DUT, and one of them is configured with incorrect password 220 wrong_passwd_network = self.reference_networks[AP_1]['5g'].copy() 221 wrong_passwd_network['password'] += 'haha' 222 networks = [wrong_passwd_network, self.reference_networks[AP_2]['5g']] 223 self.add_networks(self.dut, networks) 224 #make both AP_1 5G and AP_2 5G in range, and AP_1 5G has stronger RSSI than AP_2 5G 225 self.attenuators[AP_1_5G_ATTENUATOR].set_atten(0) 226 self.attenuators[AP_2_5G_ATTENUATOR].set_atten(10) 227 #start 3 scans to get AP_1 5G blacklisted because of the incorrect password 228 count = 0 229 while count < 3: 230 wutils.start_wifi_connection_scan(self.dut) 231 time.sleep(NETWORK_SELECTION_TIME_GAP) 232 count += 1 233 #verify 234 self.connect_and_verify_connected_bssid(self.reference_networks[AP_2][ 235 '5g']['bssid']) 236 237 @test_tracker_info(uuid="71d88fcf-c7b8-4fd2-a7cb-84ac4a130ecf") 238 def test_network_selector_2g_to_5g_prefer_same_SSID(self): 239 """ 240 1. Add SSID_A and SSID_B to DUT. Both SSIDs have both 2G and 5G 241 BSSIDs. 242 2. Attenuate the networks so that the DUT is connected to SSID_A's 243 2G in the beginning. 244 3. Increase the RSSI of both SSID_A's 5G and SSID_B's 5G. 245 4. Verify the DUT switches to SSID_A's 5G. 246 """ 247 #add two saved networks to DUT 248 networks = [ 249 self.reference_networks[AP_1]['2g'], self.reference_networks[AP_2][ 250 '2g'] 251 ] 252 self.add_networks(self.dut, networks) 253 #make AP_1 2G in range 254 self.attenuators[AP_1_2G_ATTENUATOR].set_atten(0) 255 #verify 256 self.connect_and_verify_connected_bssid(self.reference_networks[AP_1][ 257 '2g']['bssid']) 258 #make both AP_1 and AP_2 5G in range with similar RSSI 259 self.attenuators[AP_1_5G_ATTENUATOR].set_atten(0) 260 self.attenuators[AP_2_5G_ATTENUATOR].set_atten(0) 261 #ensure the time gap between two network selections 262 time.sleep(NETWORK_SELECTION_TIME_GAP) 263 #verify 264 self.connect_and_verify_connected_bssid(self.reference_networks[AP_1][ 265 '5g']['bssid']) 266 267 @test_tracker_info(uuid="c1243cf4-d96e-427e-869e-3d640bee3f28") 268 def test_network_selector_2g_to_5g_different_ssid(self): 269 """ 270 1. Add SSID_A and SSID_B to DUT. Both SSIDs have both 2G and 5G 271 BSSIDs. 272 2. Attenuate the networks so that the DUT is connected to SSID_A's 273 2G in the beginning. 274 3. Increase the RSSI of SSID_B's 5G while attenuate down SSID_A's 275 2G RSSI. 276 4. Verify the DUT switches to SSID_B's 5G. 277 """ 278 #add two saved networks to DUT 279 networks = [ 280 self.reference_networks[AP_1]['2g'], self.reference_networks[AP_2][ 281 '2g'] 282 ] 283 self.add_networks(self.dut, networks) 284 #make both AP_1 2G and AP_2 5G in range, and AP_1 2G 285 #has much stronger RSSI than AP_2 5G 286 self.attenuators[AP_1_2G_ATTENUATOR].set_atten(0) 287 self.attenuators[AP_2_5G_ATTENUATOR].set_atten(20) 288 #verify 289 self.connect_and_verify_connected_bssid(self.reference_networks[AP_1][ 290 '2g']['bssid']) 291 #bump up AP_2 5G RSSI and reduce AP_1 2G RSSI 292 self.attenuators[AP_1_2G_ATTENUATOR].set_atten(40) 293 self.attenuators[AP_2_5G_ATTENUATOR].set_atten(0) 294 #ensure the time gap between two network selections 295 time.sleep(NETWORK_SELECTION_TIME_GAP) 296 #verify 297 self.connect_and_verify_connected_bssid(self.reference_networks[AP_2][ 298 '5g']['bssid']) 299 300 @test_tracker_info(uuid="10da95df-83ed-4447-89f8-735b08dbe2eb") 301 def test_network_selector_5g_to_2g_same_ssid(self): 302 """ 303 1. Add one SSID that has both 2G and 5G to the DUT. 304 2. Attenuate down the 2G RSSI. 305 3. Connect the DUT to the 5G BSSID. 306 4. Bring up the 2G RSSI and attenuate down the 5G RSSI. 307 5. Verify the DUT switches to the 2G BSSID. 308 """ 309 #add a saved network to DUT 310 networks = [self.reference_networks[AP_1]['2g']] 311 self.add_networks(self.dut, networks) 312 #make both AP_1 2G and AP_2 5G in range, and AP_1 5G 313 #has much stronger RSSI than AP_2 2G 314 self.attenuators[AP_1_5G_ATTENUATOR].set_atten(0) 315 self.attenuators[AP_1_2G_ATTENUATOR].set_atten(50) 316 #verify 317 self.connect_and_verify_connected_bssid(self.reference_networks[AP_1][ 318 '5g']['bssid']) 319 #bump up AP_1 2G RSSI and reduce AP_1 5G RSSI 320 self.attenuators[AP_1_2G_ATTENUATOR].set_atten(0) 321 self.attenuators[AP_1_5G_ATTENUATOR].set_atten(30) 322 #ensure the time gap between two network selections 323 time.sleep(NETWORK_SELECTION_TIME_GAP) 324 #verify 325 self.connect_and_verify_connected_bssid(self.reference_networks[AP_1][ 326 '2g']['bssid']) 327 328 @test_tracker_info(uuid="ead78ae0-27ab-4bb8-ae77-0b9fe588436a") 329 def test_network_selector_stay_on_sufficient_network(self): 330 """ 331 1. Add two 5G WPA2 BSSIDs X and Y to the DUT. X has higher RSSI 332 than Y. 333 2. Connect the DUT to X. 334 3. Change attenuation so that Y's RSSI goes above X's. 335 4. Verify the DUT stays on X. 336 """ 337 #add two saved networks to DUT 338 networks = [ 339 self.reference_networks[AP_1]['5g'], self.reference_networks[AP_2][ 340 '5g'] 341 ] 342 self.add_networks(self.dut, networks) 343 #make both AP_1 5G and AP_2 5G in range, and AP_1 5G 344 #has stronger RSSI than AP_2 5G 345 self.attenuators[AP_1_5G_ATTENUATOR].set_atten(10) 346 self.attenuators[AP_2_5G_ATTENUATOR].set_atten(20) 347 #verify 348 self.connect_and_verify_connected_bssid(self.reference_networks[AP_1][ 349 '5g']['bssid']) 350 #bump up AP_2 5G RSSI over AP_1 5G RSSI 351 self.attenuators[AP_2_5G_ATTENUATOR].set_atten(0) 352 #ensure the time gap between two network selections 353 time.sleep(NETWORK_SELECTION_TIME_GAP) 354 #verify 355 self.connect_and_verify_connected_bssid(self.reference_networks[AP_1][ 356 '5g']['bssid']) 357 358 @test_tracker_info(uuid="5470010f-8b62-4b1c-8b83-1f91422eced0") 359 def test_network_selector_stay_on_user_selected_network(self): 360 """ 361 1. Connect the DUT to SSID_A with a very low RSSI via the user select code path. 362 2. Add SSID_B to the DUT as saved network. SSID_B has higher RSSI than SSID_A. 363 3. Start a scan and network selection. 364 4. Verify DUT stays on SSID_A. 365 """ 366 #make AP_1 5G in range with a low RSSI 367 self.attenuators[AP_1_5G_ATTENUATOR].set_atten(10) 368 #connect to AP_1 via user selection 369 wutils.wifi_connect(self.dut, self.reference_networks[AP_1]['5g']) 370 #verify 371 self.connect_and_verify_connected_bssid(self.reference_networks[AP_1][ 372 '5g']['bssid']) 373 #make AP_2 5G in range with a strong RSSI 374 self.attenuators[AP_2_5G_ATTENUATOR].set_atten(0) 375 #add AP_2 as a saved network to DUT 376 networks = [self.reference_networks[AP_2]['5g']] 377 self.add_networks(self.dut, networks) 378 #ensure the time gap between two network selections 379 time.sleep(NETWORK_SELECTION_TIME_GAP) 380 #verify we are still connected to AP_1 5G 381 self.connect_and_verify_connected_bssid(self.reference_networks[AP_1][ 382 '5g']['bssid']) 383 384 @test_tracker_info(uuid="f08d8f73-8c94-42af-bba9-4c49bbf16420") 385 def test_network_selector_reselect_after_forget_network(self): 386 """ 387 1. Add two 5G BSSIDs X and Y to the DUT. X has higher RSSI 388 than Y. 389 2. Connect the DUT to X. 390 3. Forget X. 391 5. Verify the DUT reselect and connect to Y. 392 """ 393 #add two saved networks to DUT 394 networks = [ 395 self.reference_networks[AP_1]['5g'], self.reference_networks[AP_2][ 396 '5g'] 397 ] 398 self.add_networks(self.dut, networks) 399 #make both AP_1 5G and AP_2 5G in range. AP_1 5G has stronger 400 #RSSI than AP_2 5G 401 self.attenuators[AP_1_5G_ATTENUATOR].set_atten(0) 402 self.attenuators[AP_2_5G_ATTENUATOR].set_atten(10) 403 #verify 404 self.connect_and_verify_connected_bssid(self.reference_networks[AP_1][ 405 '5g']['bssid']) 406 #forget AP_1 407 wutils.wifi_forget_network(self.dut, 408 self.reference_networks[AP_1]['5g']['SSID']) 409 #verify 410 self.connect_and_verify_connected_bssid(self.reference_networks[AP_2][ 411 '5g']['bssid']) 412