blob: 670aec03dc226ae2d9eecbd4523d2b4cd8131f1f [file] [log] [blame]
#!/usr/bin/env python3
#
# Copyright 2020 - 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.
from acts import signals
from acts.controllers.ap_lib import hostapd_constants
from acts.controllers.ap_lib import hostapd_security
from acts.test_utils.abstract_devices.utils_lib.wlan_utils import setup_ap
from acts.test_utils.abstract_devices.utils_lib.wlan_policy_utils import reboot_device, restore_state, save_network, setup_policy_tests
from acts.test_utils.wifi.WifiBaseTest import WifiBaseTest
from acts.utils import rand_ascii_str
import time
# These tests should have a longer timeout for connecting than normal connect
# tests because the device should probabilistically perform active scans for
# hidden networks. Multiple scans are necessary to verify a very low chance of
# random failure.
TIME_WAIT_FOR_CONNECT = 45
TIME_ATTEMPT_SCANS = 60
CONNECTIONS_ENABLED = "ConnectionsEnabled"
CONNECTIONS_DISABLED = "ConnectionsDisabled"
SECURITY_NONE = "none"
WPA2 = "wpa2"
class HiddenNetworksTest(WifiBaseTest):
""" Tests that WLAN Policy will detect hidden networks
Test Bed Requirement:
* One or more Fuchsia devices
* One Access Point
"""
def setup_class(self):
super().setup_class()
# Start an AP with a hidden network
self.hidden_ssid = rand_ascii_str(hostapd_constants.AP_SSID_LENGTH_2G)
self.access_point = self.access_points[0]
self.hidden_password = rand_ascii_str(
hostapd_constants.AP_PASSPHRASE_LENGTH_2G)
self.hidden_security = WPA2
security = hostapd_security.Security(
security_mode=self.hidden_security, password=self.hidden_password)
self.access_point.stop_all_aps()
setup_ap(self.access_point,
'whirlwind',
hostapd_constants.AP_DEFAULT_CHANNEL_5G,
self.hidden_ssid,
hidden=True,
security=security)
if len(self.fuchsia_devices) < 1:
raise EnvironmentError("No Fuchsia devices found.")
# Save the existing saved networks before we remove them for tests
# And remember whether client connections have started
self.preexisting_state = setup_policy_tests(self.fuchsia_devices)
def setup_test(self):
for fd in self.fuchsia_devices:
# Set new update listener so that the next test can always get the
# most recent udpdate immediately.
new_listener_result = fd.wlan_policy_lib.wlanSetNewListener()
if new_listener_result["error"] != None:
self.log.warn(
"Error occurred initializing a new update listener for the facade, may"
"cause errors in updates for tests: %s" %
new_listener_result["error"])
resultRemove = fd.wlan_policy_lib.wlanRemoveAllNetworks()
if resultRemove["error"] != None:
self.log.error(
"Error occurred when deleting all saved networks in test setup: %s"
% resultRemove["error"])
raise EnvironmentError(
"Failed to remove all networks in setup")
resultStart = fd.wlan_policy_lib.wlanStartClientConnections()
if resultStart["error"] != None:
self.log.error(
"Error occurred when starting client connections in test setup: %s"
% resultStart["error"])
raise EnvironmentError(
"Failed to start client connections in setup")
def teardown_class(self):
self.access_point.stop_all_aps()
for fd in self.fuchsia_devices:
# Put back the networks that were saved before tests began.
restore_state(self.fuchsia_devices, self.preexisting_state)
def test_scan_hidden_networks(self):
# Scan a few times and check that we see the hidden networks in the
# results at least once. Even if hidden networks are scanned
# probabilistically, we should see it after a few tries.
for fd in self.fuchsia_devices:
# A hidden network must be saved to be found in scan results.
# Stop client connections to not trigger a connect when saving,
# which would interfere with requested scans.
fd.wlan_policy_lib.wlanStopClientConnections()
if not save_network(fd, self.hidden_ssid, self.hidden_security,
self.hidden_password):
raise EnvironmentError("Failed to save network")
fd.wlan_policy_lib.wlanStartClientConnections()
start_time = time.time()
num_performed_scans = 0
while time.time() < start_time + TIME_ATTEMPT_SCANS:
num_performed_scans = num_performed_scans + 1
scan_result = fd.wlan_policy_lib.wlanScanForNetworks()
if scan_result["error"] != None:
self.log.error(
"Failed to scan for networks with error %s" %
scan_result["error"])
raise EnvironmentError("Failed to scan")
else:
scans = scan_result["result"]
if self.hidden_ssid in scans:
self.log.info(
"SSID of hidden network seen after %d scans" %
num_performed_scans)
return
# Don't overload SL4F with scan requests
time.sleep(1)
self.log.error("Failed to see SSID after %d scans" %
num_performed_scans)
raise signals.TestFailure("Failed to see hidden network in scans")
def test_auto_connect_hidden_on_startup(self):
""" Test that if we are not connected to anything but have a hidden
network saved, we will eventually actively scan for it and connect."""
# Start up AP with an open network with a random SSID
for fd in self.fuchsia_devices:
# Test that we will auto connect without anything being triggered by
# saving a new network.
fd.wlan_policy_lib.wlanStopClientConnections()
# Save the network.
if not save_network(fd, self.hidden_ssid, self.hidden_security,
self.hidden_password):
raise EnvironmentError("Failed to save network")
# Reboot the device and check that it auto connects.
reboot_device(fd)
if not fd.wait_for_connect(self.hidden_ssid,
self.hidden_security,
timeout=TIME_WAIT_FOR_CONNECT):
raise signals.TestFailure("Failed to connect to network")
def test_auto_connect_hidden_on_save(self):
""" Test that if we save a hidden network and are not connected to
anything, the device will connect to the hidden network that was
just saved. """
for fd in self.fuchsia_devices:
if not fd.wait_for_no_connections():
self.log.info(
"Failed to get into a disconnected state to start the test"
)
raise EnvironmentError("Failed to disconnect all")
# Save the network and make sure that we see the device auto connect to it.
if not save_network(fd, self.hidden_ssid, self.hidden_security,
self.hidden_password):
raise EnvironmentError("Failed to save network")
if not fd.wait_for_connect(self.hidden_ssid,
self.hidden_security,
timeout=TIME_WAIT_FOR_CONNECT):
raise signals.TestFailure("Failed to connect to network")