1# !/usr/bin/env python3.4 2# 3# Copyright 2017 - 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 re 18from acts import asserts 19from acts.controllers.android_device import SL4A_APK_NAME 20from acts.libs.ota import ota_updater 21import acts.signals as signals 22from acts.test_decorators import test_tracker_info 23from acts.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_5G 24import acts.test_utils.wifi.wifi_test_utils as wutils 25from acts.test_utils.wifi.WifiBaseTest import WifiBaseTest 26import acts.utils as utils 27 28WifiEnums = wutils.WifiEnums 29SSID = WifiEnums.SSID_KEY 30PWD = WifiEnums.PWD_KEY 31NETID = WifiEnums.NETID_KEY 32# Default timeout used for reboot, toggle WiFi and Airplane mode, 33# for the system to settle down after the operation. 34DEFAULT_TIMEOUT = 10 35BAND_2GHZ = 0 36BAND_5GHZ = 1 37 38 39class WifiAutoUpdateTest(WifiBaseTest): 40 """Tests for APIs in Android's WifiManager class. 41 42 Test Bed Requirement: 43 * One Android device 44 * Several Wi-Fi networks visible to the device, including an open Wi-Fi 45 network. 46 """ 47 48 def __init__(self, controllers): 49 WifiBaseTest.__init__(self, controllers) 50 self.tests = ( 51 "test_check_wifi_state_after_au", 52 "test_verify_networks_after_au", 53 "test_configstore_after_au", 54 "test_mac_randomization_after_au", 55 "test_wifi_hotspot_5g_psk_after_au", 56 "test_all_networks_connectable_after_au", 57 "test_connect_to_network_suggestion_after_au", 58 "test_check_wifi_toggling_after_au", 59 "test_connection_to_new_networks", 60 "test_reset_wifi_after_au") 61 62 def setup_class(self): 63 super(WifiAutoUpdateTest, self).setup_class() 64 ota_updater.initialize(self.user_params, self.android_devices) 65 self.dut = self.android_devices[0] 66 self.dut_client = self.android_devices[1] 67 wutils.wifi_test_device_init(self.dut) 68 wutils.wifi_toggle_state(self.dut, True) 69 70 # configure APs 71 self.legacy_configure_ap_and_start(wpa_network=True) 72 self.wpapsk_2g = self.reference_networks[0]["2g"] 73 self.wpapsk_5g = self.reference_networks[0]["5g"] 74 self.open_2g = self.open_network[0]["2g"] 75 self.open_5g = self.open_network[0]["5g"] 76 77 # saved & connected networks, network suggestions 78 # and new networks 79 self.saved_networks = [self.open_2g] 80 self.network_suggestions = [self.wpapsk_5g] 81 self.connected_networks = [self.wpapsk_2g, self.open_5g] 82 self.new_networks = [self.reference_networks[1]["2g"], 83 self.open_network[1]["5g"]] 84 85 # add pre ota upgrade configuration 86 self.wifi_config_list = [] 87 self.pre_default_mac = {} 88 self.pre_random_mac = {} 89 self.pst_default_mac = {} 90 self.pst_random_mac = {} 91 self.add_pre_update_configuration() 92 93 # Run OTA below, if ota fails then abort all tests. 94 try: 95 ota_updater.update(self.dut) 96 except Exception as e: 97 raise signals.TestAbortClass( 98 "Failed up apply OTA update. Aborting tests: %s" % e) 99 100 def setup_test(self): 101 self.dut.droid.wakeLockAcquireBright() 102 self.dut.droid.wakeUpNow() 103 104 def teardown_test(self): 105 self.dut.droid.wakeLockRelease() 106 self.dut.droid.goToSleepNow() 107 108 def on_fail(self, test_name, begin_time): 109 self.dut.take_bug_report(test_name, begin_time) 110 self.dut.cat_adb_log(test_name, begin_time) 111 112 def teardown_class(self): 113 if "AccessPoint" in self.user_params: 114 del self.user_params["reference_networks"] 115 del self.user_params["open_network"] 116 117 ### Helper Methods 118 119 def add_pre_update_configuration(self): 120 self.add_network_suggestions(self.network_suggestions) 121 self.add_network_and_enable(self.saved_networks[0]) 122 self.add_wifi_hotspot() 123 self.connect_to_multiple_networks(self.connected_networks) 124 125 def add_wifi_hotspot(self): 126 self.wifi_hotspot = {"SSID": "hotspot_%s" % utils.rand_ascii_str(6), 127 "password": "pass_%s" % utils.rand_ascii_str(6)} 128 band = WIFI_CONFIG_APBAND_5G 129 if self.dut.build_info["build_id"].startswith("Q"): 130 band = WifiEnums.WIFI_CONFIG_APBAND_5G_OLD 131 self.wifi_hotspot[WifiEnums.AP_BAND_KEY] = band 132 asserts.assert_true( 133 self.dut.droid.wifiSetWifiApConfiguration(self.wifi_hotspot), 134 "Failed to set WifiAp Configuration") 135 wifi_ap = self.dut.droid.wifiGetApConfiguration() 136 asserts.assert_true( 137 wifi_ap[WifiEnums.SSID_KEY] == self.wifi_hotspot[WifiEnums.SSID_KEY], 138 "Hotspot SSID doesn't match with expected SSID") 139 return 140 wutils.save_wifi_soft_ap_config(self.dut, self.wifi_hotspot, band) 141 142 def verify_wifi_hotspot(self): 143 """Verify wifi tethering.""" 144 wutils.start_wifi_tethering_saved_config(self.dut) 145 wutils.connect_to_wifi_network(self.dut_client, 146 self.wifi_hotspot, 147 check_connectivity=False) 148 wutils.stop_wifi_tethering(self.dut) 149 150 def connect_to_multiple_networks(self, networks): 151 """Connect to a list of wifi networks. 152 153 Args: 154 networks : list of wifi networks. 155 """ 156 self.log.info("Connect to multiple wifi networks") 157 for network in networks: 158 ssid = network[SSID] 159 wutils.start_wifi_connection_scan_and_ensure_network_found( 160 self.dut, ssid) 161 wutils.wifi_connect(self.dut, network, num_of_tries=6) 162 self.wifi_config_list.append(network) 163 self.pre_default_mac[network[SSID]] = self.get_sta_mac_address() 164 self.pre_random_mac[network[SSID]] = \ 165 self.dut.droid.wifigetRandomizedMacAddress(network) 166 167 def get_sta_mac_address(self): 168 """Gets the current MAC address being used for client mode.""" 169 out = self.dut.adb.shell("ifconfig wlan0") 170 res = re.match(".* HWaddr (\S+).*", out, re.S) 171 return res.group(1) 172 173 def add_network_suggestions(self, network_suggestions): 174 """Add wifi network suggestions to DUT. 175 176 Args: 177 network_suggestions : suggestions to add. 178 """ 179 self.dut.log.info("Adding network suggestions") 180 asserts.assert_true( 181 self.dut.droid.wifiAddNetworkSuggestions(network_suggestions), 182 "Failed to add suggestions") 183 184 # Enable suggestions by the app. 185 self.dut.log.debug("Enabling suggestions from test") 186 self.dut.adb.shell( 187 "cmd wifi network-suggestions-set-user-approved %s yes" % \ 188 SL4A_APK_NAME) 189 190 def remove_suggestions_and_ensure_no_connection(self, 191 network_suggestions, 192 expected_ssid): 193 """Remove network suggestions. 194 195 Args: 196 network_suggestions : suggestions to remove. 197 expected_ssid : SSID to verify that DUT is not connected. 198 """ 199 # remove network suggestion and verify disconnect 200 self.dut.log.info("Removing network suggestions") 201 asserts.assert_true( 202 self.dut.droid.wifiRemoveNetworkSuggestions(network_suggestions), 203 "Failed to remove suggestions") 204 205 wutils.wait_for_disconnect(self.dut) 206 self.dut.ed.clear_all_events() 207 208 # Now ensure that we didn't connect back. 209 asserts.assert_false( 210 wutils.wait_for_connect(self.dut, 211 expected_ssid, 212 assert_on_fail=False), 213 "Device should not connect back") 214 215 def add_network_and_enable(self, network): 216 """Add a network and enable it. 217 218 Args: 219 network : Network details for the network to be added. 220 """ 221 self.log.info("Add a wifi network and enable it") 222 ret = self.dut.droid.wifiAddNetwork(network) 223 asserts.assert_true(ret != -1, "Add network %r failed" % network) 224 self.wifi_config_list.append({SSID: network[SSID], NETID: ret}) 225 self.dut.droid.wifiEnableNetwork(ret, 0) 226 227 def check_networks_after_autoupdate(self, networks): 228 """Verify that all previously configured networks are persistent. 229 230 Args: 231 networks: List of network dicts. 232 """ 233 network_info = self.dut.droid.wifiGetConfiguredNetworks() 234 if len(network_info) != len(networks): 235 msg = ( 236 "Number of configured networks before and after Auto-update " 237 "don't match. \nBefore reboot = %s \n After reboot = %s" % 238 (networks, network_info)) 239 raise signals.TestFailure(msg) 240 241 # For each network, check if it exists in configured list after Auto- 242 # update. 243 for network in networks: 244 exists = wutils.match_networks({SSID: network[SSID]}, network_info) 245 if not exists: 246 raise signals.TestFailure("%s network is not present in the" 247 " configured list after Auto-update" % 248 network[SSID]) 249 # Get the new network id for each network after reboot. 250 network[NETID] = exists[0]["networkId"] 251 252 def get_enabled_network(self, network1, network2): 253 """Check network status and return currently unconnected network. 254 255 Args: 256 network1: dict representing a network. 257 network2: dict representing a network. 258 259 Returns: 260 Network dict of the unconnected network. 261 """ 262 wifi_info = self.dut.droid.wifiGetConnectionInfo() 263 enabled = network1 264 if wifi_info[SSID] == network1[SSID]: 265 enabled = network2 266 return enabled 267 268 ### Tests 269 270 @test_tracker_info(uuid="9ff1f01e-e5ff-408b-9a95-29e87a2df2d8") 271 def test_check_wifi_state_after_au(self): 272 """Check if the state of WiFi is enabled after Auto-update.""" 273 if not self.dut.droid.wifiCheckState(): 274 raise signals.TestFailure("WiFi is disabled after Auto-update!!!") 275 276 @test_tracker_info(uuid="e3ebdbba-71dd-4281-aef8-5b3d42b88770") 277 def test_verify_networks_after_au(self): 278 """Check if the previously added networks are intact. 279 280 Steps: 281 Number of networs should be the same and match each network. 282 283 """ 284 self.check_networks_after_autoupdate(self.wifi_config_list) 285 286 @test_tracker_info(uuid="799e83c2-305d-4510-921e-dac3c0dbb6c5") 287 def test_configstore_after_au(self): 288 """Verify DUT automatically connects to wifi networks after ota. 289 290 Steps: 291 1. Connect to two wifi networks pre ota. 292 2. Verify DUT automatically connects to 1 after ota. 293 3. Re-connect to the other wifi network. 294 """ 295 wifi_info = self.dut.droid.wifiGetConnectionInfo() 296 self.pst_default_mac[wifi_info[SSID]] = self.get_sta_mac_address() 297 self.pst_random_mac[wifi_info[SSID]] = \ 298 self.dut.droid.wifigetRandomizedMacAddress(wifi_info) 299 reconnect_to = self.get_enabled_network(self.wifi_config_list[1], 300 self.wifi_config_list[2]) 301 wutils.start_wifi_connection_scan_and_ensure_network_found( 302 self.dut, reconnect_to[SSID]) 303 wutils.wifi_connect_by_id(self.dut, reconnect_to[NETID]) 304 connect_data = self.dut.droid.wifiGetConnectionInfo() 305 connect_ssid = connect_data[SSID] 306 self.log.info("Expected SSID = %s" % reconnect_to[SSID]) 307 self.log.info("Connected SSID = %s" % connect_ssid) 308 if connect_ssid != reconnect_to[SSID]: 309 raise signals.TestFailure( 310 "Device failed to reconnect to the correct" 311 " network after reboot.") 312 self.pst_default_mac[wifi_info[SSID]] = self.get_sta_mac_address() 313 self.pst_random_mac[wifi_info[SSID]] = \ 314 self.dut.droid.wifigetRandomizedMacAddress(wifi_info) 315 316 for network in self.connected_networks: 317 wutils.wifi_forget_network(self.dut, network[SSID]) 318 319 @test_tracker_info(uuid="e26d0ed9-9457-4a95-a962-4d43b0032bac") 320 def test_mac_randomization_after_au(self): 321 """Verify randomized MAC addrs are persistent after ota. 322 323 Steps: 324 1. Reconnect to the wifi networks configured pre ota. 325 2. Get the randomized MAC addrs. 326 """ 327 for ssid, mac in self.pst_random_mac.items(): 328 asserts.assert_true( 329 self.pre_random_mac[ssid] == mac, 330 "MAC addr of %s is %s after ota. Expected %s" % 331 (ssid, mac, self.pre_random_mac[ssid])) 332 333 @test_tracker_info(uuid="f68a65e6-97b7-4746-bad8-4c206551d87e") 334 def test_wifi_hotspot_5g_psk_after_au(self): 335 """Verify hotspot after ota upgrade. 336 337 Steps: 338 1. Start wifi hotspot on the saved config. 339 2. Verify DUT client connects to it. 340 """ 341 self.verify_wifi_hotspot() 342 343 @test_tracker_info(uuid="21f91372-88a6-44b9-a4e8-d4664823dffb") 344 def test_connect_to_network_suggestion_after_au(self): 345 """Verify connection to network suggestion after ota. 346 347 Steps: 348 1. DUT has network suggestion added before OTA. 349 2. Wait for the device to connect to it. 350 3. Remove the suggestions and ensure the device does not 351 connect back. 352 """ 353 wutils.start_wifi_connection_scan_and_return_status(self.dut) 354 wutils.wait_for_connect(self.dut, self.network_suggestions[0][SSID]) 355 self.remove_suggestions_and_ensure_no_connection( 356 self.network_suggestions, self.network_suggestions[0][SSID]) 357 358 @test_tracker_info(uuid="b8e47a4f-62fe-4a0e-b999-27ae1ebf4d19") 359 def test_connection_to_new_networks(self): 360 """Check if we can connect to new networks after Auto-update. 361 362 Steps: 363 1. Connect to a PSK network. 364 2. Connect to an open network. 365 3. Forget ntworks added in 1 & 2. 366 TODO: (@bmahadev) Add WEP network once it's ready. 367 """ 368 for network in self.new_networks: 369 wutils.connect_to_wifi_network(self.dut, network) 370 for network in self.new_networks: 371 wutils.wifi_forget_network(self.dut, network[SSID]) 372 373 @test_tracker_info(uuid="1d8309e4-d5a2-4f48-ba3b-895a58c9bf3a") 374 def test_all_networks_connectable_after_au(self): 375 """Check if previously added networks are connectable. 376 377 Steps: 378 1. Connect to previously added PSK network using network id. 379 2. Connect to previously added open network using network id. 380 TODO: (@bmahadev) Add WEP network once it's ready. 381 """ 382 network = self.wifi_config_list[0] 383 if not wutils.connect_to_wifi_network_with_id(self.dut, 384 network[NETID], 385 network[SSID]): 386 raise signals.TestFailure("Failed to connect to %s after OTA" % 387 network[SSID]) 388 wutils.wifi_forget_network(self.dut, network[SSID]) 389 390 @test_tracker_info(uuid="05671859-38b1-4dbf-930c-18048971d075") 391 def test_check_wifi_toggling_after_au(self): 392 """Check if WiFi can be toggled ON/OFF after auto-update.""" 393 self.log.debug("Going from on to off.") 394 wutils.wifi_toggle_state(self.dut, False) 395 self.log.debug("Going from off to on.") 396 wutils.wifi_toggle_state(self.dut, True) 397 398 @test_tracker_info(uuid="440edf32-4b00-42b0-9811-9f2bc4a83efb") 399 def test_reset_wifi_after_au(self): 400 """"Check if WiFi can be reset after auto-update.""" 401 wutils.reset_wifi(self.dut) 402