| # !/usr/bin/env python3.4 |
| # |
| # Copyright 2017 - The Android Open Source Project |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| |
| import re |
| from acts import asserts |
| from acts.controllers.android_device import SL4A_APK_NAME |
| from acts.libs.ota import ota_updater |
| import acts.signals as signals |
| from acts.test_decorators import test_tracker_info |
| from acts_contrib.test_utils.tel.tel_wifi_utils import WIFI_CONFIG_APBAND_5G |
| import acts_contrib.test_utils.wifi.wifi_test_utils as wutils |
| from acts_contrib.test_utils.wifi.WifiBaseTest import WifiBaseTest |
| import acts.utils as utils |
| |
| WifiEnums = wutils.WifiEnums |
| SSID = WifiEnums.SSID_KEY |
| PWD = WifiEnums.PWD_KEY |
| NETID = WifiEnums.NETID_KEY |
| # Default timeout used for reboot, toggle WiFi and Airplane mode, |
| # for the system to settle down after the operation. |
| DEFAULT_TIMEOUT = 10 |
| BAND_2GHZ = 0 |
| BAND_5GHZ = 1 |
| |
| |
| class WifiAutoUpdateTest(WifiBaseTest): |
| """Tests for APIs in Android's WifiManager class. |
| |
| Test Bed Requirement: |
| * One Android device |
| * Several Wi-Fi networks visible to the device, including an open Wi-Fi |
| network. |
| """ |
| |
| def __init__(self, controllers): |
| WifiBaseTest.__init__(self, controllers) |
| self.tests = ( |
| "test_check_wifi_state_after_au", |
| "test_verify_networks_after_au", |
| "test_configstore_after_au", |
| "test_mac_randomization_after_au", |
| "test_wifi_hotspot_5g_psk_after_au", |
| "test_all_networks_connectable_after_au", |
| "test_connect_to_network_suggestion_after_au", |
| "test_check_wifi_toggling_after_au", |
| "test_connection_to_new_networks", |
| "test_reset_wifi_after_au") |
| |
| def setup_class(self): |
| super(WifiAutoUpdateTest, self).setup_class() |
| ota_updater.initialize(self.user_params, self.android_devices) |
| self.dut = self.android_devices[0] |
| self.dut_client = self.android_devices[1] |
| wutils.wifi_test_device_init(self.dut) |
| wutils.wifi_toggle_state(self.dut, True) |
| |
| # configure APs |
| opt_param = ["reference_networks"] |
| self.unpack_userparams(opt_param_names=opt_param) |
| if "AccessPoint" in self.user_params: |
| self.legacy_configure_ap_and_start(wpa_network=True, |
| wep_network=True) |
| elif "OpenWrtAP" in self.user_params: |
| self.configure_openwrt_ap_and_start(wpa_network=True, |
| wep_network=True, |
| ap_count=2) |
| self.wpapsk_2g = self.reference_networks[0]["2g"] |
| self.wpapsk_5g = self.reference_networks[0]["5g"] |
| self.wep_2g = self.wep_networks[0]["2g"] |
| self.wep_5g = self.wep_networks[0]["5g"] |
| |
| # saved & connected networks, network suggestions |
| # and new networks |
| self.saved_networks = [self.wep_2g] |
| self.network_suggestions = [self.wpapsk_5g] |
| self.connected_networks = [self.wpapsk_2g, self.wep_5g] |
| self.new_networks = [self.reference_networks[1]["2g"], |
| self.wep_networks[1]["5g"]] |
| |
| # add pre ota upgrade configuration |
| self.wifi_config_list = [] |
| self.pre_default_mac = {} |
| self.pre_random_mac = {} |
| self.pst_default_mac = {} |
| self.pst_random_mac = {} |
| self.add_pre_update_configuration() |
| |
| # Run OTA below, if ota fails then abort all tests. |
| try: |
| ota_updater.update(self.dut) |
| except Exception as e: |
| raise signals.TestAbortClass( |
| "Failed up apply OTA update. Aborting tests: %s" % e) |
| |
| def setup_test(self): |
| super().setup_test() |
| self.dut.droid.wakeLockAcquireBright() |
| self.dut.droid.wakeUpNow() |
| |
| def teardown_test(self): |
| super().teardown_test() |
| self.dut.droid.wakeLockRelease() |
| self.dut.droid.goToSleepNow() |
| |
| def teardown_class(self): |
| if "AccessPoint" in self.user_params: |
| del self.user_params["reference_networks"] |
| |
| ### Helper Methods |
| |
| def add_pre_update_configuration(self): |
| self.add_network_suggestions(self.network_suggestions) |
| self.add_network_and_enable(self.saved_networks[0]) |
| self.add_wifi_hotspot() |
| self.connect_to_multiple_networks(self.connected_networks) |
| |
| def add_wifi_hotspot(self): |
| self.wifi_hotspot = {"SSID": "hotspot_%s" % utils.rand_ascii_str(6), |
| "password": "pass_%s" % utils.rand_ascii_str(6)} |
| band = WIFI_CONFIG_APBAND_5G |
| if self.dut.build_info["build_id"].startswith("R"): |
| band = WifiEnums.WIFI_CONFIG_SOFTAP_BAND_5G |
| self.wifi_hotspot[WifiEnums.AP_BAND_KEY] = band |
| asserts.assert_true( |
| self.dut.droid.wifiSetWifiApConfiguration(self.wifi_hotspot), |
| "Failed to set WifiAp Configuration") |
| wifi_ap = self.dut.droid.wifiGetApConfiguration() |
| asserts.assert_true( |
| wifi_ap[WifiEnums.SSID_KEY] == self.wifi_hotspot[WifiEnums.SSID_KEY], |
| "Hotspot SSID doesn't match with expected SSID") |
| return |
| if self.dut.build_info["build_id"].startswith("Q"): |
| band = WifiEnums.WIFI_CONFIG_APBAND_5G_OLD |
| self.wifi_hotspot[WifiEnums.AP_BAND_KEY] = band |
| asserts.assert_true( |
| self.dut.droid.wifiSetWifiApConfiguration(self.wifi_hotspot), |
| "Failed to set WifiAp Configuration") |
| wifi_ap = self.dut.droid.wifiGetApConfiguration() |
| asserts.assert_true( |
| wifi_ap[WifiEnums.SSID_KEY] == self.wifi_hotspot[WifiEnums.SSID_KEY], |
| "Hotspot SSID doesn't match with expected SSID") |
| return |
| wutils.save_wifi_soft_ap_config(self.dut, self.wifi_hotspot, band) |
| |
| def verify_wifi_hotspot(self): |
| """Verify wifi tethering.""" |
| wutils.start_wifi_tethering_saved_config(self.dut) |
| wutils.connect_to_wifi_network(self.dut_client, |
| self.wifi_hotspot, |
| check_connectivity=False) |
| wutils.stop_wifi_tethering(self.dut) |
| |
| def connect_to_multiple_networks(self, networks): |
| """Connect to a list of wifi networks. |
| |
| Args: |
| networks : list of wifi networks. |
| """ |
| self.log.info("Connect to multiple wifi networks") |
| for network in networks: |
| ssid = network[SSID] |
| wutils.start_wifi_connection_scan_and_ensure_network_found( |
| self.dut, ssid) |
| wutils.wifi_connect(self.dut, network, num_of_tries=6) |
| self.wifi_config_list.append(network) |
| self.pre_default_mac[network[SSID]] = self.get_sta_mac_address() |
| self.pre_random_mac[network[SSID]] = \ |
| self.dut.droid.wifigetRandomizedMacAddress(network) |
| |
| def get_sta_mac_address(self): |
| """Gets the current MAC address being used for client mode.""" |
| out = self.dut.adb.shell("ifconfig wlan0") |
| res = re.match(".* HWaddr (\S+).*", out, re.S) |
| return res.group(1) |
| |
| def add_network_suggestions(self, network_suggestions): |
| """Add wifi network suggestions to DUT. |
| |
| Args: |
| network_suggestions : suggestions to add. |
| """ |
| self.dut.log.info("Adding network suggestions") |
| asserts.assert_true( |
| self.dut.droid.wifiAddNetworkSuggestions(network_suggestions), |
| "Failed to add suggestions") |
| |
| # Enable suggestions by the app. |
| self.dut.log.debug("Enabling suggestions from test") |
| self.dut.adb.shell( |
| "cmd wifi network-suggestions-set-user-approved %s yes" % \ |
| SL4A_APK_NAME) |
| |
| def remove_suggestions_and_ensure_no_connection(self, |
| network_suggestions, |
| expected_ssid): |
| """Remove network suggestions. |
| |
| Args: |
| network_suggestions : suggestions to remove. |
| expected_ssid : SSID to verify that DUT is not connected. |
| """ |
| # remove network suggestion and verify disconnect |
| self.dut.log.info("Removing network suggestions") |
| asserts.assert_true( |
| self.dut.droid.wifiRemoveNetworkSuggestions(network_suggestions), |
| "Failed to remove suggestions") |
| |
| wutils.wait_for_disconnect(self.dut) |
| self.dut.ed.clear_all_events() |
| |
| # Now ensure that we didn't connect back. |
| asserts.assert_false( |
| wutils.wait_for_connect(self.dut, |
| expected_ssid, |
| assert_on_fail=False), |
| "Device should not connect back") |
| |
| def add_network_and_enable(self, network): |
| """Add a network and enable it. |
| |
| Args: |
| network : Network details for the network to be added. |
| """ |
| self.log.info("Add a wifi network and enable it") |
| ret = self.dut.droid.wifiAddNetwork(network) |
| asserts.assert_true(ret != -1, "Add network %r failed" % network) |
| self.wifi_config_list.append({SSID: network[SSID], NETID: ret}) |
| self.dut.droid.wifiEnableNetwork(ret, 0) |
| |
| def check_networks_after_autoupdate(self, networks): |
| """Verify that all previously configured networks are persistent. |
| |
| Args: |
| networks: List of network dicts. |
| """ |
| network_info = self.dut.droid.wifiGetConfiguredNetworks() |
| """ |
| b/189285598, the network id of a network might be changed after \ |
| reboot because the network sequence is not stable on \ |
| backup/restore. This test should find the correct network against |
| the desired SSID before connecting to the network after reboot. |
| Start from Android S. |
| """ |
| network_info_ssid = list() |
| for i in network_info: |
| network_info_ssid.append(i['SSID']) |
| network_info_ssid_list = set(network_info_ssid) |
| networks_ssid= list() |
| for i in networks: |
| networks_ssid.append(i['SSID']) |
| networks_ssid_list = set(networks_ssid) |
| if len(network_info_ssid_list) != len(networks_ssid_list): |
| msg = ( |
| "Number of configured networks before and after Auto-update " |
| "don't match. \nBefore reboot = %s \n After reboot = %s" % |
| (networks, network_info)) |
| raise signals.TestFailure(msg) |
| |
| # For each network, check if it exists in configured list after Auto- |
| # update. |
| for network in networks: |
| exists = wutils.match_networks({SSID: network[SSID]}, network_info) |
| if not exists: |
| raise signals.TestFailure("%s network is not present in the" |
| " configured list after Auto-update" % |
| network[SSID]) |
| |
| # Get the new network id for each network after reboot. |
| network[NETID] = exists[0]["networkId"] |
| |
| def get_enabled_network(self, network1, network2): |
| """Check network status and return currently unconnected network. |
| |
| Args: |
| network1: dict representing a network. |
| network2: dict representing a network. |
| |
| Returns: |
| Network dict of the unconnected network. |
| """ |
| wifi_info = self.dut.droid.wifiGetConnectionInfo() |
| enabled = network1 |
| if wifi_info[SSID] == network1[SSID]: |
| enabled = network2 |
| return enabled |
| |
| ### Tests |
| |
| @test_tracker_info(uuid="9ff1f01e-e5ff-408b-9a95-29e87a2df2d8") |
| @WifiBaseTest.wifi_test_wrap |
| def test_check_wifi_state_after_au(self): |
| """Check if the state of WiFi is enabled after Auto-update.""" |
| if not self.dut.droid.wifiCheckState(): |
| raise signals.TestFailure("WiFi is disabled after Auto-update!!!") |
| |
| @test_tracker_info(uuid="e3ebdbba-71dd-4281-aef8-5b3d42b88770") |
| @WifiBaseTest.wifi_test_wrap |
| def test_verify_networks_after_au(self): |
| """Check if the previously added networks are intact. |
| |
| Steps: |
| Number of networs should be the same and match each network. |
| |
| """ |
| self.check_networks_after_autoupdate(self.wifi_config_list) |
| |
| @test_tracker_info(uuid="799e83c2-305d-4510-921e-dac3c0dbb6c5") |
| @WifiBaseTest.wifi_test_wrap |
| def test_configstore_after_au(self): |
| """Verify DUT automatically connects to wifi networks after ota. |
| |
| Steps: |
| 1. Connect to two wifi networks pre ota. |
| 2. Verify DUT automatically connects to 1 after ota. |
| 3. Re-connect to the other wifi network. |
| """ |
| wifi_info = self.dut.droid.wifiGetConnectionInfo() |
| self.pst_default_mac[wifi_info[SSID]] = self.get_sta_mac_address() |
| self.pst_random_mac[wifi_info[SSID]] = \ |
| self.dut.droid.wifigetRandomizedMacAddress(wifi_info) |
| reconnect_to = self.get_enabled_network(self.wifi_config_list[1], |
| self.wifi_config_list[2]) |
| wutils.start_wifi_connection_scan_and_ensure_network_found( |
| self.dut, reconnect_to[SSID]) |
| wutils.wifi_connect_by_id(self.dut, reconnect_to[NETID]) |
| connect_data = self.dut.droid.wifiGetConnectionInfo() |
| connect_ssid = connect_data[SSID] |
| self.log.info("Expected SSID = %s" % reconnect_to[SSID]) |
| self.log.info("Connected SSID = %s" % connect_ssid) |
| if connect_ssid != reconnect_to[SSID]: |
| raise signals.TestFailure( |
| "Device failed to reconnect to the correct" |
| " network after reboot.") |
| self.pst_default_mac[wifi_info[SSID]] = self.get_sta_mac_address() |
| self.pst_random_mac[wifi_info[SSID]] = \ |
| self.dut.droid.wifigetRandomizedMacAddress(wifi_info) |
| |
| for network in self.connected_networks: |
| wutils.wifi_forget_network(self.dut, network[SSID]) |
| |
| @test_tracker_info(uuid="e26d0ed9-9457-4a95-a962-4d43b0032bac") |
| @WifiBaseTest.wifi_test_wrap |
| def test_mac_randomization_after_au(self): |
| """Verify randomized MAC addrs are persistent after ota. |
| |
| Steps: |
| 1. Reconnect to the wifi networks configured pre ota. |
| 2. Get the randomized MAC addrs. |
| """ |
| for ssid, mac in self.pst_random_mac.items(): |
| asserts.assert_true( |
| self.pre_random_mac[ssid] == mac, |
| "MAC addr of %s is %s after ota. Expected %s" % |
| (ssid, mac, self.pre_random_mac[ssid])) |
| |
| @test_tracker_info(uuid="f68a65e6-97b7-4746-bad8-4c206551d87e") |
| @WifiBaseTest.wifi_test_wrap |
| def test_wifi_hotspot_5g_psk_after_au(self): |
| """Verify hotspot after ota upgrade. |
| |
| Steps: |
| 1. Start wifi hotspot on the saved config. |
| 2. Verify DUT client connects to it. |
| """ |
| self.verify_wifi_hotspot() |
| |
| @test_tracker_info(uuid="21f91372-88a6-44b9-a4e8-d4664823dffb") |
| @WifiBaseTest.wifi_test_wrap |
| def test_connect_to_network_suggestion_after_au(self): |
| """Verify connection to network suggestion after ota. |
| |
| Steps: |
| 1. DUT has network suggestion added before OTA. |
| 2. Wait for the device to connect to it. |
| 3. Remove the suggestions and ensure the device does not |
| connect back. |
| """ |
| wutils.reset_wifi(self.dut) |
| wutils.start_wifi_connection_scan_and_return_status(self.dut) |
| wutils.wait_for_connect(self.dut, self.network_suggestions[0][SSID]) |
| self.remove_suggestions_and_ensure_no_connection( |
| self.network_suggestions, self.network_suggestions[0][SSID]) |
| |
| @test_tracker_info(uuid="b8e47a4f-62fe-4a0e-b999-27ae1ebf4d19") |
| @WifiBaseTest.wifi_test_wrap |
| def test_connection_to_new_networks(self): |
| """Check if we can connect to new networks after Auto-update. |
| |
| Steps: |
| 1. Connect to a PSK network. |
| 2. Connect to an open network. |
| 3. Forget ntworks added in 1 & 2. |
| TODO: (@bmahadev) Add WEP network once it's ready. |
| """ |
| for network in self.new_networks: |
| wutils.connect_to_wifi_network(self.dut, network) |
| for network in self.new_networks: |
| wutils.wifi_forget_network(self.dut, network[SSID]) |
| |
| @test_tracker_info(uuid="1d8309e4-d5a2-4f48-ba3b-895a58c9bf3a") |
| @WifiBaseTest.wifi_test_wrap |
| def test_all_networks_connectable_after_au(self): |
| """Check if previously added networks are connectable. |
| |
| Steps: |
| 1. Connect to previously added PSK network using network id. |
| 2. Connect to previously added open network using network id. |
| TODO: (@bmahadev) Add WEP network once it's ready. |
| """ |
| network = self.wifi_config_list[0] |
| if not wutils.connect_to_wifi_network_with_id(self.dut, |
| network[NETID], |
| network[SSID]): |
| raise signals.TestFailure("Failed to connect to %s after OTA" % |
| network[SSID]) |
| wutils.wifi_forget_network(self.dut, network[SSID]) |
| |
| @test_tracker_info(uuid="05671859-38b1-4dbf-930c-18048971d075") |
| @WifiBaseTest.wifi_test_wrap |
| def test_check_wifi_toggling_after_au(self): |
| """Check if WiFi can be toggled ON/OFF after auto-update.""" |
| self.log.debug("Going from on to off.") |
| wutils.wifi_toggle_state(self.dut, False) |
| self.log.debug("Going from off to on.") |
| wutils.wifi_toggle_state(self.dut, True) |
| |
| @test_tracker_info(uuid="440edf32-4b00-42b0-9811-9f2bc4a83efb") |
| @WifiBaseTest.wifi_test_wrap |
| def test_reset_wifi_after_au(self): |
| """"Check if WiFi can be reset after auto-update.""" |
| wutils.reset_wifi(self.dut) |