blob: e2d1036a96db9573b3517c9e82fe2d754a237fa8 [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 connection and disconnection in a loop
"""
import logging
import time
from mobly import signals, test_runner
from mobly.records import TestResultRecord
from antlion.controllers.access_point import setup_ap
from antlion.controllers.ap_lib import hostapd_constants, hostapd_security
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 ConnectionStressTest(base_test.WifiBaseTest):
# Default number of test iterations here.
# Override using parameter in config file.
# Eg: "connection_stress_test_iterations": "50"
num_of_iterations = 10
channel_2G = hostapd_constants.AP_DEFAULT_CHANNEL_2G
channel_5G = hostapd_constants.AP_DEFAULT_CHANNEL_5G
def setup_class(self):
super().setup_class()
self.log = logging.getLogger()
self.ssid = rand_ascii_str(10)
self.fd = self.fuchsia_devices[0]
self.dut = create_wlan_device(self.fd)
self.access_point = self.access_points[0]
self.num_of_iterations = int(
self.user_params.get(
"connection_stress_test_iterations", self.num_of_iterations
)
)
self.log.info(f"iterations: {self.num_of_iterations}")
def teardown_test(self):
self.dut.reset_wifi()
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 start_ap(self, profile, channel, security=None):
"""Starts an Access Point
Args:
profile: Profile name such as 'whirlwind'
channel: Channel to operate on
"""
self.log.info(f"Profile: {profile}, Channel: {channel}")
setup_ap(
access_point=self.access_point,
profile_name=profile,
channel=channel,
ssid=self.ssid,
security=security,
)
def connect_disconnect(
self, ap_config, ssid=None, password=None, negative_test=False
):
"""Helper to start an AP, connect DUT to it and disconnect
Args:
ap_config: Dictionary contaning profile name and channel
ssid: ssid to connect to
password: password for the ssid to connect to
"""
security_mode = ap_config.get("security_mode", None)
target_security = (
hostapd_constants.SECURITY_STRING_TO_DEFAULT_TARGET_SECURITY.get(
security_mode, None
)
)
if security_mode:
security_profile = hostapd_security.Security(
security_mode=ap_config["security_mode"], password=ap_config["password"]
)
else:
security_profile = None
# Start AP
self.start_ap(
ap_config["profile"], ap_config["channel"], security=security_profile
)
failed = False
# Connect and Disconnect several times
for x in range(0, self.num_of_iterations):
if not ssid:
ssid = self.ssid
if negative_test:
if not self.dut.associate(
ssid, target_pwd=password, target_security=target_security
):
self.log.info(f"Attempt {x}. Did not associate as expected.")
else:
self.log.error(
"Attempt %d. Negative test successfully "
"associated. Fail." % x
)
failed = True
else:
# Connect
if self.dut.associate(ssid, target_pwd=password):
self.log.info(f"Attempt {x}. Successfully associated")
else:
self.log.error(f"Attempt {x}. Failed to associate.")
failed = True
# Disconnect
self.dut.disconnect()
# Wait a second before trying again
time.sleep(1)
# Stop AP
self.access_point.stop_all_aps()
if failed:
raise signals.TestFailure("One or more association attempt failed.")
def test_whirlwind_2g(self):
self.connect_disconnect(
{"profile": "whirlwind", "channel": self.channel_2G, "security_mode": None}
)
def test_whirlwind_5g(self):
self.connect_disconnect(
{"profile": "whirlwind", "channel": self.channel_5G, "security_mode": None}
)
def test_whirlwind_11ab_2g(self):
self.connect_disconnect(
{
"profile": "whirlwind_11ab_legacy",
"channel": self.channel_2G,
"security_mode": None,
}
)
def test_whirlwind_11ab_5g(self):
self.connect_disconnect(
{
"profile": "whirlwind_11ab_legacy",
"channel": self.channel_5G,
"security_mode": None,
}
)
def test_whirlwind_11ag_2g(self):
self.connect_disconnect(
{
"profile": "whirlwind_11ag_legacy",
"channel": self.channel_2G,
"security_mode": None,
}
)
def test_whirlwind_11ag_5g(self):
self.connect_disconnect(
{
"profile": "whirlwind_11ag_legacy",
"channel": self.channel_5G,
"security_mode": None,
}
)
def test_wrong_ssid_whirlwind_2g(self):
self.connect_disconnect(
{"profile": "whirlwind", "channel": self.channel_2G, "security_mode": None},
ssid=rand_ascii_str(20),
negative_test=True,
)
def test_wrong_ssid_whirlwind_5g(self):
self.connect_disconnect(
{"profile": "whirlwind", "channel": self.channel_5G, "security_mode": None},
ssid=rand_ascii_str(20),
negative_test=True,
)
def test_wrong_password_whirlwind_2g(self):
self.connect_disconnect(
{
"profile": "whirlwind",
"channel": self.channel_2G,
"security_mode": hostapd_constants.WPA2_STRING,
"password": rand_ascii_str(10),
},
password=rand_ascii_str(20),
negative_test=True,
)
def test_wrong_password_whirlwind_5g(self):
self.connect_disconnect(
{
"profile": "whirlwind",
"channel": self.channel_5G,
"security_mode": hostapd_constants.WPA2_STRING,
"password": rand_ascii_str(10),
},
password=rand_ascii_str(20),
negative_test=True,
)
if __name__ == "__main__":
test_runner.main()