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 itertools
18import pprint
19import queue
20import time
21
22import acts.base_test
23import acts.signals as signals
24import acts.test_utils.wifi.wifi_test_utils as wutils
25import acts.utils
26
27from acts import asserts
28from acts.test_decorators import test_tracker_info
29from acts.test_utils.bt.bt_test_utils import enable_bluetooth
30from acts.test_utils.bt.bt_test_utils import disable_bluetooth
31from acts.test_utils.wifi.WifiBaseTest import WifiBaseTest
32
33WifiEnums = wutils.WifiEnums
34# Default timeout used for reboot, toggle WiFi and Airplane mode,
35# for the system to settle down after the operation.
36DEFAULT_TIMEOUT = 10
37BAND_2GHZ = 0
38BAND_5GHZ = 1
39
40
41class WifiManagerTest(WifiBaseTest):
42    """Tests for APIs in Android's WifiManager class.
43
44    Test Bed Requirement:
45    * Two Android device
46    * Several Wi-Fi networks visible to the device, including an open Wi-Fi
47      network.
48    """
49
50    def setup_class(self):
51        super().setup_class()
52
53        self.dut = self.android_devices[0]
54        wutils.wifi_test_device_init(self.dut)
55        wutils.wifi_toggle_state(self.dut, True)
56
57        self.dut_client = None
58        if len(self.android_devices) > 1:
59            self.dut_client = self.android_devices[1]
60            wutils.wifi_test_device_init(self.dut_client)
61            wutils.wifi_toggle_state(self.dut_client, True)
62
63        req_params = []
64        opt_param = [
65            "open_network", "reference_networks", "iperf_server_address",
66            "wpa_networks", "wep_networks", "iperf_server_port"
67        ]
68        self.unpack_userparams(
69            req_param_names=req_params, opt_param_names=opt_param)
70
71        if "AccessPoint" in self.user_params:
72            self.legacy_configure_ap_and_start(wpa_network=True, wep_network=True)
73
74        asserts.assert_true(
75            len(self.reference_networks) > 0,
76            "Need at least one reference network with psk.")
77        self.wpapsk_2g = self.reference_networks[0]["2g"]
78        self.wpapsk_5g = self.reference_networks[0]["5g"]
79        self.open_network_2g = self.open_network[0]["2g"]
80        self.open_network_5g = self.open_network[0]["5g"]
81
82    def setup_test(self):
83        for ad in self.android_devices:
84            ad.droid.wakeLockAcquireBright()
85            ad.droid.wakeUpNow()
86        wutils.wifi_toggle_state(self.dut, True)
87
88    def teardown_test(self):
89        for ad in self.android_devices:
90            ad.droid.wakeLockRelease()
91            ad.droid.goToSleepNow()
92        self.turn_location_off_and_scan_toggle_off()
93        wutils.reset_wifi(self.dut)
94        if self.dut_client:
95            wutils.reset_wifi(self.dut_client)
96
97    def on_fail(self, test_name, begin_time):
98        self.dut.take_bug_report(test_name, begin_time)
99        self.dut.cat_adb_log(test_name, begin_time)
100
101    def teardown_class(self):
102        if "AccessPoint" in self.user_params:
103            del self.user_params["reference_networks"]
104            del self.user_params["open_network"]
105
106    """Helper Functions"""
107
108    def connect_to_wifi_network(self, params):
109        """Connection logic for open and psk wifi networks.
110
111        Args:
112            params: A tuple of network info and AndroidDevice object.
113        """
114        network, ad = params
115        droid = ad.droid
116        ed = ad.ed
117        SSID = network[WifiEnums.SSID_KEY]
118        wutils.start_wifi_connection_scan_and_ensure_network_found(
119            ad, SSID);
120        wutils.wifi_connect(ad, network, num_of_tries=3)
121
122    def get_connection_data(self, dut, network):
123        """Get network id and ssid info from connection data.
124
125        Args:
126            dut: The Android device object under test.
127            network: dict representing the network to connect to.
128
129        Returns:
130            A convenience dict with the connected network's ID and SSID.
131
132        """
133        params = (network, dut)
134        self.connect_to_wifi_network(params)
135        connect_data = dut.droid.wifiGetConnectionInfo()
136        ssid_id_dict = dict()
137        ssid_id_dict[WifiEnums.NETID_KEY] = connect_data[WifiEnums.NETID_KEY]
138        ssid_id_dict[WifiEnums.SSID_KEY] = connect_data[WifiEnums.SSID_KEY]
139        return ssid_id_dict
140
141    def connect_multiple_networks(self, dut):
142        """Connect to one 2.4GHz and one 5Ghz network.
143
144        Args:
145            dut: The Android device object under test.
146
147        Returns:
148            A list with the connection details for the 2GHz and 5GHz networks.
149
150        """
151        network_list = list()
152        connect_2g_data = self.get_connection_data(dut, self.wpapsk_2g)
153        network_list.append(connect_2g_data)
154        connect_5g_data = self.get_connection_data(dut, self.wpapsk_5g)
155        network_list.append(connect_5g_data)
156        return network_list
157
158    def get_enabled_network(self, network1, network2):
159        """Check network status and return currently unconnected network.
160
161        Args:
162            network1: dict representing a network.
163            network2: dict representing a network.
164
165        Return:
166            Network dict of the unconnected network.
167
168        """
169        wifi_info = self.dut.droid.wifiGetConnectionInfo()
170        enabled = network1
171        if wifi_info[WifiEnums.SSID_KEY] == network1[WifiEnums.SSID_KEY]:
172            enabled = network2
173        return enabled
174
175    def check_configstore_networks(self, networks):
176        """Verify that all previously configured networks are presistent after
177           reboot.
178
179        Args:
180            networks: List of network dicts.
181
182        Return:
183            None. Raises TestFailure.
184
185        """
186        network_info = self.dut.droid.wifiGetConfiguredNetworks()
187        if len(network_info) != len(networks):
188            msg = (
189                "Length of configured networks before and after reboot don't"
190                " match. \nBefore reboot = %s \n After reboot = %s" %
191                (networks, network_info))
192            raise signals.TestFailure(msg)
193        current_count = 0
194        # For each network, check if it exists in configured list after reboot
195        for network in networks:
196            exists = wutils.match_networks({
197                WifiEnums.SSID_KEY: network[WifiEnums.SSID_KEY]
198            }, network_info)
199            if not len(exists):
200                raise signals.TestFailure("%s network is not present in the"
201                                          " configured list after reboot" %
202                                          network[WifiEnums.SSID_KEY])
203            # Get the new network id for each network after reboot.
204            network[WifiEnums.NETID_KEY] = exists[0]['networkId']
205            if exists[0]['status'] == 'CURRENT':
206                current_count += 1
207                # At any given point, there can only be one currently active
208                # network, defined with 'status':'CURRENT'
209                if current_count > 1:
210                    raise signals.TestFailure("More than one network showing"
211                                              "as 'CURRENT' after reboot")
212
213    def connect_to_wifi_network_with_id(self, network_id, network_ssid):
214        """Connect to the given network using network id and verify SSID.
215
216        Args:
217            network_id: int Network Id of the network.
218            network_ssid: string SSID of the network.
219
220        Returns: True if connect using network id was successful;
221                 False otherwise.
222
223        """
224        wutils.start_wifi_connection_scan_and_ensure_network_found(
225            self.dut, network_ssid);
226        wutils.wifi_connect_by_id(self.dut, network_id)
227        connect_data = self.dut.droid.wifiGetConnectionInfo()
228        connect_ssid = connect_data[WifiEnums.SSID_KEY]
229        self.log.debug("Expected SSID = %s Connected SSID = %s" %
230                       (network_ssid, connect_ssid))
231        if connect_ssid != network_ssid:
232            return False
233        return True
234
235    def run_iperf_client(self, params):
236        """Run iperf traffic after connection.
237
238        Args:
239            params: A tuple of network info and AndroidDevice object.
240        """
241        if "iperf_server_address" in self.user_params:
242            wait_time = 5
243            network, ad = params
244            SSID = network[WifiEnums.SSID_KEY]
245            self.log.info("Starting iperf traffic through {}".format(SSID))
246            time.sleep(wait_time)
247            port_arg = "-p {}".format(self.iperf_server_port)
248            success, data = ad.run_iperf_client(self.iperf_server_address,
249                                                port_arg)
250            self.log.debug(pprint.pformat(data))
251            asserts.assert_true(success, "Error occurred in iPerf traffic.")
252
253    def connect_to_wifi_network_toggle_wifi_and_run_iperf(self, params):
254        """ Connect to the provided network and then toggle wifi mode and wait
255        for reconnection to the provided network.
256
257        Logic steps are
258        1. Connect to the network.
259        2. Turn wifi off.
260        3. Turn wifi on.
261        4. Wait for connection to the network.
262        5. Run iperf traffic.
263
264        Args:
265            params: A tuple of network info and AndroidDevice object.
266       """
267        network, ad = params
268        self.connect_to_wifi_network(params)
269        wutils.toggle_wifi_and_wait_for_reconnection(
270            ad, network, num_of_tries=5)
271        self.run_iperf_client(params)
272
273    def run_iperf(self, iperf_args):
274        if "iperf_server_address" not in self.user_params:
275            self.log.error(("Missing iperf_server_address. "
276                            "Provide one in config."))
277        else:
278            iperf_addr = self.user_params["iperf_server_address"]
279            self.log.info("Running iperf client.")
280            result, data = self.dut.run_iperf_client(iperf_addr, iperf_args)
281            self.log.debug(data)
282
283    def run_iperf_rx_tx(self, time, omit=10):
284        args = "-p {} -t {} -O 10".format(self.iperf_server_port, time, omit)
285        self.log.info("Running iperf client {}".format(args))
286        self.run_iperf(args)
287        args = "-p {} -t {} -O 10 -R".format(self.iperf_server_port, time,
288                                             omit)
289        self.log.info("Running iperf client {}".format(args))
290        self.run_iperf(args)
291
292    def get_energy_info(self):
293        """ Steps:
294            1. Check that the WiFi energy info reporting support on this device
295               is as expected (support or not).
296            2. If the device does not support energy info reporting as
297               expected, skip the test.
298            3. Call API to get WiFi energy info.
299            4. Verify the values of "ControllerEnergyUsed" and
300               "ControllerIdleTimeMillis" in energy info don't decrease.
301            5. Repeat from Step 3 for 10 times.
302        """
303        # Check if dut supports energy info reporting.
304        actual_support = self.dut.droid.wifiIsEnhancedPowerReportingSupported()
305        model = self.dut.model
306        if not actual_support:
307            asserts.skip(
308                ("Device %s does not support energy info reporting as "
309                 "expected.") % model)
310        # Verify reported values don't decrease.
311        self.log.info(("Device %s supports energy info reporting, verify that "
312                       "the reported values don't decrease.") % model)
313        energy = 0
314        idle_time = 0
315        for i in range(10):
316            info = self.dut.droid.wifiGetControllerActivityEnergyInfo()
317            self.log.debug("Iteration %d, got energy info: %s" % (i, info))
318            new_energy = info["ControllerEnergyUsed"]
319            new_idle_time = info["ControllerIdleTimeMillis"]
320            asserts.assert_true(new_energy >= energy,
321                                "Energy value decreased: previous %d, now %d" %
322                                (energy, new_energy))
323            energy = new_energy
324            asserts.assert_true(new_idle_time >= idle_time,
325                                "Idle time decreased: previous %d, now %d" % (
326                                    idle_time, new_idle_time))
327            idle_time = new_idle_time
328            wutils.start_wifi_connection_scan(self.dut)
329
330    def turn_location_on_and_scan_toggle_on(self):
331        """ Turns on wifi location scans.
332        """
333        acts.utils.set_location_service(self.dut, True)
334        self.dut.droid.wifiScannerToggleAlwaysAvailable(True)
335        msg = "Failed to turn on location service's scan."
336        asserts.assert_true(self.dut.droid.wifiScannerIsAlwaysAvailable(), msg)
337
338    def turn_location_off_and_scan_toggle_off(self):
339        """ Turns off wifi location scans.
340        """
341        acts.utils.set_location_service(self.dut, False)
342        self.dut.droid.wifiScannerToggleAlwaysAvailable(False)
343        msg = "Failed to turn off location service's scan."
344        asserts.assert_true(not self.dut.droid.wifiScannerIsAlwaysAvailable(), msg)
345
346    def turn_location_on_and_scan_toggle_off(self):
347        """ Turns off wifi location scans, but keeps location on.
348        """
349        acts.utils.set_location_service(self.dut, True)
350        self.dut.droid.wifiScannerToggleAlwaysAvailable(False)
351        msg = "Failed to turn off location service's scan."
352        asserts.assert_true(not self.dut.droid.wifiScannerIsAlwaysAvailable(), msg)
353
354    def helper_reconnect_toggle_wifi(self):
355        """Connect to multiple networks, turn off/on wifi, then reconnect to
356           a previously connected network.
357
358        Steps:
359        1. Connect to a 2GHz network.
360        2. Connect to a 5GHz network.
361        3. Turn WiFi OFF/ON.
362        4. Reconnect to the non-current network.
363
364        """
365        connect_2g_data = self.get_connection_data(self.dut, self.wpapsk_2g)
366        connect_5g_data = self.get_connection_data(self.dut, self.wpapsk_5g)
367        wutils.toggle_wifi_off_and_on(self.dut)
368        reconnect_to = self.get_enabled_network(connect_2g_data,
369                                                connect_5g_data)
370        reconnect = self.connect_to_wifi_network_with_id(
371            reconnect_to[WifiEnums.NETID_KEY],
372            reconnect_to[WifiEnums.SSID_KEY])
373        if not reconnect:
374            raise signals.TestFailure("Device did not connect to the correct"
375                                      " network after toggling WiFi.")
376
377    def helper_reconnect_toggle_airplane(self):
378        """Connect to multiple networks, turn on/off Airplane moce, then
379           reconnect a previously connected network.
380
381        Steps:
382        1. Connect to a 2GHz network.
383        2. Connect to a 5GHz network.
384        3. Turn ON/OFF Airplane mode.
385        4. Reconnect to the non-current network.
386
387        """
388        connect_2g_data = self.get_connection_data(self.dut, self.wpapsk_2g)
389        connect_5g_data = self.get_connection_data(self.dut, self.wpapsk_5g)
390        wutils.toggle_airplane_mode_on_and_off(self.dut)
391        reconnect_to = self.get_enabled_network(connect_2g_data,
392                                                connect_5g_data)
393        reconnect = self.connect_to_wifi_network_with_id(
394            reconnect_to[WifiEnums.NETID_KEY],
395            reconnect_to[WifiEnums.SSID_KEY])
396        if not reconnect:
397            raise signals.TestFailure("Device did not connect to the correct"
398                                      " network after toggling Airplane mode.")
399
400    def helper_reboot_configstore_reconnect(self):
401        """Connect to multiple networks, reboot then reconnect to previously
402           connected network.
403
404        Steps:
405        1. Connect to a 2GHz network.
406        2. Connect to a 5GHz network.
407        3. Reboot device.
408        4. Verify all networks are persistent after reboot.
409        5. Reconnect to the non-current network.
410
411        """
412        network_list = self.connect_multiple_networks(self.dut)
413        self.dut.reboot()
414        time.sleep(DEFAULT_TIMEOUT)
415        self.check_configstore_networks(network_list)
416
417        reconnect_to = self.get_enabled_network(network_list[BAND_2GHZ],
418                                                network_list[BAND_5GHZ])
419
420        reconnect = self.connect_to_wifi_network_with_id(
421            reconnect_to[WifiEnums.NETID_KEY],
422            reconnect_to[WifiEnums.SSID_KEY])
423        if not reconnect:
424            raise signals.TestFailure(
425                "Device failed to reconnect to the correct"
426                " network after reboot.")
427
428    def helper_toggle_wifi_reboot_configstore_reconnect(self):
429        """Connect to multiple networks, disable WiFi, reboot, then
430           reconnect to previously connected network.
431
432        Steps:
433        1. Connect to a 2GHz network.
434        2. Connect to a 5GHz network.
435        3. Turn WiFi OFF.
436        4. Reboot device.
437        5. Turn WiFi ON.
438        4. Verify all networks are persistent after reboot.
439        5. Reconnect to the non-current network.
440
441        """
442        network_list = self.connect_multiple_networks(self.dut)
443        self.log.debug("Toggling wifi OFF")
444        wutils.wifi_toggle_state(self.dut, False)
445        time.sleep(DEFAULT_TIMEOUT)
446        self.dut.reboot()
447        time.sleep(DEFAULT_TIMEOUT)
448        self.log.debug("Toggling wifi ON")
449        wutils.wifi_toggle_state(self.dut, True)
450        time.sleep(DEFAULT_TIMEOUT)
451        self.check_configstore_networks(network_list)
452        reconnect_to = self.get_enabled_network(network_list[BAND_2GHZ],
453                                                network_list[BAND_5GHZ])
454        reconnect = self.connect_to_wifi_network_with_id(
455            reconnect_to[WifiEnums.NETID_KEY],
456            reconnect_to[WifiEnums.SSID_KEY])
457        if not reconnect:
458            msg = ("Device failed to reconnect to the correct network after"
459                   " toggling WiFi and rebooting.")
460            raise signals.TestFailure(msg)
461
462    def helper_toggle_airplane_reboot_configstore_reconnect(self):
463        """Connect to multiple networks, enable Airplane mode, reboot, then
464           reconnect to previously connected network.
465
466        Steps:
467        1. Connect to a 2GHz network.
468        2. Connect to a 5GHz network.
469        3. Toggle Airplane mode ON.
470        4. Reboot device.
471        5. Toggle Airplane mode OFF.
472        4. Verify all networks are persistent after reboot.
473        5. Reconnect to the non-current network.
474
475        """
476        network_list = self.connect_multiple_networks(self.dut)
477        self.log.debug("Toggling Airplane mode ON")
478        asserts.assert_true(
479            acts.utils.force_airplane_mode(self.dut, True),
480            "Can not turn on airplane mode on: %s" % self.dut.serial)
481        time.sleep(DEFAULT_TIMEOUT)
482        self.dut.reboot()
483        time.sleep(DEFAULT_TIMEOUT)
484        self.log.debug("Toggling Airplane mode OFF")
485        asserts.assert_true(
486            acts.utils.force_airplane_mode(self.dut, False),
487            "Can not turn on airplane mode on: %s" % self.dut.serial)
488        time.sleep(DEFAULT_TIMEOUT)
489        self.check_configstore_networks(network_list)
490        reconnect_to = self.get_enabled_network(network_list[BAND_2GHZ],
491                                                network_list[BAND_5GHZ])
492        reconnect = self.connect_to_wifi_network_with_id(
493            reconnect_to[WifiEnums.NETID_KEY],
494            reconnect_to[WifiEnums.SSID_KEY])
495        if not reconnect:
496            msg = ("Device failed to reconnect to the correct network after"
497                   " toggling Airplane mode and rebooting.")
498            raise signals.TestFailure(msg)
499
500    def verify_traffic_between_devices(self,dest_device,src_device,num_of_tries=2):
501        """Test the clients and DUT can ping each other.
502
503        Args:
504            num_of_tries: the retry times of ping test.
505            dest_device:Test device.
506            src_device:Second DUT access same AP
507        """
508        dest_device = dest_device.droid.connectivityGetIPv4Addresses('wlan0')[0]
509        for _ in range(num_of_tries):
510            if acts.utils.adb_shell_ping(src_device, count=10, dest_ip=dest_device, timeout=20):
511                break
512        else:
513            asserts.fail("Ping to %s from %s failed" % (src_device.serial, dest_device))
514
515    """Tests"""
516
517    @test_tracker_info(uuid="525fc5e3-afba-4bfd-9a02-5834119e3c66")
518    def test_toggle_wifi_state_and_get_startupTime(self):
519        """Test toggling wifi"""
520        self.log.debug("Going from on to off.")
521        wutils.wifi_toggle_state(self.dut, False)
522        self.log.debug("Going from off to on.")
523        startTime = time.time()
524        wutils.wifi_toggle_state(self.dut, True)
525        startup_time = time.time() - startTime
526        self.log.debug("WiFi was enabled on the device in %s s." % startup_time)
527
528    @test_tracker_info(uuid="e9d11563-2bbe-4c96-87eb-ec919b51435b")
529    def test_toggle_with_screen(self):
530        """Test toggling wifi with screen on/off"""
531        wait_time = 5
532        self.log.debug("Screen from off to on.")
533        self.dut.droid.wakeLockAcquireBright()
534        self.dut.droid.wakeUpNow()
535        time.sleep(wait_time)
536        self.log.debug("Going from on to off.")
537        try:
538            wutils.wifi_toggle_state(self.dut, False)
539            time.sleep(wait_time)
540            self.log.debug("Going from off to on.")
541            wutils.wifi_toggle_state(self.dut, True)
542        finally:
543            self.dut.droid.wakeLockRelease()
544            time.sleep(wait_time)
545            self.dut.droid.goToSleepNow()
546
547    @test_tracker_info(uuid="71556e06-7fb1-4e2b-9338-b01f1f8e286e")
548    def test_scan(self):
549        """Test wifi connection scan can start and find expected networks."""
550        ssid = self.open_network_2g[WifiEnums.SSID_KEY]
551        wutils.start_wifi_connection_scan_and_ensure_network_found(
552            self.dut, ssid)
553        ssid = self.open_network_5g[WifiEnums.SSID_KEY]
554        wutils.start_wifi_connection_scan_and_ensure_network_found(
555            self.dut, ssid)
556
557    @test_tracker_info(uuid="3ea09efb-6921-429e-afb1-705ef5a09afa")
558    def test_scan_with_wifi_off_and_location_scan_on(self):
559        """Put wifi in scan only mode"""
560        self.turn_location_on_and_scan_toggle_on()
561        wutils.wifi_toggle_state(self.dut, False)
562
563        """Test wifi connection scan can start and find expected networks."""
564        ssid = self.open_network_2g[WifiEnums.SSID_KEY]
565        wutils.start_wifi_connection_scan_and_ensure_network_found(
566            self.dut, ssid)
567        ssid = self.open_network_5g[WifiEnums.SSID_KEY]
568        wutils.start_wifi_connection_scan_and_ensure_network_found(
569            self.dut, ssid)
570
571    @test_tracker_info(uuid="770caebe-bcb1-43ac-95b6-5dd52dd90e80")
572    def test_scan_with_wifi_off_and_location_scan_off(self):
573        """Turn off wifi and location scan"""
574        self.turn_location_on_and_scan_toggle_off()
575        wutils.wifi_toggle_state(self.dut, False)
576
577        """Test wifi connection scan should fail."""
578        self.dut.droid.wifiStartScan()
579        try:
580            self.dut.ed.pop_event("WifiManagerScanResultsAvailable", 60)
581        except queue.Empty:
582            self.log.debug("Wifi scan results not received.")
583        else:
584            asserts.fail("Wi-Fi scan results received")
585
586    @test_tracker_info(uuid="a4ad9930-a8fa-4868-81ed-a79c7483e502")
587    def test_add_network(self):
588        """Test wifi connection scan."""
589        ssid = self.open_network_2g[WifiEnums.SSID_KEY]
590        nId = self.dut.droid.wifiAddNetwork(self.open_network_2g)
591        asserts.assert_true(nId > -1, "Failed to add network.")
592        configured_networks = self.dut.droid.wifiGetConfiguredNetworks()
593        self.log.debug(
594            ("Configured networks after adding: %s" % configured_networks))
595        wutils.assert_network_in_list({
596            WifiEnums.SSID_KEY: ssid
597        }, configured_networks)
598
599    @test_tracker_info(uuid="aca85551-10ba-4007-90d9-08bcdeb16a60")
600    def test_forget_network(self):
601        ssid = self.open_network_2g[WifiEnums.SSID_KEY]
602        nId = self.dut.droid.wifiAddNetwork(self.open_network_2g)
603        asserts.assert_true(nId > -1, "Failed to add network.")
604        configured_networks = self.dut.droid.wifiGetConfiguredNetworks()
605        self.log.debug(
606            ("Configured networks after adding: %s" % configured_networks))
607        wutils.assert_network_in_list({
608            WifiEnums.SSID_KEY: ssid
609        }, configured_networks)
610        wutils.wifi_forget_network(self.dut, ssid)
611        configured_networks = self.dut.droid.wifiGetConfiguredNetworks()
612        for nw in configured_networks:
613            asserts.assert_true(
614                nw[WifiEnums.BSSID_KEY] != ssid,
615                "Found forgotten network %s in configured networks." % ssid)
616
617    @test_tracker_info(uuid="b306d65c-6df3-4eb5-a178-6278bdc76c3e")
618    def test_reconnect_to_connected_network(self):
619        """Connect to a network and immediately issue reconnect.
620
621        Steps:
622        1. Connect to a 2GHz network.
623        2. Reconnect to the network using its network id.
624        3. Connect to a 5GHz network.
625        4. Reconnect to the network using its network id.
626
627        """
628        connect_2g_data = self.get_connection_data(self.dut, self.wpapsk_2g)
629        reconnect_2g = self.connect_to_wifi_network_with_id(
630            connect_2g_data[WifiEnums.NETID_KEY],
631            connect_2g_data[WifiEnums.SSID_KEY])
632        if not reconnect_2g:
633            raise signals.TestFailure("Device did not connect to the correct"
634                                      " 2GHz network.")
635        connect_5g_data = self.get_connection_data(self.dut, self.wpapsk_5g)
636        reconnect_5g = self.connect_to_wifi_network_with_id(
637            connect_5g_data[WifiEnums.NETID_KEY],
638            connect_5g_data[WifiEnums.SSID_KEY])
639        if not reconnect_5g:
640            raise signals.TestFailure("Device did not connect to the correct"
641                                      " 5GHz network.")
642
643    @test_tracker_info(uuid="3cff17f6-b684-4a95-a438-8272c2ad441d")
644    def test_reconnect_to_previously_connected(self):
645        """Connect to multiple networks and reconnect to the previous network.
646
647        Steps:
648        1. Connect to a 2GHz network.
649        2. Connect to a 5GHz network.
650        3. Reconnect to the 2GHz network using its network id.
651        4. Reconnect to the 5GHz network using its network id.
652
653        """
654        connect_2g_data = self.get_connection_data(self.dut, self.wpapsk_2g)
655        connect_5g_data = self.get_connection_data(self.dut, self.wpapsk_5g)
656        reconnect_2g = self.connect_to_wifi_network_with_id(
657            connect_2g_data[WifiEnums.NETID_KEY],
658            connect_2g_data[WifiEnums.SSID_KEY])
659        if not reconnect_2g:
660            raise signals.TestFailure("Device did not connect to the correct"
661                                      " 2GHz network.")
662        reconnect_5g = self.connect_to_wifi_network_with_id(
663            connect_5g_data[WifiEnums.NETID_KEY],
664            connect_5g_data[WifiEnums.SSID_KEY])
665        if not reconnect_5g:
666            raise signals.TestFailure("Device did not connect to the correct"
667                                      " 5GHz network.")
668
669    @test_tracker_info(uuid="334175c3-d26a-4c87-a8ab-8eb220b2d80f")
670    def test_reconnect_toggle_wifi(self):
671        """Connect to multiple networks, turn off/on wifi, then reconnect to
672           a previously connected network.
673
674        Steps:
675        1. Connect to a 2GHz network.
676        2. Connect to a 5GHz network.
677        3. Turn WiFi OFF/ON.
678        4. Reconnect to the non-current network.
679
680        """
681        self.helper_reconnect_toggle_wifi()
682
683    @test_tracker_info(uuid="bd2cec9e-7f17-44ef-8a0c-4da92a9b55ae")
684    def test_reconnect_toggle_wifi_with_location_scan_on(self):
685        """Connect to multiple networks, turn off/on wifi, then reconnect to
686           a previously connected network.
687
688        Steps:
689        1. Turn on location scans.
690        2. Connect to a 2GHz network.
691        3. Connect to a 5GHz network.
692        4. Turn WiFi OFF/ON.
693        5. Reconnect to the non-current network.
694
695        """
696        self.turn_location_on_and_scan_toggle_on()
697        self.helper_reconnect_toggle_wifi()
698
699    @test_tracker_info(uuid="8e6e6c21-fefb-4fe8-9fb1-f09b1182b76d")
700    def test_reconnect_toggle_airplane(self):
701        """Connect to multiple networks, turn on/off Airplane moce, then
702           reconnect a previously connected network.
703
704        Steps:
705        1. Connect to a 2GHz network.
706        2. Connect to a 5GHz network.
707        3. Turn ON/OFF Airplane mode.
708        4. Reconnect to the non-current network.
709
710        """
711        self.helper_reconnect_toggle_airplane()
712
713    @test_tracker_info(uuid="28562f13-8a0a-492e-932c-e587560db5f2")
714    def test_reconnect_toggle_airplane_with_location_scan_on(self):
715        """Connect to multiple networks, turn on/off Airplane moce, then
716           reconnect a previously connected network.
717
718        Steps:
719        1. Turn on location scans.
720        2. Connect to a 2GHz network.
721        3. Connect to a 5GHz network.
722        4. Turn ON/OFF Airplane mode.
723        5. Reconnect to the non-current network.
724
725        """
726        self.turn_location_on_and_scan_toggle_on()
727        self.helper_reconnect_toggle_airplane()
728
729    @test_tracker_info(uuid="3d041c12-05e2-46a7-ab9b-e3f60cc735db")
730    def test_reboot_configstore_reconnect(self):
731        """Connect to multiple networks, reboot then reconnect to previously
732           connected network.
733
734        Steps:
735        1. Connect to a 2GHz network.
736        2. Connect to a 5GHz network.
737        3. Reboot device.
738        4. Verify all networks are persistent after reboot.
739        5. Reconnect to the non-current network.
740
741        """
742        self.helper_reboot_configstore_reconnect()
743
744    @test_tracker_info(uuid="a70d5853-67b5-4d48-bdf7-08ee51fafd21")
745    def test_reboot_configstore_reconnect_with_location_scan_on(self):
746        """Connect to multiple networks, reboot then reconnect to previously
747           connected network.
748
749        Steps:
750        1. Turn on location scans.
751        2. Connect to a 2GHz network.
752        3. Connect to a 5GHz network.
753        4. Reboot device.
754        5. Verify all networks are persistent after reboot.
755        6. Reconnect to the non-current network.
756
757        """
758        self.turn_location_on_and_scan_toggle_on()
759        self.helper_reboot_configstore_reconnect()
760
761    @test_tracker_info(uuid="26d94dfa-1349-4c8b-aea0-475eb73bb521")
762    def test_toggle_wifi_reboot_configstore_reconnect(self):
763        """Connect to multiple networks, disable WiFi, reboot, then
764           reconnect to previously connected network.
765
766        Steps:
767        1. Connect to a 2GHz network.
768        2. Connect to a 5GHz network.
769        3. Turn WiFi OFF.
770        4. Reboot device.
771        5. Turn WiFi ON.
772        4. Verify all networks are persistent after reboot.
773        5. Reconnect to the non-current network.
774
775        """
776        self.helper_toggle_wifi_reboot_configstore_reconnect()
777
778    @test_tracker_info(uuid="7c004a3b-c1c6-4371-9124-0f34650be915")
779    def test_toggle_wifi_reboot_configstore_reconnect_with_location_scan_on(self):
780        """Connect to multiple networks, disable WiFi, reboot, then
781           reconnect to previously connected network.
782
783        Steps:
784        1. Turn on location scans.
785        2. Connect to a 2GHz network.
786        3. Connect to a 5GHz network.
787        4. Turn WiFi OFF.
788        5. Reboot device.
789        6. Turn WiFi ON.
790        7. Verify all networks are persistent after reboot.
791        8. Reconnect to the non-current network.
792
793        """
794        self.turn_location_on_and_scan_toggle_on()
795        self.helper_toggle_wifi_reboot_configstore_reconnect()
796
797    @test_tracker_info(uuid="4fce017b-b443-40dc-a598-51d59d3bb38f")
798    def test_toggle_airplane_reboot_configstore_reconnect(self):
799        """Connect to multiple networks, enable Airplane mode, reboot, then
800           reconnect to previously connected network.
801
802        Steps:
803        1. Connect to a 2GHz network.
804        2. Connect to a 5GHz network.
805        3. Toggle Airplane mode ON.
806        4. Reboot device.
807        5. Toggle Airplane mode OFF.
808        4. Verify all networks are persistent after reboot.
809        5. Reconnect to the non-current network.
810
811        """
812        self.helper_toggle_airplane_reboot_configstore_reconnect()
813
814    @test_tracker_info(uuid="7f0810f9-2338-4158-95f5-057f5a1905b6")
815    def test_toggle_airplane_reboot_configstore_reconnect_with_location_scan_on(self):
816        """Connect to multiple networks, enable Airplane mode, reboot, then
817           reconnect to previously connected network.
818
819        Steps:
820        1. Turn on location scans.
821        2. Connect to a 2GHz network.
822        3. Connect to a 5GHz network.
823        4. Toggle Airplane mode ON.
824        5. Reboot device.
825        6. Toggle Airplane mode OFF.
826        7. Verify all networks are persistent after reboot.
827        8. Reconnect to the non-current network.
828
829        """
830        self.turn_location_on_and_scan_toggle_on()
831        self.helper_toggle_airplane_reboot_configstore_reconnect()
832
833    @test_tracker_info(uuid="81eb7527-4c92-4422-897a-6b5f6445e84a")
834    def test_config_store_with_wpapsk_2g(self):
835        self.connect_to_wifi_network_toggle_wifi_and_run_iperf(
836            (self.wpapsk_2g, self.dut))
837
838    @test_tracker_info(uuid="8457903d-cb7e-4c89-bcea-7f59585ea6e0")
839    def test_config_store_with_wpapsk_5g(self):
840        self.connect_to_wifi_network_toggle_wifi_and_run_iperf(
841            (self.wpapsk_5g, self.dut))
842
843    @test_tracker_info(uuid="b9fbc13a-47b4-4f64-bd2c-e5a3cb24ab2f")
844    def test_tdls_supported(self):
845        model = self.dut.model
846        self.log.debug("Model is %s" % model)
847        if not model.startswith("volantis"):
848            asserts.assert_true(self.dut.droid.wifiIsTdlsSupported(), (
849                "TDLS should be supported on %s, but device is "
850                "reporting not supported.") % model)
851        else:
852            asserts.assert_false(self.dut.droid.wifiIsTdlsSupported(), (
853                "TDLS should not be supported on %s, but device "
854                "is reporting supported.") % model)
855
856    @test_tracker_info(uuid="50637d40-ea59-4f4b-9fc1-e6641d64074c")
857    def test_energy_info(self):
858        """Verify the WiFi energy info reporting feature """
859        self.get_energy_info()
860
861    @test_tracker_info(uuid="1f1cf549-53eb-4f36-9f33-ce06c9158efc")
862    def test_energy_info_connected(self):
863        """Verify the WiFi energy info reporting feature when connected.
864
865        Connect to a wifi network, then the same as test_energy_info.
866        """
867        wutils.wifi_connect(self.dut, self.open_network_2g)
868        self.get_energy_info()
869
870    @test_tracker_info(uuid="2622c253-defc-4a35-93a6-ca9d29a8238c")
871    def test_connect_to_wep_2g(self):
872        """Verify DUT can connect to 2GHz WEP network
873
874        Steps:
875        1. Ensure the 2GHz WEP network is visible in scan result.
876        2. Connect to the network and validate internet connection.
877        """
878        wutils.connect_to_wifi_network(self.dut, self.wep_networks[0]["2g"])
879
880    @test_tracker_info(uuid="1f2d17a2-e92d-43af-966b-3421c0db8620")
881    def test_connect_to_wep_5g(self):
882        """Verify DUT can connect to 5GHz WEP network
883
884        Steps:
885        1. Ensure the 5GHz WEP network is visible in scan result.
886        2. Connect to the network and validate internet connection.
887        """
888        wutils.connect_to_wifi_network(self.dut, self.wep_networks[0]["5g"])
889
890    @test_tracker_info(uuid="4a957952-289d-4657-9882-e1475274a7ff")
891    def test_connect_to_wpa_2g(self):
892        """Verify DUT can connect to 2GHz WPA-PSK network
893
894        Steps:
895        1. Ensure the 2GHz WPA-PSK network is visible in scan result.
896        2. Connect to the network and validate internet connection.
897        """
898        wutils.connect_to_wifi_network(self.dut, self.wpa_networks[0]["2g"])
899
900    @test_tracker_info(uuid="612c3c31-a4c5-4014-9a2d-3f4bcc20c0d7")
901    def test_connect_to_wpa_5g(self):
902        """Verify DUT can connect to 5GHz WPA-PSK network
903
904        Steps:
905        1. Ensure the 5GHz WPA-PSK network is visible in scan result.
906        2. Connect to the network and validate internet connection.
907        """
908        wutils.connect_to_wifi_network(self.dut, self.wpa_networks[0]["5g"])
909
910    @test_tracker_info(uuid="2a617fb4-1d8e-44e9-a500-a5456e1df83f")
911    def test_connect_to_2g_can_be_pinged(self):
912        """Verify DUT can be pinged by another device when it connects to 2GHz AP
913
914        Steps:
915        1. Ensure the 2GHz WPA-PSK network is visible in scan result.
916        2. Connect to the network and validate internet connection.
917        3. Check DUT can be pinged by another device
918        """
919        wutils.connect_to_wifi_network(self.dut, self.wpa_networks[0]["2g"])
920        wutils.connect_to_wifi_network(self.dut_client, self.wpa_networks[0]["2g"])
921        self.verify_traffic_between_devices(self.dut,self.dut_client)
922
923    @test_tracker_info(uuid="94bdd657-649b-4a2c-89c3-3ec6ba18e08e")
924    def test_connect_to_5g_can_be_pinged(self):
925        """Verify DUT can be pinged by another device when it connects to 5GHz AP
926
927        Steps:
928        1. Ensure the 5GHz WPA-PSK network is visible in scan result.
929        2. Connect to the network and validate internet connection.
930        3. Check DUT can be pinged by another device
931        """
932        wutils.connect_to_wifi_network(self.dut, self.wpa_networks[0]["5g"])
933        wutils.connect_to_wifi_network(self.dut_client, self.wpa_networks[0]["5g"])
934        self.verify_traffic_between_devices(self.dut,self.dut_client)
935
936    @test_tracker_info(uuid="d87359aa-c4da-4554-b5de-8e3fa852a6b0")
937    def test_sta_turn_off_screen_can_be_pinged(self):
938        """Verify DUT can be pinged by another device after idle for a while
939
940        Steps:
941        1. Ensure the 2GHz WPA-PSK network is visible in scan result.
942        2. DUT and DUT_Client connect to the network and validate internet connection.
943        3. Let DUT sleep for 5 minutes
944        4. Check DUT can be pinged by DUT_Client
945        """
946        # DUT connect to AP
947        wutils.connect_to_wifi_network(self.dut, self.wpa_networks[0]["2g"])
948        wutils.connect_to_wifi_network(self.dut_client, self.wpa_networks[0]["2g"])
949        # Check DUT and DUT_Client can ping each other successfully
950        self.verify_traffic_between_devices(self.dut,self.dut_client)
951        self.verify_traffic_between_devices(self.dut_client,self.dut)
952        # DUT turn off screen and go sleep for 5 mins
953        self.dut.droid.wakeLockRelease()
954        self.dut.droid.goToSleepNow()
955        # TODO(hsiuchangchen): find a way to check system already suspended
956        #                      instead of waiting 5 mins
957        self.log.info("Sleep for 5 minutes")
958        time.sleep(300)
959        # Verify DUT_Client can ping DUT when DUT sleeps
960        self.verify_traffic_between_devices(self.dut,self.dut_client)
961        self.dut.droid.wakeLockAcquireBright()
962        self.dut.droid.wakeUpNow()
963
964    @test_tracker_info(uuid="402cfaa8-297f-4865-9e27-6bab6adca756")
965    def test_reboot_wifi_and_bluetooth_on(self):
966        """Toggle WiFi and bluetooth ON then reboot """
967        wutils.wifi_toggle_state(self.dut, True)
968        enable_bluetooth(self.dut.droid, self.dut.ed)
969
970        self.dut.reboot()
971        time.sleep(DEFAULT_TIMEOUT)
972
973        asserts.assert_true(self.dut.droid.bluetoothCheckState(),
974                "bluetooth state changed after reboot")
975        asserts.assert_true(self.dut.droid.wifiCheckState(),
976                "wifi state changed after reboot")
977
978        disable_bluetooth(self.dut.droid)
979