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