blob: 9340707759a40d4c44011db9e1749f23d36f878a [file] [log] [blame]
#!/usr/bin/env python3
#
# Copyright 2022 The Fuchsia Authors
#
# 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.
"""
Script for testing WiFi recovery after rebooting the AP.
Override default number of iterations using the following
parameter in the test config file.
"beacon_loss_test_iterations": "5"
"""
import logging
import time
from mobly import asserts, test_runner
from mobly.records import TestResultRecord
from antlion.controllers.access_point import setup_ap
from antlion.controllers.ap_lib import hostapd_constants
from antlion.test_utils.abstract_devices.wlan_device import create_wlan_device
from antlion.test_utils.wifi import base_test
from antlion.utils import rand_ascii_str
class BeaconLossTest(base_test.WifiBaseTest):
# Default number of test iterations here.
# Override using parameter in config file.
# Eg: "beacon_loss_test_iterations": "10"
num_of_iterations = 5
# Time to wait for AP to startup
wait_ap_startup_s = 15
# Default wait time in seconds for the AP radio to turn back on
wait_to_connect_after_ap_txon_s = 5
# Time to wait for device to disconnect after AP radio of
wait_after_ap_txoff_s = 15
# Time to wait for device to complete connection setup after
# given an associate command
wait_client_connection_setup_s = 15
def setup_class(self):
super().setup_class()
self.log = logging.getLogger()
self.ssid = rand_ascii_str(10)
device_type = self.user_params.get("dut", "fuchsia_devices")
if device_type == "fuchsia_devices":
self.dut = create_wlan_device(self.fuchsia_devices[0])
elif device_type == "android_devices":
self.dut = create_wlan_device(self.android_devices[0])
else:
raise ValueError(
f'Invalid "dut" type specified in config: "{device_type}".'
'Expected "fuchsia_devices" or "android_devices".'
)
self.access_point = self.access_points[0]
self.num_of_iterations = int(
self.user_params.get("beacon_loss_test_iterations", self.num_of_iterations)
)
self.in_use_interface = None
def teardown_test(self):
self.dut.disconnect()
self.dut.reset_wifi()
# ensure radio is on, in case the test failed while the radio was off
self.access_point.iwconfig.ap_iwconfig(self.in_use_interface, "txpower on")
self.download_ap_logs()
self.access_point.stop_all_aps()
def on_fail(self, record: TestResultRecord):
super().on_fail(record)
self.access_point.stop_all_aps()
def beacon_loss(self, channel):
setup_ap(
access_point=self.access_point,
profile_name="whirlwind",
channel=channel,
ssid=self.ssid,
)
time.sleep(self.wait_ap_startup_s)
if channel > 14:
self.in_use_interface = self.access_point.wlan_5g
else:
self.in_use_interface = self.access_point.wlan_2g
# TODO(b/144505723): [ACTS] update BeaconLossTest.py to handle client
# roaming, saved networks, etc.
self.log.info("sending associate command for ssid %s", self.ssid)
self.dut.associate(target_ssid=self.ssid)
asserts.assert_true(self.dut.is_connected(), "Failed to connect.")
time.sleep(self.wait_client_connection_setup_s)
for _ in range(0, self.num_of_iterations):
# Turn off AP radio
self.log.info("turning off radio")
self.access_point.iwconfig.ap_iwconfig(self.in_use_interface, "txpower off")
time.sleep(self.wait_after_ap_txoff_s)
# Did we disconnect from AP?
asserts.assert_false(self.dut.is_connected(), "Failed to disconnect.")
# Turn on AP radio
self.log.info("turning on radio")
self.access_point.iwconfig.ap_iwconfig(self.in_use_interface, "txpower on")
time.sleep(self.wait_to_connect_after_ap_txon_s)
# Tell the client to connect
self.log.info(f"sending associate command for ssid {self.ssid}")
self.dut.associate(target_ssid=self.ssid)
time.sleep(self.wait_client_connection_setup_s)
# Did we connect back to WiFi?
asserts.assert_true(self.dut.is_connected(), "Failed to connect back.")
return True
def test_beacon_loss_2g(self):
self.beacon_loss(channel=hostapd_constants.AP_DEFAULT_CHANNEL_2G)
def test_beacon_loss_5g(self):
self.beacon_loss(channel=hostapd_constants.AP_DEFAULT_CHANNEL_5G)
if __name__ == "__main__":
test_runner.main()