1#!/usr/bin/env python3.4 2# 3# Copyright (C) 2020 The Android Open Source Project 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); you may not 6# use this file except in compliance with the License. You may obtain a copy of 7# 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, WITHOUT 13# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14# License for the specific language governing permissions and limitations under 15# the License. 16# 17"""This test exercises the Scan functionality for the WLAN Policy API.""" 18 19from datetime import datetime 20 21from acts import signals 22from acts.controllers.ap_lib import (hostapd_ap_preset, hostapd_bss_settings, 23 hostapd_constants, hostapd_security) 24from acts_contrib.test_utils.wifi.WifiBaseTest import WifiBaseTest 25 26 27class PolicyScanTest(WifiBaseTest): 28 """WLAN policy scan test class. 29 30 Test Bed Requirement: 31 * One or more Fuchsia devices 32 * One Whirlwind Access Point 33 """ 34 35 def setup_class(self): 36 super().setup_class() 37 if len(self.fuchsia_devices) < 1: 38 raise signals.TestFailure("No fuchsia devices found.") 39 for fd in self.fuchsia_devices: 40 fd.configure_wlan(association_mechanism='policy', 41 preserve_saved_networks=True) 42 if len(self.access_points) < 1: 43 raise signals.TestFailure("No access points found.") 44 # Prepare the AP 45 self.access_point = self.access_points[0] 46 self.access_point.stop_all_aps() 47 # Generate network params. 48 bss_settings_2g = [] 49 bss_settings_5g = [] 50 open_network = self.get_open_network(False, []) 51 self.open_network_2g = open_network["2g"] 52 self.open_network_5g = open_network["5g"] 53 wpa2_settings = self.get_psk_network(False, []) 54 self.wpa2_network_2g = wpa2_settings["2g"] 55 self.wpa2_network_5g = wpa2_settings["5g"] 56 bss_settings_2g.append( 57 hostapd_bss_settings.BssSettings( 58 name=self.wpa2_network_2g["SSID"], 59 ssid=self.wpa2_network_2g["SSID"], 60 security=hostapd_security.Security( 61 security_mode=self.wpa2_network_2g["security"], 62 password=self.wpa2_network_2g["password"]))) 63 bss_settings_5g.append( 64 hostapd_bss_settings.BssSettings( 65 name=self.wpa2_network_5g["SSID"], 66 ssid=self.wpa2_network_5g["SSID"], 67 security=hostapd_security.Security( 68 security_mode=self.wpa2_network_5g["security"], 69 password=self.wpa2_network_5g["password"]))) 70 self.ap_2g = hostapd_ap_preset.create_ap_preset( 71 iface_wlan_2g=self.access_points[0].wlan_2g, 72 iface_wlan_5g=self.access_points[0].wlan_5g, 73 channel=hostapd_constants.AP_DEFAULT_CHANNEL_2G, 74 ssid=self.open_network_2g["SSID"], 75 bss_settings=bss_settings_2g) 76 self.ap_5g = hostapd_ap_preset.create_ap_preset( 77 iface_wlan_2g=self.access_points[0].wlan_2g, 78 iface_wlan_5g=self.access_points[0].wlan_5g, 79 channel=hostapd_constants.AP_DEFAULT_CHANNEL_5G, 80 ssid=self.open_network_5g["SSID"], 81 bss_settings=bss_settings_5g) 82 # Start the networks 83 self.access_point.start_ap(hostapd_config=self.ap_2g) 84 self.access_point.start_ap(hostapd_config=self.ap_5g) 85 # Save the SSIDs 86 self.all_ssids = [ 87 self.open_network_2g["SSID"], 88 self.wpa2_network_2g["SSID"], 89 self.open_network_5g["SSID"], 90 self.wpa2_network_5g["SSID"], 91 ] 92 93 def setup_test(self): 94 for fd in self.fuchsia_devices: 95 # stub for setting up all the fuchsia devices in the testbed. 96 return fd.wlan_policy_controller.remove_all_networks_and_wait_for_no_connections( 97 ) 98 99 def teardown_test(self): 100 for fd in self.fuchsia_devices: 101 # stub until policy layer has something useful to use here. 102 pass 103 104 def teardown_class(self): 105 pass 106 107 def on_fail(self, test_name, begin_time): 108 for fd in self.fuchsia_devices: 109 try: 110 fd.take_bug_report(test_name, begin_time) 111 fd.get_log(test_name, begin_time) 112 except Exception: 113 pass 114 115 try: 116 if fd.device.hard_reboot_on_fail: 117 fd.hard_power_cycle(self.pdu_devices) 118 except AttributeError: 119 pass 120 121 """Helper Functions""" 122 123 def perform_scan(self, fd): 124 """ Initiates scan on a Fuchsia device and returns results 125 126 Args: 127 fd: A fuchsia device 128 129 Raises: 130 signals.TestFailure: if an error is reported by the device during 131 the scan 132 133 Returns: 134 A list of scan results 135 """ 136 start_time = datetime.now() 137 138 scan_response = fd.sl4f.wlan_policy_lib.wlanScanForNetworks() 139 140 # first check if we received an error 141 if scan_response.get("error") is not None: 142 # the response indicates an error - log and raise failure 143 raise signals.TestFailure("Aborting test - scan failed with " 144 "error: %s" % scan_response.get("error")) 145 146 # the scan command did not get an error response - go ahead 147 # and check for scan results 148 scan_results = scan_response["result"] 149 total_time_ms = (datetime.now() - start_time).total_seconds() * 1000 150 151 self.log.info("scan contained %d results", len(scan_results)) 152 self.log.info("scan time: %d ms", total_time_ms) 153 154 return scan_results 155 156 def connect_to_network(self, wlan_network_params, fd): 157 """ Connects the Fuchsia device to the specified network 158 159 Args: 160 wlan_network_params: A dictionary containing wlan information. 161 fd: A fuchsia device 162 163 Raises: 164 signals.TestFailure: if the device fails to connect 165 """ 166 target_ssid = wlan_network_params["SSID"] 167 target_pwd = wlan_network_params.get("password") 168 target_security = wlan_network_params.get("security") 169 170 # TODO(mnck): use the Policy version of this call, when it is available. 171 connection_response = fd.wlan_policy_controller.save_and_connect( 172 target_ssid, target_security, password=target_pwd) 173 if not connection_response: 174 raise signals.TestFailure("Aborting test - Connect call failed") 175 self.log.info("Network connection successful.") 176 177 def assert_network_is_in_results(self, scan_results, *, ssid): 178 """ Verified scan results contain a specified network 179 180 Args: 181 scan_results: Scan results from a fuchsia Policy API scan 182 ssid: SSID for network that should be in the results 183 184 Raises: 185 signals.TestFailure: if the network is not present in the scan 186 results 187 """ 188 if ssid not in scan_results: 189 raise signals.TestFailure( 190 'Network "%s" was not found in scan results: %s', ssid, 191 scan_results) 192 193 """Tests""" 194 195 def test_basic_scan_request(self): 196 """Verify a scan returns all expected networks""" 197 for fd in self.fuchsia_devices: 198 scan_results = self.perform_scan(fd) 199 if len(scan_results) == 0: 200 raise signals.TestFailure("Scan failed or did not " 201 "find any networks") 202 for ssid in self.all_ssids: 203 self.assert_network_is_in_results(scan_results, ssid=ssid) 204 205 def test_scan_while_connected_open_network_2g(self): 206 """Connect to an open 2g network and perform a scan""" 207 for fd in self.fuchsia_devices: 208 self.connect_to_network(self.open_network_2g, fd) 209 scan_results = self.perform_scan(fd) 210 for ssid in self.all_ssids: 211 self.assert_network_is_in_results(scan_results, ssid=ssid) 212 213 def test_scan_while_connected_wpa2_network_2g(self): 214 """Connect to a WPA2 2g network and perform a scan""" 215 for fd in self.fuchsia_devices: 216 self.connect_to_network(self.wpa2_network_2g, fd) 217 scan_results = self.perform_scan(fd) 218 for ssid in self.all_ssids: 219 self.assert_network_is_in_results(scan_results, ssid=ssid) 220 221 def test_scan_while_connected_open_network_5g(self): 222 """Connect to an open 5g network and perform a scan""" 223 for fd in self.fuchsia_devices: 224 self.connect_to_network(self.open_network_5g, fd) 225 scan_results = self.perform_scan(fd) 226 for ssid in self.all_ssids: 227 self.assert_network_is_in_results(scan_results, ssid=ssid) 228 229 def test_scan_while_connected_wpa2_network_5g(self): 230 """Connect to a WPA2 5g network and perform a scan""" 231 for fd in self.fuchsia_devices: 232 self.connect_to_network(self.wpa2_network_5g, fd) 233 scan_results = self.perform_scan(fd) 234 for ssid in self.all_ssids: 235 self.assert_network_is_in_results(scan_results, ssid=ssid) 236