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