blob: d1ed6631c0e4de68ac2f83b475853b0b6e5971d2 [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.
import itertools
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.controllers.ap_lib.hostapd_security import 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
# AC Capabilities
"""
Capabilities Not Supported on Whirlwind:
- Supported Channel Width ([VHT160], [VHT160-80PLUS80]): 160mhz and 80+80
unsupported
- SU Beamformer [SU-BEAMFORMER]
- SU Beamformee [SU-BEAMFORMEE]
- MU Beamformer [MU-BEAMFORMER]
- MU Beamformee [MU-BEAMFORMEE]
- BF Antenna ([BF-ANTENNA-2], [BF-ANTENNA-3], [BF-ANTENNA-4])
- Rx STBC 2, 3, & 4 ([RX-STBC-12],[RX-STBC-123],[RX-STBC-124])
- VHT Link Adaptation ([VHT-LINK-ADAPT2],[VHT-LINK-ADAPT3])
- VHT TXOP Power Save [VHT-TXOP-PS]
- HTC-VHT [HTC-VHT]
"""
VHT_MAX_MPDU_LEN = [
hostapd_constants.AC_CAPABILITY_MAX_MPDU_7991,
hostapd_constants.AC_CAPABILITY_MAX_MPDU_11454,
"",
]
RXLDPC = [hostapd_constants.AC_CAPABILITY_RXLDPC, ""]
SHORT_GI_80 = [hostapd_constants.AC_CAPABILITY_SHORT_GI_80, ""]
TX_STBC = [hostapd_constants.AC_CAPABILITY_TX_STBC_2BY1, ""]
RX_STBC = [hostapd_constants.AC_CAPABILITY_RX_STBC_1, ""]
MAX_A_MPDU = [
hostapd_constants.AC_CAPABILITY_MAX_A_MPDU_LEN_EXP0,
hostapd_constants.AC_CAPABILITY_MAX_A_MPDU_LEN_EXP1,
hostapd_constants.AC_CAPABILITY_MAX_A_MPDU_LEN_EXP2,
hostapd_constants.AC_CAPABILITY_MAX_A_MPDU_LEN_EXP3,
hostapd_constants.AC_CAPABILITY_MAX_A_MPDU_LEN_EXP4,
hostapd_constants.AC_CAPABILITY_MAX_A_MPDU_LEN_EXP5,
hostapd_constants.AC_CAPABILITY_MAX_A_MPDU_LEN_EXP6,
hostapd_constants.AC_CAPABILITY_MAX_A_MPDU_LEN_EXP7,
"",
]
RX_ANTENNA = [hostapd_constants.AC_CAPABILITY_RX_ANTENNA_PATTERN, ""]
TX_ANTENNA = [hostapd_constants.AC_CAPABILITY_TX_ANTENNA_PATTERN, ""]
# Default 11N Capabilities
N_CAPABS_40MHZ = [
hostapd_constants.N_CAPABILITY_LDPC,
hostapd_constants.N_CAPABILITY_SGI20,
hostapd_constants.N_CAPABILITY_RX_STBC1,
hostapd_constants.N_CAPABILITY_SGI20,
hostapd_constants.N_CAPABILITY_SGI40,
hostapd_constants.N_CAPABILITY_MAX_AMSDU_7935,
hostapd_constants.N_CAPABILITY_HT40_PLUS,
]
N_CAPABS_20MHZ = [
hostapd_constants.N_CAPABILITY_LDPC,
hostapd_constants.N_CAPABILITY_SGI20,
hostapd_constants.N_CAPABILITY_RX_STBC1,
hostapd_constants.N_CAPABILITY_SGI20,
hostapd_constants.N_CAPABILITY_MAX_AMSDU_7935,
hostapd_constants.N_CAPABILITY_HT20,
]
# Default wpa2 profile.
WPA2_SECURITY = Security(
security_mode=hostapd_constants.WPA2_STRING,
password=rand_ascii_str(20),
wpa_cipher=hostapd_constants.WPA2_DEFAULT_CIPER,
wpa2_cipher=hostapd_constants.WPA2_DEFAULT_CIPER,
)
SECURITIES = [None, WPA2_SECURITY]
def generate_test_name(settings):
"""Generates a test name string based on the ac_capabilities for
a test case.
Args:
settings: a dict with the test settings (bandwidth, security, ac_capabs)
Returns:
A string test case name
"""
chbw = settings["chbw"]
sec = "wpa2" if settings["security"] else "open"
ret = []
for cap in hostapd_constants.AC_CAPABILITIES_MAPPING.keys():
if cap in settings["ac_capabilities"]:
ret.append(hostapd_constants.AC_CAPABILITIES_MAPPING[cap])
return "test_11ac_%smhz_%s_%s" % (chbw, sec, "".join(ret))
# 6912 test cases
class WlanPhyCompliance11ACTest(base_test.WifiBaseTest):
"""Tests for validating 11ac PHYS.
Test Bed Requirement:
* One Android device or Fuchsia device
* One Access Point
"""
def __init__(self, controllers):
super().__init__(controllers)
def setup_generated_tests(self):
test_args = (
self._generate_20mhz_test_args()
+ self._generate_40mhz_test_args()
+ self._generate_80mhz_test_args()
)
self.generate_tests(
test_logic=self.setup_and_connect,
name_func=generate_test_name,
arg_sets=test_args,
)
def setup_class(self):
super().setup_class()
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.android_devices = getattr(self, "android_devices", [])
self.access_point.stop_all_aps()
def setup_test(self):
for ad in self.android_devices:
ad.droid.wakeLockAcquireBright()
ad.droid.wakeUpNow()
self.dut.wifi_toggle_state(True)
def teardown_test(self):
for ad in self.android_devices:
ad.droid.wakeLockRelease()
ad.droid.goToSleepNow()
self.dut.turn_location_off_and_scan_toggle_off()
self.dut.disconnect()
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 setup_and_connect(self, ap_settings):
"""Uses ap_settings to set up ap and then attempts to associate a DUT.
Args:
ap_settings: a dict containing test case settings, including
bandwidth, security, n_capabilities, and ac_capabilities
"""
ssid = rand_ascii_str(20)
security = ap_settings["security"]
chbw = ap_settings["chbw"]
password = None
target_security = None
if security:
password = security.password
target_security = security.security_mode_string
n_capabilities = ap_settings["n_capabilities"]
ac_capabilities = ap_settings["ac_capabilities"]
setup_ap(
access_point=self.access_point,
profile_name="whirlwind",
mode=hostapd_constants.MODE_11AC_MIXED,
channel=36,
n_capabilities=n_capabilities,
ac_capabilities=ac_capabilities,
force_wmm=True,
ssid=ssid,
security=security,
vht_bandwidth=chbw,
password=password,
)
asserts.assert_true(
self.dut.associate(
ssid, target_pwd=password, target_security=target_security
),
"Failed to associate.",
)
# 1728 tests
def _generate_20mhz_test_args(self):
test_args = []
# 864 test cases for open security
# 864 test cases for wpa2 security
for combination in itertools.product(
SECURITIES,
VHT_MAX_MPDU_LEN,
RXLDPC,
RX_STBC,
TX_STBC,
MAX_A_MPDU,
RX_ANTENNA,
TX_ANTENNA,
):
security = combination[0]
ac_capabilities = combination[1:]
test_args.append(
(
{
"chbw": 20,
"security": security,
"n_capabilities": N_CAPABS_20MHZ,
"ac_capabilities": ac_capabilities,
},
)
)
return test_args
# 1728 tests
def _generate_40mhz_test_args(self):
test_args = []
# 864 test cases for open security
# 864 test cases for wpa2 security
for combination in itertools.product(
SECURITIES,
VHT_MAX_MPDU_LEN,
RXLDPC,
RX_STBC,
TX_STBC,
MAX_A_MPDU,
RX_ANTENNA,
TX_ANTENNA,
):
security = combination[0]
ac_capabilities = combination[1:]
test_args.append(
(
{
"chbw": 40,
"security": security,
"n_capabilities": N_CAPABS_40MHZ,
"ac_capabilities": ac_capabilities,
},
)
)
return test_args
# 3456 tests
def _generate_80mhz_test_args(self):
test_args = []
# 1728 test cases for open security
# 1728 test cases for wpa2 security
for combination in itertools.product(
SECURITIES,
VHT_MAX_MPDU_LEN,
RXLDPC,
SHORT_GI_80,
RX_STBC,
TX_STBC,
MAX_A_MPDU,
RX_ANTENNA,
TX_ANTENNA,
):
security = combination[0]
ac_capabilities = combination[1:]
test_args.append(
(
{
"chbw": 80,
"security": security,
"n_capabilities": N_CAPABS_40MHZ,
"ac_capabilities": ac_capabilities,
},
)
)
return test_args
if __name__ == "__main__":
test_runner.main()